source: mainline/uspace/lib/gui/window.c@ 516e780

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 516e780 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 20.2 KB
Line 
1/*
2 * Copyright (c) 2012 Petr Koupy
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup gui
30 * @{
31 */
32/**
33 * @file
34 */
35
36#include <stdbool.h>
37#include <errno.h>
38#include <stdio.h>
39#include <stdlib.h>
40
41#include <as.h>
42#include <stdlib.h>
43#include <str.h>
44
45#include <fibril.h>
46#include <task.h>
47#include <adt/prodcons.h>
48#include <adt/list.h>
49
50#include <async.h>
51#include <loc.h>
52
53#include <io/pixel.h>
54#include <source.h>
55#include <font.h>
56#include <drawctx.h>
57#include <surface.h>
58#include <font/embedded.h>
59
60#include "common.h"
61#include "connection.h"
62#include "widget.h"
63#include "window.h"
64
65static sysarg_t border_thickness = 4;
66static sysarg_t bevel_thickness = 1;
67static sysarg_t header_height = 20;
68static sysarg_t header_min_width = 40;
69static sysarg_t close_thickness = 20;
70
71static pixel_t color_highlight = PIXEL(255, 255, 255, 255);
72static pixel_t color_shadow = PIXEL(255, 85, 85, 85);
73static pixel_t color_surface = PIXEL(255, 186, 186, 186);
74
75static pixel_t color_header_focus_highlight = PIXEL(255, 120, 145, 255);
76static pixel_t color_header_focus_shadow = PIXEL(255, 40, 48, 89);
77static pixel_t color_header_focus_surface = PIXEL(255, 88, 106, 196);
78
79static pixel_t color_header_unfocus_highlight = PIXEL(255, 16, 78, 126);
80static pixel_t color_header_unfocus_shadow = PIXEL(255, 5, 26, 42);
81static pixel_t color_header_unfocus_surface = PIXEL(255, 12, 57, 92);
82
83static pixel_t color_caption_focus = PIXEL(255, 255, 255, 255);
84static pixel_t color_caption_unfocus = PIXEL(255, 207, 207, 207);
85
86static void paint_internal(widget_t *widget)
87{
88 surface_t *surface = window_claim(widget->window);
89 if (!surface)
90 window_yield(widget->window);
91
92 source_t source;
93 source_init(&source);
94
95 drawctx_t drawctx;
96 drawctx_init(&drawctx, surface);
97 drawctx_set_source(&drawctx, &source);
98
99 /* Window border outer bevel */
100
101 draw_bevel(&drawctx, &source, widget->vpos, widget->hpos,
102 widget->width, widget->height, color_highlight, color_shadow);
103
104 /* Window border surface */
105
106 source_set_color(&source, color_surface);
107 drawctx_transfer(&drawctx, widget->hpos + 1, widget->vpos + 1,
108 widget->width - 2, 2);
109 drawctx_transfer(&drawctx, widget->hpos + 1, widget->vpos + 1,
110 2, widget->height - 2);
111 drawctx_transfer(&drawctx, widget->hpos + 1,
112 widget->vpos + widget->height - 3, widget->width - 2, 2);
113 drawctx_transfer(&drawctx, widget->hpos + widget->width - 3,
114 widget->vpos + 1, 2, widget->height - 4);
115
116 /* Window border inner bevel */
117
118 draw_bevel(&drawctx, &source, widget->hpos + 3, widget->vpos + 3,
119 widget->width - 6, widget->height - 6, color_shadow,
120 color_highlight);
121
122 /* Header bevel */
123
124 sysarg_t header_hpos = widget->hpos + border_thickness;
125 sysarg_t header_vpos = widget->vpos + border_thickness;
126 sysarg_t header_width = widget->width - 2 * border_thickness -
127 close_thickness;
128
129 draw_bevel(&drawctx, &source, header_hpos, header_vpos,
130 header_width, header_height, widget->window->is_focused ?
131 color_header_focus_highlight : color_header_unfocus_highlight,
132 widget->window->is_focused ?
133 color_header_focus_shadow : color_header_unfocus_shadow);
134
135 /* Header surface */
136
137 source_set_color(&source, widget->window->is_focused ?
138 color_header_focus_surface : color_header_unfocus_surface);
139 drawctx_transfer(&drawctx, header_hpos + 1, header_vpos + 1,
140 header_width - 2, header_height - 2);
141
142 /* Close button bevel */
143
144 sysarg_t close_hpos = widget->hpos + widget->width -
145 border_thickness - close_thickness;
146 sysarg_t close_vpos = widget->vpos + border_thickness;
147
148 draw_bevel(&drawctx, &source, close_hpos, close_vpos,
149 close_thickness, close_thickness, color_highlight, color_shadow);
150
151 /* Close button surface */
152
153 source_set_color(&source, color_surface);
154 drawctx_transfer(&drawctx, close_hpos + 1, close_vpos + 1,
155 close_thickness - 2, close_thickness - 2);
156
157 /* Close button icon */
158
159 draw_icon_cross(surface, close_hpos + 3, close_vpos + 3,
160 color_highlight, color_shadow);
161
162 /* Window caption */
163
164 font_t *font;
165 errno_t rc = embedded_font_create(&font, 16);
166 if (rc != EOK) {
167 window_yield(widget->window);
168 return;
169 }
170
171 drawctx_set_font(&drawctx, font);
172 source_set_color(&source, widget->window->is_focused ?
173 color_caption_focus : color_caption_unfocus);
174
175 sysarg_t cpt_width;
176 sysarg_t cpt_height;
177 font_get_box(font, widget->window->caption, &cpt_width, &cpt_height);
178
179 bool draw_title =
180 (widget->width >= 2 * border_thickness + 2 * bevel_thickness +
181 close_thickness + cpt_width);
182 if (draw_title) {
183 sysarg_t cpt_x = ((widget->width - cpt_width) / 2) + widget->hpos;
184 sysarg_t cpt_y = ((header_height - cpt_height) / 2) +
185 widget->vpos + border_thickness;
186
187 if (widget->window->caption)
188 drawctx_print(&drawctx, widget->window->caption, cpt_x, cpt_y);
189 }
190
191 font_release(font);
192 window_yield(widget->window);
193}
194
195static void root_destroy(widget_t *widget)
196{
197 widget_deinit(widget);
198}
199
200static void root_reconfigure(widget_t *widget)
201{
202 if (widget->window->is_decorated) {
203 list_foreach(widget->children, link, widget_t, child) {
204 child->rearrange(child,
205 widget->hpos + border_thickness,
206 widget->vpos + border_thickness + header_height,
207 widget->width - 2 * border_thickness,
208 widget->height - 2 * border_thickness - header_height);
209 }
210 } else {
211 list_foreach(widget->children, link, widget_t, child) {
212 child->rearrange(child, widget->hpos, widget->vpos,
213 widget->width, widget->height);
214 }
215 }
216}
217
218static void root_rearrange(widget_t *widget, sysarg_t hpos, sysarg_t vpos,
219 sysarg_t width, sysarg_t height)
220{
221 widget_modify(widget, hpos, vpos, width, height);
222 if (widget->window->is_decorated) {
223 paint_internal(widget);
224 list_foreach(widget->children, link, widget_t, child) {
225 child->rearrange(child,
226 hpos + border_thickness,
227 vpos + border_thickness + header_height,
228 width - 2 * border_thickness,
229 height - 2 * border_thickness - header_height);
230 }
231 } else {
232 list_foreach(widget->children, link, widget_t, child) {
233 child->rearrange(child, hpos, vpos, width, height);
234 }
235 }
236}
237
238static void root_repaint(widget_t *widget)
239{
240 if (widget->window->is_decorated) {
241 paint_internal(widget);
242 }
243 list_foreach(widget->children, link, widget_t, child) {
244 child->repaint(child);
245 }
246 if (widget->window->is_decorated) {
247 window_damage(widget->window);
248 }
249}
250
251static void root_handle_keyboard_event(widget_t *widget, kbd_event_t event)
252{
253 if (!list_empty(&widget->children)) {
254 widget_t *child = (widget_t *) list_first(&widget->children);
255 child->handle_keyboard_event(child, event);
256 }
257}
258
259static void root_handle_position_event(widget_t *widget, pos_event_t event)
260{
261 if (widget->window->is_decorated) {
262 sysarg_t width = widget->width;
263 sysarg_t height = widget->height;
264
265 bool btn_left = (event.btn_num == 1) && (event.type == POS_PRESS);
266 bool btn_right = (event.btn_num == 2) && (event.type == POS_PRESS);
267 bool allowed_button = btn_left || btn_right;
268
269 bool left = (event.hpos < border_thickness);
270 bool right = (event.hpos >= width - border_thickness);
271 bool top = (event.vpos < border_thickness);
272 bool bottom = (event.vpos >= height - border_thickness);
273 bool header = (event.hpos >= border_thickness) &&
274 (event.hpos < width - border_thickness) &&
275 (event.vpos >= border_thickness) &&
276 (event.vpos < border_thickness + header_height);
277 bool close = (header) &&
278 (event.hpos >= width - border_thickness - close_thickness);
279
280 if (top && left && allowed_button) {
281 window_grab_flags_t flags = GF_EMPTY;
282 flags |= GF_MOVE_X;
283 flags |= GF_MOVE_Y;
284 flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
285 flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
286 win_grab(widget->window->osess, event.pos_id, flags);
287 } else if (bottom && left && allowed_button) {
288 window_grab_flags_t flags = GF_EMPTY;
289 flags |= GF_MOVE_X;
290 flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
291 flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
292 win_grab(widget->window->osess, event.pos_id, flags);
293 } else if (bottom && right && allowed_button) {
294 window_grab_flags_t flags = GF_EMPTY;
295 flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
296 flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
297 win_grab(widget->window->osess, event.pos_id, flags);
298 } else if (top && right && allowed_button) {
299 window_grab_flags_t flags = GF_EMPTY;
300 flags |= GF_MOVE_Y;
301 flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
302 flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
303 win_grab(widget->window->osess, event.pos_id, flags);
304 } else if (top && allowed_button) {
305 window_grab_flags_t flags = GF_EMPTY;
306 flags |= GF_MOVE_Y;
307 flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
308 win_grab(widget->window->osess, event.pos_id, flags);
309 } else if (left && allowed_button) {
310 window_grab_flags_t flags = GF_EMPTY;
311 flags |= GF_MOVE_X;
312 flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
313 win_grab(widget->window->osess, event.pos_id, flags);
314 } else if (bottom && allowed_button) {
315 window_grab_flags_t flags = GF_EMPTY;
316 flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
317 win_grab(widget->window->osess, event.pos_id, flags);
318 } else if (right && allowed_button) {
319 window_grab_flags_t flags = GF_EMPTY;
320 flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
321 win_grab(widget->window->osess, event.pos_id, flags);
322 } else if (close && btn_left) {
323 win_close_request(widget->window->osess);
324 } else if (header && btn_left) {
325 window_grab_flags_t flags = GF_EMPTY;
326 flags |= GF_MOVE_X;
327 flags |= GF_MOVE_Y;
328 win_grab(widget->window->osess, event.pos_id, flags);
329 } else {
330 list_foreach(widget->children, link, widget_t, child) {
331 child->handle_position_event(child, event);
332 }
333 }
334 } else {
335 list_foreach(widget->children, link, widget_t, child) {
336 child->handle_position_event(child, event);
337 }
338 }
339}
340
341static void deliver_keyboard_event(window_t *win, kbd_event_t event)
342{
343 if (win->focus) {
344 win->focus->handle_keyboard_event(win->focus, event);
345 } else {
346 win->root.handle_keyboard_event(&win->root, event);
347 }
348}
349
350static void deliver_position_event(window_t *win, pos_event_t event)
351{
352 if (win->grab) {
353 win->grab->handle_position_event(win->grab, event);
354 } else {
355 win->root.handle_position_event(&win->root, event);
356 }
357}
358
359static void handle_signal_event(window_t *win, signal_event_t event)
360{
361 widget_t *widget = (widget_t *) event.object;
362 slot_t slot = (slot_t) event.slot;
363 void *data = (void *) event.argument;
364
365 slot(widget, data);
366
367 free(data);
368}
369
370static void handle_resize(window_t *win, sysarg_t offset_x, sysarg_t offset_y,
371 sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
372{
373 if (width < 2 * border_thickness + header_min_width) {
374 win_damage(win->osess, 0, 0, 0, 0);
375 return;
376 }
377
378 if (height < 2 * border_thickness + header_height) {
379 win_damage(win->osess, 0, 0, 0, 0);
380 return;
381 }
382
383 /* Allocate resources for new surface. */
384 surface_t *new_surface = surface_create(width, height, NULL,
385 SURFACE_FLAG_SHARED);
386 if (!new_surface)
387 return;
388
389 /* Switch new and old surface. */
390 fibril_mutex_lock(&win->guard);
391 surface_t *old_surface = win->surface;
392 win->surface = new_surface;
393 fibril_mutex_unlock(&win->guard);
394
395 /*
396 * Let all widgets in the tree alter their position and size.
397 * Widgets might also paint themselves onto the new surface.
398 */
399 win->root.rearrange(&win->root, 0, 0, width, height);
400
401 fibril_mutex_lock(&win->guard);
402 surface_reset_damaged_region(win->surface);
403 fibril_mutex_unlock(&win->guard);
404
405 /* Inform compositor about new surface. */
406 errno_t rc = win_resize(win->osess, offset_x, offset_y, width, height,
407 placement_flags, surface_direct_access(new_surface));
408
409 if (rc != EOK) {
410 /* Rollback to old surface. Reverse all changes. */
411
412 sysarg_t old_width = 0;
413 sysarg_t old_height = 0;
414 if (old_surface)
415 surface_get_resolution(old_surface, &old_width, &old_height);
416
417 fibril_mutex_lock(&win->guard);
418 new_surface = win->surface;
419 win->surface = old_surface;
420 fibril_mutex_unlock(&win->guard);
421
422 win->root.rearrange(&win->root, 0, 0, old_width, old_height);
423
424 if (win->surface) {
425 fibril_mutex_lock(&win->guard);
426 surface_reset_damaged_region(win->surface);
427 fibril_mutex_unlock(&win->guard);
428 }
429
430 surface_destroy(new_surface);
431 } else {
432 /* Deallocate old surface. */
433 if (old_surface)
434 surface_destroy(old_surface);
435 }
436}
437
438static void handle_refresh(window_t *win)
439{
440 win->root.repaint(&win->root);
441}
442
443static void handle_damage(window_t *win)
444{
445 sysarg_t x, y, width, height;
446 fibril_mutex_lock(&win->guard);
447 surface_get_damaged_region(win->surface, &x, &y, &width, &height);
448 surface_reset_damaged_region(win->surface);
449 fibril_mutex_unlock(&win->guard);
450
451 if (width > 0 && height > 0) {
452 /* Notify compositor. */
453 win_damage(win->osess, x, y, width, height);
454 }
455}
456
457static void destroy_children(widget_t *widget)
458{
459 /* Recursively destroy widget tree in bottom-top order. */
460 while (!list_empty(&widget->children)) {
461 widget_t *child =
462 list_get_instance(list_first(&widget->children), widget_t, link);
463 destroy_children(child);
464 child->destroy(child);
465 }
466}
467
468static void handle_close(window_t *win)
469{
470 destroy_children(&win->root);
471 win->root.destroy(&win->root);
472 win->grab = NULL;
473 win->focus = NULL;
474
475 win_close(win->osess);
476 async_hangup(win->isess);
477 async_hangup(win->osess);
478
479 while (!list_empty(&win->events.list)) {
480 window_event_t *event = (window_event_t *) list_first(&win->events.list);
481 list_remove(&event->link);
482 free(event);
483 }
484
485 if (win->surface) {
486 surface_destroy(win->surface);
487 }
488
489 free(win->caption);
490
491 free(win);
492}
493
494/* Window event loop. Runs in own dedicated fibril. */
495static errno_t event_loop(void *arg)
496{
497 bool is_main = false;
498 bool terminate = false;
499 window_t *win = (window_t *) arg;
500
501 while (true) {
502 window_event_t *event = (window_event_t *) prodcons_consume(&win->events);
503
504 switch (event->type) {
505 case ET_KEYBOARD_EVENT:
506 deliver_keyboard_event(win, event->data.kbd);
507 break;
508 case ET_POSITION_EVENT:
509 if (!win->is_focused) {
510 win->is_focused = true;
511 handle_refresh(win);
512 }
513 deliver_position_event(win, event->data.pos);
514 break;
515 case ET_SIGNAL_EVENT:
516 handle_signal_event(win, event->data.signal);
517 break;
518 case ET_WINDOW_RESIZE:
519 handle_resize(win, event->data.resize.offset_x,
520 event->data.resize.offset_y, event->data.resize.width,
521 event->data.resize.height, event->data.resize.placement_flags);
522 break;
523 case ET_WINDOW_FOCUS:
524 if (!win->is_focused) {
525 win->is_focused = true;
526 handle_refresh(win);
527 }
528 break;
529 case ET_WINDOW_UNFOCUS:
530 if (win->is_focused) {
531 win->is_focused = false;
532 handle_refresh(win);
533 }
534 break;
535 case ET_WINDOW_REFRESH:
536 handle_refresh(win);
537 break;
538 case ET_WINDOW_DAMAGE:
539 handle_damage(win);
540 break;
541 case ET_WINDOW_CLOSE:
542 is_main = win->is_main;
543 handle_close(win);
544 terminate = true;
545 break;
546 default:
547 break;
548 }
549
550 free(event);
551 if (terminate) {
552 break;
553 }
554 }
555
556 if (is_main) {
557 exit(0); /* Terminate whole task. */
558 }
559 return 0;
560}
561
562/* Input fetcher from compositor. Runs in own dedicated fibril. */
563static errno_t fetch_input(void *arg)
564{
565 errno_t rc;
566 bool terminate = false;
567 window_t *win = (window_t *) arg;
568
569 while (true) {
570 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
571
572 if (event) {
573 rc = win_get_event(win->isess, event);
574 if (rc == EOK) {
575 terminate = (event->type == ET_WINDOW_CLOSE);
576 link_initialize(&event->link);
577 prodcons_produce(&win->events, &event->link);
578 } else {
579 free(event);
580 terminate = true;
581 }
582 } else {
583 terminate = true;
584 }
585
586 if (terminate) {
587 break;
588 }
589 }
590
591 return 0;
592}
593
594window_t *window_open(const char *winreg, const void *data,
595 window_flags_t flags, const char *caption)
596{
597 window_t *win = (window_t *) malloc(sizeof(window_t));
598 if (!win)
599 return NULL;
600
601 win->is_main = flags & WINDOW_MAIN;
602 win->is_decorated = flags & WINDOW_DECORATED;
603 win->is_focused = true;
604 prodcons_initialize(&win->events);
605 fibril_mutex_initialize(&win->guard);
606
607 widget_init(&win->root, NULL, data);
608 win->root.window = win;
609 win->root.destroy = root_destroy;
610 win->root.reconfigure = root_reconfigure;
611 win->root.rearrange = root_rearrange;
612 win->root.repaint = root_repaint;
613 win->root.handle_keyboard_event = root_handle_keyboard_event;
614 win->root.handle_position_event = root_handle_position_event;
615 win->grab = NULL;
616 win->focus = NULL;
617 win->surface = NULL;
618
619 service_id_t reg_dsid;
620 errno_t rc = loc_service_get_id(winreg, &reg_dsid, 0);
621 if (rc != EOK) {
622 free(win);
623 return NULL;
624 }
625
626 async_sess_t *reg_sess =
627 loc_service_connect(reg_dsid, INTERFACE_COMPOSITOR, 0);
628 if (reg_sess == NULL) {
629 free(win);
630 return NULL;
631 }
632
633 service_id_t in_dsid;
634 service_id_t out_dsid;
635 rc = win_register(reg_sess, flags, &in_dsid, &out_dsid);
636 async_hangup(reg_sess);
637 if (rc != EOK) {
638 free(win);
639 return NULL;
640 }
641
642 win->osess = loc_service_connect(out_dsid, INTERFACE_COMPOSITOR, 0);
643 if (win->osess == NULL) {
644 free(win);
645 return NULL;
646 }
647
648 win->isess = loc_service_connect(in_dsid, INTERFACE_COMPOSITOR, 0);
649 if (win->isess == NULL) {
650 async_hangup(win->osess);
651 free(win);
652 return NULL;
653 }
654
655 if (caption == NULL)
656 win->caption = NULL;
657 else
658 win->caption = str_dup(caption);
659
660 return win;
661}
662
663void window_resize(window_t *win, sysarg_t offset_x, sysarg_t offset_y,
664 sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
665{
666 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
667 if (event) {
668 link_initialize(&event->link);
669 event->type = ET_WINDOW_RESIZE;
670 event->data.resize.offset_x = offset_x;
671 event->data.resize.offset_y = offset_y;
672 event->data.resize.width = width;
673 event->data.resize.height = height;
674 event->data.resize.placement_flags = placement_flags;
675 prodcons_produce(&win->events, &event->link);
676 }
677}
678
679errno_t window_set_caption(window_t *win, const char *caption)
680{
681 char *cap;
682
683 if (caption == NULL) {
684 win->caption = NULL;
685 } else {
686 cap = str_dup(caption);
687 if (cap == NULL)
688 return ENOMEM;
689 free(win->caption);
690 win->caption = cap;
691 }
692
693 win->is_focused = false;
694 handle_refresh(win);
695
696 return EOK;
697}
698
699void window_refresh(window_t *win)
700{
701 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
702 if (event) {
703 link_initialize(&event->link);
704 event->type = ET_WINDOW_REFRESH;
705 prodcons_produce(&win->events, &event->link);
706 }
707}
708
709void window_damage(window_t *win)
710{
711 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
712 if (event) {
713 link_initialize(&event->link);
714 event->type = ET_WINDOW_DAMAGE;
715 prodcons_produce(&win->events, &event->link);
716 }
717}
718
719widget_t *window_root(window_t *win)
720{
721 return &win->root;
722}
723
724void window_exec(window_t *win)
725{
726 fid_t ev_fid = fibril_create(event_loop, win);
727 fid_t fi_fid = fibril_create(fetch_input, win);
728 if (!ev_fid || !fi_fid) {
729 return;
730 }
731 fibril_add_ready(ev_fid);
732 fibril_add_ready(fi_fid);
733}
734
735surface_t *window_claim(window_t *win)
736{
737 fibril_mutex_lock(&win->guard);
738 return win->surface;
739}
740
741void window_yield(window_t *win)
742{
743 fibril_mutex_unlock(&win->guard);
744}
745
746void window_close(window_t *win)
747{
748 /* Request compositor to init closing cascade. */
749 win_close_request(win->osess);
750}
751
752/** @}
753 */
Note: See TracBrowser for help on using the repository browser.