source: mainline/uspace/lib/gui/window.c@ 62fbb7e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 62fbb7e was 62fbb7e, checked in by Martin Decky <martin@…>, 11 years ago

refactor window placement logic and introduce logical window placement flags

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