source: mainline/uspace/lib/gui/window.c@ 2fff3c4

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

Curb the proliferation of libdraw headers

libdraw provides a lot of ambiguously named headers, which makes it
confusing. This change merges the subdirectories into single headers,
and moves all headers into draw subdirectory, so that it's obvious
at a glance what library the header belongs to.

Compare:

#include <path.h>
#include <source.h>
#include <font/bitmap_backend.h>
#include <font/pcf.h>

vs.

#include <draw/path.h>
#include <draw/source.h>
#include <draw/font.h>

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