source: mainline/uspace/lib/gui/window.c@ 35b8bfe

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

make the title bar more subtle, change the close icon to the easily recognizable cross

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