source: mainline/uspace/lib/gui/window.c@ 3275736

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3275736 was 3275736, checked in by Jiri Svoboda <jiri@…>, 5 years ago

Create display window upon resize

GUI window size is not known when it is created. Until display server can
resize windows, need this hack so that we know the correct size when
creating the display window.

  • Property mode set to 100644
File size: 21.4 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 <loc.h>
51
52#include <io/pixel.h>
53#include <draw/source.h>
54#include <draw/font.h>
55#include <draw/drawctx.h>
56#include <draw/surface.h>
57#include <display.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 display_wnd_params_t wparams;
373 display_window_t *new_window = NULL;
374 gfx_bitmap_params_t params;
375 gfx_bitmap_alloc_t alloc;
376 gfx_bitmap_t *new_bitmap = NULL;
377 gfx_context_t *new_gc = NULL;
378 errno_t rc;
379
380 if (width < 2 * border_thickness + header_min_width) {
381 //win_damage(win->osess, 0, 0, 0, 0);
382 return;
383 }
384
385 if (height < 2 * border_thickness + header_height) {
386 //win_damage(win->osess, 0, 0, 0, 0);
387 return;
388 }
389
390 /* Allocate resources for new surface. */
391 surface_t *new_surface = surface_create(width, height, NULL,
392 SURFACE_FLAG_SHARED);
393 if (!new_surface)
394 return;
395
396 display_wnd_params_init(&wparams);
397 wparams.rect.p0.x = 0;
398 wparams.rect.p0.y = 0;
399 wparams.rect.p1.x = width;
400 wparams.rect.p1.y = height;
401
402 rc = display_window_create(win->display, &wparams, NULL, NULL,
403 &new_window);
404 if (rc != EOK) {
405 surface_destroy(new_surface);
406 return;
407 }
408
409 rc = display_window_get_gc(new_window, &new_gc);
410 if (rc != EOK) {
411 display_window_destroy(new_window);
412 surface_destroy(new_surface);
413 return;
414 }
415
416 params.rect.p0.x = 0;
417 params.rect.p0.y = 0;
418 params.rect.p1.x = width;
419 params.rect.p1.y = height;
420
421 alloc.pitch = width * sizeof(uint32_t);
422 alloc.off0 = 0;
423 alloc.pixels = surface_direct_access(new_surface);
424
425 rc = gfx_bitmap_create(new_gc, &params, &alloc, &new_bitmap);
426 if (rc != EOK) {
427 gfx_context_delete(new_gc);
428 display_window_destroy(new_window);
429 surface_destroy(new_surface);
430 return;
431 }
432
433 /* Switch new and old surface. */
434 fibril_mutex_lock(&win->guard);
435 surface_t *old_surface = win->surface;
436 gfx_bitmap_t *old_bitmap = win->bitmap;
437 display_window_t *old_window = win->dwindow;
438 gfx_context_t *old_gc = win->gc;
439 win->surface = new_surface;
440 win->bitmap = new_bitmap;
441 win->dwindow = new_window;
442 win->gc = new_gc;
443 fibril_mutex_unlock(&win->guard);
444
445 /*
446 * Let all widgets in the tree alter their position and size.
447 * Widgets might also paint themselves onto the new surface.
448 */
449 win->root.rearrange(&win->root, 0, 0, width, height);
450
451 fibril_mutex_lock(&win->guard);
452 surface_reset_damaged_region(win->surface);
453 fibril_mutex_unlock(&win->guard);
454
455 /* Inform compositor about new surface. */
456// errno_t rc = win_resize(win->osess, offset_x, offset_y, width, height,
457// placement_flags, surface_direct_access(new_surface));
458 rc = EOK;
459
460 if (rc != EOK) {
461 /* Rollback to old surface. Reverse all changes. */
462
463 sysarg_t old_width = 0;
464 sysarg_t old_height = 0;
465 if (old_surface)
466 surface_get_resolution(old_surface, &old_width, &old_height);
467
468 fibril_mutex_lock(&win->guard);
469 new_surface = win->surface;
470 win->surface = old_surface;
471 win->bitmap = old_bitmap;
472 win->dwindow = old_window;
473 win->gc = old_gc;
474 fibril_mutex_unlock(&win->guard);
475
476 win->root.rearrange(&win->root, 0, 0, old_width, old_height);
477
478 if (win->surface) {
479 fibril_mutex_lock(&win->guard);
480 surface_reset_damaged_region(win->surface);
481 fibril_mutex_unlock(&win->guard);
482 }
483
484 surface_destroy(new_surface);
485 } else {
486 if (old_window != NULL)
487 display_window_destroy(old_window);
488 if (old_gc != NULL)
489 gfx_context_delete(old_gc);
490 if (old_bitmap != NULL)
491 gfx_bitmap_destroy(old_bitmap);
492 /* Deallocate old surface. */
493 if (old_surface)
494 surface_destroy(old_surface);
495
496 (void) gfx_bitmap_render(win->bitmap, NULL, NULL);
497 }
498}
499
500static void handle_refresh(window_t *win)
501{
502 win->root.repaint(&win->root);
503}
504
505static void handle_damage(window_t *win)
506{
507 sysarg_t x, y, width, height;
508 gfx_rect_t rect;
509 fibril_mutex_lock(&win->guard);
510 surface_get_damaged_region(win->surface, &x, &y, &width, &height);
511 surface_reset_damaged_region(win->surface);
512 fibril_mutex_unlock(&win->guard);
513
514
515 if (width > 0 && height > 0) {
516 /* Notify compositor. */
517 //win_damage(win->osess, x, y, width, height);
518
519 rect.p0.x = x;
520 rect.p0.y = y;
521 rect.p1.x = x + width;
522 rect.p1.y = y + height;
523
524 printf("render damaged region: %d,%d,%d,%d,\n",
525 (int)x,(int)y,(int)width,(int)height);
526 if (win->bitmap != NULL)
527 (void) gfx_bitmap_render(win->bitmap, &rect, NULL);
528 }
529}
530
531static void destroy_children(widget_t *widget)
532{
533 /* Recursively destroy widget tree in bottom-top order. */
534 while (!list_empty(&widget->children)) {
535 widget_t *child =
536 list_get_instance(list_first(&widget->children), widget_t, link);
537 destroy_children(child);
538 child->destroy(child);
539 }
540}
541
542static void handle_close(window_t *win)
543{
544 destroy_children(&win->root);
545 win->root.destroy(&win->root);
546 win->grab = NULL;
547 win->focus = NULL;
548
549 display_window_destroy(win->dwindow);
550 display_close(win->display);
551
552 while (!list_empty(&win->events.list)) {
553 window_event_t *event = (window_event_t *) list_first(&win->events.list);
554 list_remove(&event->link);
555 free(event);
556 }
557
558 if (win->surface) {
559 surface_destroy(win->surface);
560 }
561
562 free(win->caption);
563
564 free(win);
565}
566
567/* Window event loop. Runs in own dedicated fibril. */
568static errno_t event_loop(void *arg)
569{
570 bool is_main = false;
571 bool terminate = false;
572 window_t *win = (window_t *) arg;
573
574 while (true) {
575 window_event_t *event = (window_event_t *) prodcons_consume(&win->events);
576
577 switch (event->type) {
578 case ET_KEYBOARD_EVENT:
579 deliver_keyboard_event(win, event->data.kbd);
580 break;
581 case ET_POSITION_EVENT:
582 if (!win->is_focused) {
583 win->is_focused = true;
584 handle_refresh(win);
585 }
586 deliver_position_event(win, event->data.pos);
587 break;
588 case ET_SIGNAL_EVENT:
589 handle_signal_event(win, event->data.signal);
590 break;
591 case ET_WINDOW_RESIZE:
592 handle_resize(win, event->data.resize.offset_x,
593 event->data.resize.offset_y, event->data.resize.width,
594 event->data.resize.height, event->data.resize.placement_flags);
595 break;
596 case ET_WINDOW_FOCUS:
597 if (!win->is_focused) {
598 win->is_focused = true;
599 handle_refresh(win);
600 }
601 break;
602 case ET_WINDOW_UNFOCUS:
603 if (win->is_focused) {
604 win->is_focused = false;
605 handle_refresh(win);
606 }
607 break;
608 case ET_WINDOW_REFRESH:
609 handle_refresh(win);
610 break;
611 case ET_WINDOW_DAMAGE:
612 handle_damage(win);
613 break;
614 case ET_WINDOW_CLOSE:
615 is_main = win->is_main;
616 handle_close(win);
617 terminate = true;
618 break;
619 default:
620 break;
621 }
622
623 free(event);
624 if (terminate) {
625 break;
626 }
627 }
628
629 if (is_main) {
630 exit(0); /* Terminate whole task. */
631 }
632 return 0;
633}
634
635/* Input fetcher from compositor. Runs in own dedicated fibril. */
636static errno_t fetch_input(void *arg)
637{
638// errno_t rc;
639// bool terminate = false;
640// window_t *win = (window_t *) arg;
641
642/* while (true) {
643 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
644
645 if (event) {
646 rc = win_get_event(win->isess, event);
647 if (rc == EOK) {
648 terminate = (event->type == ET_WINDOW_CLOSE);
649 link_initialize(&event->link);
650 prodcons_produce(&win->events, &event->link);
651 } else {
652 free(event);
653 terminate = true;
654 }
655 } else {
656 terminate = true;
657 }
658
659 if (terminate) {
660 break;
661 }
662 }
663*/
664 return 0;
665}
666
667window_t *window_open(const char *winreg, const void *data,
668 window_flags_t flags, const char *caption)
669{
670 window_t *win = (window_t *) calloc(1, sizeof(window_t));
671 if (!win)
672 return NULL;
673
674 win->is_main = flags & WINDOW_MAIN;
675 win->is_decorated = flags & WINDOW_DECORATED;
676 win->is_focused = true;
677 prodcons_initialize(&win->events);
678 fibril_mutex_initialize(&win->guard);
679
680 widget_init(&win->root, NULL, data);
681 win->root.window = win;
682 win->root.destroy = root_destroy;
683 win->root.reconfigure = root_reconfigure;
684 win->root.rearrange = root_rearrange;
685 win->root.repaint = root_repaint;
686 win->root.handle_keyboard_event = root_handle_keyboard_event;
687 win->root.handle_position_event = root_handle_position_event;
688 win->grab = NULL;
689 win->focus = NULL;
690 win->surface = NULL;
691
692 errno_t rc = display_open(winreg, &win->display);
693 if (rc != EOK) {
694 free(win);
695 return NULL;
696 }
697
698
699 if (caption == NULL)
700 win->caption = NULL;
701 else
702 win->caption = str_dup(caption);
703
704 return win;
705}
706
707void window_resize(window_t *win, sysarg_t offset_x, sysarg_t offset_y,
708 sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
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_RESIZE;
714 event->data.resize.offset_x = offset_x;
715 event->data.resize.offset_y = offset_y;
716 event->data.resize.width = width;
717 event->data.resize.height = height;
718 event->data.resize.placement_flags = placement_flags;
719 prodcons_produce(&win->events, &event->link);
720 }
721}
722
723errno_t window_set_caption(window_t *win, const char *caption)
724{
725 char *cap;
726
727 if (caption == NULL) {
728 win->caption = NULL;
729 } else {
730 cap = str_dup(caption);
731 if (cap == NULL)
732 return ENOMEM;
733 free(win->caption);
734 win->caption = cap;
735 }
736
737 win->is_focused = false;
738 handle_refresh(win);
739
740 return EOK;
741}
742
743void window_refresh(window_t *win)
744{
745 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
746 if (event) {
747 link_initialize(&event->link);
748 event->type = ET_WINDOW_REFRESH;
749 prodcons_produce(&win->events, &event->link);
750 }
751}
752
753void window_damage(window_t *win)
754{
755 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
756 if (event) {
757 link_initialize(&event->link);
758 event->type = ET_WINDOW_DAMAGE;
759 prodcons_produce(&win->events, &event->link);
760 }
761}
762
763widget_t *window_root(window_t *win)
764{
765 return &win->root;
766}
767
768void window_exec(window_t *win)
769{
770 fid_t ev_fid = fibril_create(event_loop, win);
771 fid_t fi_fid = fibril_create(fetch_input, win);
772 if (!ev_fid || !fi_fid) {
773 return;
774 }
775 fibril_add_ready(ev_fid);
776 fibril_add_ready(fi_fid);
777}
778
779surface_t *window_claim(window_t *win)
780{
781 fibril_mutex_lock(&win->guard);
782 return win->surface;
783}
784
785void window_yield(window_t *win)
786{
787 fibril_mutex_unlock(&win->guard);
788}
789
790void window_close(window_t *win)
791{
792 /* Request compositor to init closing cascade. */
793 //win_close_request(win->osess);
794}
795
796/** @}
797 */
Note: See TracBrowser for help on using the repository browser.