source: mainline/uspace/lib/ui/src/window.c@ 6a0b2cc

ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 6a0b2cc was 8a6ebbb, checked in by Jiri Svoboda <jiri@…>, 22 months ago

Add restore, minimize, maximize entries to system menu

  • Property mode set to 100644
File size: 40.1 KB
Line 
1/*
2 * Copyright (c) 2023 Jiri Svoboda
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 libui
30 * @{
31 */
32/**
33 * @file Window
34 */
35
36#include <congfx/console.h>
37#include <display.h>
38#include <errno.h>
39#include <gfx/bitmap.h>
40#include <gfx/context.h>
41#include <gfx/cursor.h>
42#include <gfx/render.h>
43#include <io/kbd_event.h>
44#include <io/pos_event.h>
45#include <mem.h>
46#include <memgfx/memgc.h>
47#include <stdlib.h>
48#include <ui/control.h>
49#include <ui/menu.h>
50#include <ui/menuentry.h>
51#include <ui/resource.h>
52#include <ui/ui.h>
53#include <ui/wdecor.h>
54#include <ui/window.h>
55#include "../private/control.h"
56#include "../private/dummygc.h"
57#include "../private/resource.h"
58#include "../private/ui.h"
59#include "../private/wdecor.h"
60#include "../private/window.h"
61
62static void dwnd_close_event(void *);
63static void dwnd_focus_event(void *, unsigned);
64static void dwnd_kbd_event(void *, kbd_event_t *);
65static void dwnd_pos_event(void *, pos_event_t *);
66static void dwnd_resize_event(void *, gfx_rect_t *);
67static void dwnd_unfocus_event(void *, unsigned);
68
69static display_wnd_cb_t dwnd_cb = {
70 .close_event = dwnd_close_event,
71 .focus_event = dwnd_focus_event,
72 .kbd_event = dwnd_kbd_event,
73 .pos_event = dwnd_pos_event,
74 .resize_event = dwnd_resize_event,
75 .unfocus_event = dwnd_unfocus_event
76};
77
78static void wd_sysmenu(ui_wdecor_t *, void *, sysarg_t);
79static void wd_minimize(ui_wdecor_t *, void *);
80static void wd_maximize(ui_wdecor_t *, void *);
81static void wd_unmaximize(ui_wdecor_t *, void *);
82static void wd_close(ui_wdecor_t *, void *);
83static void wd_move(ui_wdecor_t *, void *, gfx_coord2_t *, sysarg_t);
84static void wd_resize(ui_wdecor_t *, void *, ui_wdecor_rsztype_t,
85 gfx_coord2_t *, sysarg_t);
86static void wd_set_cursor(ui_wdecor_t *, void *, ui_stock_cursor_t);
87
88static ui_wdecor_cb_t wdecor_cb = {
89 .sysmenu = wd_sysmenu,
90 .minimize = wd_minimize,
91 .maximize = wd_maximize,
92 .unmaximize = wd_unmaximize,
93 .close = wd_close,
94 .move = wd_move,
95 .resize = wd_resize,
96 .set_cursor = wd_set_cursor
97};
98
99static void wnd_sysmenu_left(ui_menu_t *, void *, sysarg_t);
100static void wnd_sysmenu_right(ui_menu_t *, void *, sysarg_t);
101static void wnd_sysmenu_close_req(ui_menu_t *, void *);
102static void wnd_sysmenu_press_accel(ui_menu_t *, void *, char32_t, sysarg_t);
103
104static ui_menu_cb_t wnd_sysmenu_cb = {
105 .left = wnd_sysmenu_left,
106 .right = wnd_sysmenu_right,
107 .close_req = wnd_sysmenu_close_req,
108 .press_accel = wnd_sysmenu_press_accel
109};
110
111static void wnd_sysmenu_erestore(ui_menu_entry_t *, void *);
112static void wnd_sysmenu_eminimize(ui_menu_entry_t *, void *);
113static void wnd_sysmenu_emaximize(ui_menu_entry_t *, void *);
114static void wnd_sysmenu_eclose(ui_menu_entry_t *, void *);
115
116static void ui_window_invalidate(void *, gfx_rect_t *);
117static void ui_window_update(void *);
118static errno_t ui_window_cursor_get_pos(void *, gfx_coord2_t *);
119static errno_t ui_window_cursor_set_pos(void *, gfx_coord2_t *);
120static errno_t ui_window_cursor_set_visible(void *, bool);
121
122/** Window memory GC callbacks */
123static mem_gc_cb_t ui_window_mem_gc_cb = {
124 .invalidate = ui_window_invalidate,
125 .update = ui_window_update,
126 .cursor_get_pos = ui_window_cursor_get_pos,
127 .cursor_set_pos = ui_window_cursor_set_pos,
128 .cursor_set_visible = ui_window_cursor_set_visible
129};
130
131static void ui_window_app_invalidate(void *, gfx_rect_t *);
132static void ui_window_app_update(void *);
133
134/** Application area memory GC callbacks */
135static mem_gc_cb_t ui_window_app_mem_gc_cb = {
136 .invalidate = ui_window_app_invalidate,
137 .update = ui_window_app_update
138};
139
140static void ui_window_expose_cb(void *);
141
142/** Initialize window parameters structure.
143 *
144 * Window parameters structure must always be initialized using this function
145 * first. By default, the window will be decorated. To get a non-decorated
146 * window, one needs to clear ui_wds_decorated
147 * (e.g. params->style &= ~ui_wds_decorated).
148 *
149 * @param params Window parameters structure
150 */
151void ui_wnd_params_init(ui_wnd_params_t *params)
152{
153 memset(params, 0, sizeof(ui_wnd_params_t));
154
155 /* Make window decorated by default. */
156 params->style = ui_wds_decorated;
157}
158
159/** Compute where window should be placed on the screen.
160 *
161 * This only applies to windows that do not use default placement or
162 * if we are running in full-screen mode.
163 *
164 * @param window Window
165 * @param drect Display rectangle
166 * @param params Window parameters
167 * @param pos Place to store position of top-left corner
168 */
169static void ui_window_place(ui_window_t *window, gfx_rect_t *drect,
170 ui_wnd_params_t *params, gfx_coord2_t *pos)
171{
172 gfx_coord2_t dims;
173
174 assert(params->placement != ui_wnd_place_default ||
175 ui_is_fullscreen(window->ui));
176
177 pos->x = 0;
178 pos->y = 0;
179
180 switch (params->placement) {
181 case ui_wnd_place_default:
182 assert(ui_is_fullscreen(window->ui));
183 /* Center window */
184 gfx_rect_dims(&params->rect, &dims);
185 pos->x = (drect->p0.x + drect->p1.x) / 2 - dims.x / 2;
186 pos->y = (drect->p0.y + drect->p1.y) / 2 - dims.y / 2;
187 break;
188 case ui_wnd_place_top_left:
189 case ui_wnd_place_full_screen:
190 pos->x = drect->p0.x - params->rect.p0.x;
191 pos->y = drect->p0.y - params->rect.p0.y;
192 break;
193 case ui_wnd_place_top_right:
194 pos->x = drect->p1.x - params->rect.p1.x;
195 pos->y = drect->p0.y - params->rect.p0.y;
196 break;
197 case ui_wnd_place_bottom_left:
198 pos->x = drect->p0.x - params->rect.p0.x;
199 pos->y = drect->p1.y - params->rect.p1.y;
200 break;
201 case ui_wnd_place_bottom_right:
202 pos->x = drect->p1.x - params->rect.p1.x;
203 pos->y = drect->p1.y - params->rect.p1.y;
204 break;
205 case ui_wnd_place_popup:
206 /* Place popup window below parent rectangle */
207 pos->x = params->prect.p0.x;
208 pos->y = params->prect.p1.y;
209 break;
210 }
211}
212
213/** Create window's system menu.
214 *
215 * @param window Window
216 * @return EOK on success or an error code
217 */
218static errno_t ui_window_sysmenu_create(ui_window_t *window)
219{
220 errno_t rc;
221 ui_menu_entry_t *mrestore;
222 ui_menu_entry_t *mmin;
223 ui_menu_entry_t *mmax;
224 ui_menu_entry_t *msep;
225 ui_menu_entry_t *mclose;
226
227 rc = ui_menu_create(window, &window->sysmenu);
228 if (rc != EOK)
229 goto error;
230
231 ui_menu_set_cb(window->sysmenu, &wnd_sysmenu_cb, (void *)window);
232
233 rc = ui_menu_entry_create(window->sysmenu, "~R~estore",
234 "", &mrestore);
235 if (rc != EOK)
236 goto error;
237
238 if (!window->wdecor->maximized)
239 ui_menu_entry_set_disabled(mrestore, true);
240
241 ui_menu_entry_set_cb(mrestore, wnd_sysmenu_erestore, (void *)window);
242
243 rc = ui_menu_entry_create(window->sysmenu, "Mi~n~imize",
244 "", &mmin);
245 if (rc != EOK)
246 goto error;
247
248 if ((window->wdecor->style & ui_wds_minimize_btn) == 0)
249 ui_menu_entry_set_disabled(mmin, true);
250
251 ui_menu_entry_set_cb(mmin, wnd_sysmenu_eminimize, (void *)window);
252
253 rc = ui_menu_entry_create(window->sysmenu, "Ma~x~imize",
254 "", &mmax);
255 if (rc != EOK)
256 goto error;
257
258 if ((window->wdecor->style & ui_wds_maximize_btn) == 0 ||
259 window->wdecor->maximized)
260 ui_menu_entry_set_disabled(mmax, true);
261
262 ui_menu_entry_set_cb(mmax, wnd_sysmenu_emaximize, (void *)window);
263
264 rc = ui_menu_entry_sep_create(window->sysmenu, &msep);
265 if (rc != EOK)
266 goto error;
267
268 rc = ui_menu_entry_create(window->sysmenu, "~C~lose", "Alt-F4",
269 &mclose);
270 if (rc != EOK)
271 goto error;
272
273 if ((window->wdecor->style & ui_wds_close_btn) == 0)
274 ui_menu_entry_set_disabled(mclose, true);
275
276 ui_menu_entry_set_cb(mclose, wnd_sysmenu_eclose, (void *)window);
277
278 window->sysmenu_restore = mrestore;
279 window->sysmenu_minimize = mmin;
280 window->sysmenu_maximize = mmax;
281
282 return EOK;
283error:
284 return rc;
285}
286
287/** Create new window.
288 *
289 * @param ui User interface
290 * @param params Window parameters
291 * @param rwindow Place to store pointer to new window
292 * @return EOK on success or an error code
293 */
294errno_t ui_window_create(ui_t *ui, ui_wnd_params_t *params,
295 ui_window_t **rwindow)
296{
297 ui_window_t *window;
298 display_info_t info;
299 gfx_coord2_t scr_dims;
300 display_wnd_params_t dparams;
301 gfx_context_t *gc = NULL;
302 ui_resource_t *res = NULL;
303 ui_wdecor_t *wdecor = NULL;
304 dummy_gc_t *dgc = NULL;
305 gfx_bitmap_params_t bparams;
306 gfx_bitmap_alloc_t alloc;
307 gfx_bitmap_t *bmp = NULL;
308 gfx_coord2_t off;
309 mem_gc_t *memgc = NULL;
310 xlate_gc_t *xgc = NULL;
311 errno_t rc;
312
313 window = calloc(1, sizeof(ui_window_t));
314 if (window == NULL)
315 return ENOMEM;
316
317 window->ui = ui;
318
319 display_wnd_params_init(&dparams);
320 dparams.rect = params->rect;
321 dparams.caption = params->caption;
322 /* Only allow making the window larger */
323 gfx_rect_dims(&params->rect, &dparams.min_size);
324
325 /*
326 * If idev_id is not specified, use the UI default (probably
327 * obtained from display specification. This creates the
328 * main window in the seat specified on the command line.
329 */
330 if (params->idev_id != 0)
331 dparams.idev_id = params->idev_id;
332 else
333 dparams.idev_id = ui->idev_id;
334
335 if ((params->flags & ui_wndf_popup) != 0)
336 dparams.flags |= wndf_popup;
337 if ((params->flags & ui_wndf_topmost) != 0)
338 dparams.flags |= wndf_topmost;
339 if ((params->flags & ui_wndf_system) != 0)
340 dparams.flags |= wndf_system;
341 if ((params->flags & ui_wndf_avoid) != 0)
342 dparams.flags |= wndf_avoid;
343
344 if (ui->display != NULL) {
345 if (params->placement != ui_wnd_place_default) {
346 rc = display_get_info(ui->display, &info);
347 if (rc != EOK)
348 goto error;
349 }
350
351 if (params->placement == ui_wnd_place_full_screen) {
352 /* Make window the size of the screen */
353 gfx_rect_dims(&info.rect, &scr_dims);
354 gfx_coord2_add(&dparams.rect.p0, &scr_dims,
355 &dparams.rect.p1);
356 }
357
358 if (params->placement != ui_wnd_place_default) {
359 /* Set initial display window position */
360 ui_window_place(window, &info.rect, params,
361 &dparams.pos);
362
363 dparams.flags |= wndf_setpos;
364 }
365
366 rc = display_window_create(ui->display, &dparams, &dwnd_cb,
367 (void *) window, &window->dwindow);
368 if (rc != EOK)
369 goto error;
370
371 rc = display_window_get_gc(window->dwindow, &gc);
372 if (rc != EOK)
373 goto error;
374 } else if (ui->console != NULL) {
375 gc = console_gc_get_ctx(ui->cgc);
376
377 if (params->placement == ui_wnd_place_full_screen) {
378 /* Make window the size of the screen */
379 gfx_rect_dims(&ui->rect, &scr_dims);
380 gfx_coord2_add(&dparams.rect.p0, &scr_dims,
381 &dparams.rect.p1);
382 (void) console_set_caption(ui->console,
383 params->caption);
384 }
385 } else {
386 /* Needed for unit tests */
387 rc = dummygc_create(&dgc);
388 if (rc != EOK)
389 goto error;
390
391 gc = dummygc_get_ctx(dgc);
392 }
393
394#ifdef CONFIG_UI_CS_RENDER
395 /* Create window bitmap */
396 gfx_bitmap_params_init(&bparams);
397#ifndef CONFIG_WIN_DOUBLE_BUF
398 /* Console does not support direct output */
399 if (ui->display != NULL)
400 bparams.flags |= bmpf_direct_output;
401#endif
402
403 /* Move rectangle so that top-left corner is 0,0 */
404 gfx_rect_rtranslate(&dparams.rect.p0, &dparams.rect, &bparams.rect);
405
406 rc = gfx_bitmap_create(gc, &bparams, NULL, &bmp);
407 if (rc != EOK)
408 goto error;
409
410 /* Create memory GC */
411 rc = gfx_bitmap_get_alloc(bmp, &alloc);
412 if (rc != EOK) {
413 gfx_bitmap_destroy(window->app_bmp);
414 return rc;
415 }
416
417 rc = mem_gc_create(&bparams.rect, &alloc, &ui_window_mem_gc_cb,
418 (void *) window, &memgc);
419 if (rc != EOK) {
420 gfx_bitmap_destroy(window->app_bmp);
421 return rc;
422 }
423
424 window->bmp = bmp;
425 window->mgc = memgc;
426 window->gc = mem_gc_get_ctx(memgc);
427 window->realgc = gc;
428 (void) off;
429#else
430 /* Server-side rendering */
431
432 /* Full-screen mode? */
433 if (ui->display == NULL) {
434 /* Create translating GC to translate window contents */
435 off.x = 0;
436 off.y = 0;
437 rc = xlate_gc_create(&off, gc, &xgc);
438 if (rc != EOK)
439 goto error;
440
441 window->xgc = xgc;
442 window->gc = xlate_gc_get_ctx(xgc);
443 window->realgc = gc;
444 } else {
445 window->gc = gc;
446 }
447
448 (void) ui_window_mem_gc_cb;
449 (void) alloc;
450 (void) bparams;
451#endif
452 if (ui->display == NULL) {
453 ui_window_place(window, &ui->rect, params, &window->dpos);
454
455 if (window->xgc != NULL)
456 xlate_gc_set_off(window->xgc, &window->dpos);
457 }
458
459 rc = ui_resource_create(window->gc, ui_is_textmode(ui), &res);
460 if (rc != EOK)
461 goto error;
462
463 rc = ui_wdecor_create(res, params->caption, params->style, &wdecor);
464 if (rc != EOK)
465 goto error;
466
467 ui_wdecor_set_rect(wdecor, &dparams.rect);
468 ui_wdecor_set_cb(wdecor, &wdecor_cb, (void *) window);
469 ui_wdecor_paint(wdecor);
470
471 ui_resource_set_expose_cb(res, ui_window_expose_cb, (void *) window);
472
473 window->rect = dparams.rect;
474 window->res = res;
475 window->wdecor = wdecor;
476 window->cursor = ui_curs_arrow;
477 window->placement = params->placement;
478
479 rc = ui_window_sysmenu_create(window);
480 if (rc != EOK)
481 goto error;
482
483 *rwindow = window;
484
485 list_append(&window->lwindows, &ui->windows);
486 return EOK;
487error:
488 if (wdecor != NULL)
489 ui_wdecor_destroy(wdecor);
490 if (res != NULL)
491 ui_resource_destroy(res);
492 if (memgc != NULL)
493 mem_gc_delete(memgc);
494 if (xgc != NULL)
495 xlate_gc_delete(xgc);
496 if (bmp != NULL)
497 gfx_bitmap_destroy(bmp);
498 if (dgc != NULL)
499 dummygc_destroy(dgc);
500 free(window);
501 return rc;
502}
503
504/** Destroy window.
505 *
506 * @param window Window or @c NULL
507 */
508void ui_window_destroy(ui_window_t *window)
509{
510 ui_t *ui;
511
512 if (window == NULL)
513 return;
514
515 ui = window->ui;
516
517 list_remove(&window->lwindows);
518 ui_control_destroy(window->control);
519 ui_menu_destroy(window->sysmenu);
520 ui_wdecor_destroy(window->wdecor);
521 ui_resource_destroy(window->res);
522 if (window->app_mgc != NULL)
523 mem_gc_delete(window->app_mgc);
524 if (window->app_bmp != NULL)
525 gfx_bitmap_destroy(window->app_bmp);
526 if (window->mgc != NULL) {
527 mem_gc_delete(window->mgc);
528 window->gc = NULL;
529 }
530 if (window->bmp != NULL)
531 gfx_bitmap_destroy(window->bmp);
532 if (window->dwindow != NULL)
533 display_window_destroy(window->dwindow);
534
535 /* Need to repaint if windows are emulated */
536 if (ui_is_fullscreen(ui)) {
537 ui_paint(ui);
538 }
539
540 if (ui->console != NULL &&
541 window->placement == ui_wnd_place_full_screen) {
542 (void) console_set_caption(ui->console, "");
543 }
544
545 free(window);
546}
547
548/** Add control to window.
549 *
550 * Only one control can be added to a window. If more than one control
551 * is added, the results are undefined.
552 *
553 * @param window Window
554 * @param control Control
555 */
556void ui_window_add(ui_window_t *window, ui_control_t *control)
557{
558 assert(window->control == NULL);
559
560 window->control = control;
561 control->elemp = (void *) window;
562}
563
564/** Remove control from window.
565 *
566 * @param window Window
567 * @param control Control
568 */
569void ui_window_remove(ui_window_t *window, ui_control_t *control)
570{
571 assert(window->control == control);
572 assert((ui_window_t *) control->elemp == window);
573
574 window->control = NULL;
575 control->elemp = NULL;
576}
577
578/** Get active window (only valid in fullscreen mode).
579 *
580 * @param ui User interface
581 * @return Active window
582 */
583ui_window_t *ui_window_get_active(ui_t *ui)
584{
585 link_t *link;
586
587 link = list_last(&ui->windows);
588 if (link == NULL)
589 return NULL;
590
591 return list_get_instance(link, ui_window_t, lwindows);
592}
593
594/** Resize or (un)maximize window.
595 *
596 * @param window Window
597 * @param rect Rectangle
598 * @param scop Size change operation
599 *
600 * @return EOK on success or an error code
601 */
602errno_t ui_window_size_change(ui_window_t *window, gfx_rect_t *rect,
603 ui_wnd_sc_op_t scop)
604{
605 gfx_coord2_t offs;
606 gfx_rect_t nrect;
607 gfx_rect_t arect;
608 gfx_bitmap_t *app_bmp = NULL;
609 gfx_bitmap_t *win_bmp = NULL;
610 gfx_bitmap_params_t app_params;
611 gfx_bitmap_params_t win_params;
612 gfx_bitmap_alloc_t app_alloc;
613 gfx_bitmap_alloc_t win_alloc;
614 errno_t rc;
615
616 /*
617 * Move rect so that p0=0,0 - keep window's coordinate system origin
618 * locked to top-left corner of the window.
619 */
620 offs = rect->p0;
621 gfx_rect_rtranslate(&offs, rect, &nrect);
622
623 /* mgc != NULL iff client-side rendering */
624 if (window->mgc != NULL) {
625#ifdef CONFIG_WIN_DOUBLE_BUF
626 /*
627 * Create new window bitmap in advance. If direct mapping,
628 * will need do it after resizing the window.
629 */
630 assert(window->bmp != NULL);
631 gfx_bitmap_params_init(&win_params);
632 win_params.rect = nrect;
633
634 rc = gfx_bitmap_create(window->realgc, &win_params, NULL,
635 &win_bmp);
636 if (rc != EOK)
637 goto error;
638
639 rc = gfx_bitmap_get_alloc(win_bmp, &win_alloc);
640 if (rc != EOK)
641 goto error;
642#endif
643 }
644
645 /* Application area GC? */
646 if (window->app_gc != NULL) {
647 /* Resize application bitmap */
648 assert(window->app_bmp != NULL);
649
650 gfx_bitmap_params_init(&app_params);
651
652 /*
653 * The bitmap will have the same dimensions as the
654 * application rectangle, but start at 0,0.
655 */
656 ui_wdecor_app_from_rect(window->wdecor->style, &nrect, &arect);
657 gfx_rect_rtranslate(&arect.p0, &arect, &app_params.rect);
658
659 rc = gfx_bitmap_create(window->gc, &app_params, NULL,
660 &app_bmp);
661 if (rc != EOK)
662 goto error;
663
664 rc = gfx_bitmap_get_alloc(app_bmp, &app_alloc);
665 if (rc != EOK)
666 goto error;
667 }
668
669 /* dwindow can be NULL in case of unit tests or fullscreen mode */
670 if (window->dwindow != NULL) {
671 switch (scop) {
672 case ui_wsc_resize:
673 rc = display_window_resize(window->dwindow, &offs,
674 &nrect);
675 if (rc != EOK)
676 goto error;
677 break;
678 case ui_wsc_maximize:
679 rc = display_window_maximize(window->dwindow);
680 if (rc != EOK)
681 goto error;
682 break;
683 case ui_wsc_unmaximize:
684 rc = display_window_unmaximize(window->dwindow);
685 if (rc != EOK)
686 goto error;
687 break;
688 }
689 }
690
691 /* Client side rendering? */
692 if (window->mgc != NULL) {
693#ifndef CONFIG_WIN_DOUBLE_BUF
694 /* Window is resized, now we can map the window bitmap again */
695 gfx_bitmap_params_init(&win_params);
696 win_params.flags |= bmpf_direct_output;
697 win_params.rect = nrect;
698
699 rc = gfx_bitmap_create(window->realgc, &win_params, NULL,
700 &win_bmp);
701 if (rc != EOK)
702 goto error;
703
704 rc = gfx_bitmap_get_alloc(win_bmp, &win_alloc);
705 if (rc != EOK)
706 goto error;
707#endif
708 mem_gc_retarget(window->mgc, &win_params.rect, &win_alloc);
709
710 gfx_bitmap_destroy(window->bmp);
711 window->bmp = win_bmp;
712 }
713
714 window->rect = nrect;
715 ui_wdecor_set_rect(window->wdecor, &nrect);
716 ui_wdecor_paint(window->wdecor);
717 gfx_update(window->gc);
718
719 /* Application area GC? */
720 if (window->app_gc != NULL) {
721 mem_gc_retarget(window->app_mgc, &app_params.rect, &app_alloc);
722
723 gfx_bitmap_destroy(window->app_bmp);
724 window->app_bmp = app_bmp;
725 }
726
727 return EOK;
728error:
729 if (app_bmp != NULL)
730 gfx_bitmap_destroy(app_bmp);
731 if (win_bmp != NULL)
732 gfx_bitmap_destroy(win_bmp);
733 return rc;
734}
735
736/** Resize/move window.
737 *
738 * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
739 * the top-left corner of the window will move on the screen accordingly.
740 *
741 * @param window Window
742 * @param rect Rectangle
743 *
744 * @return EOK on success or an error code
745 */
746errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
747{
748 return ui_window_size_change(window, rect, ui_wsc_resize);
749}
750
751/** Set window callbacks.
752 *
753 * @param window Window
754 * @param cb Window callbacks
755 * @param arg Callback argument
756 */
757void ui_window_set_cb(ui_window_t *window, ui_window_cb_t *cb, void *arg)
758{
759 window->cb = cb;
760 window->arg = arg;
761}
762
763/** Change window caption.
764 *
765 * @param window Window
766 * @param caption New caption
767 *
768 * @return EOK on success or an error code
769 */
770errno_t ui_window_set_caption(ui_window_t *window, const char *caption)
771{
772 errno_t rc;
773
774 /* Set console caption if fullscreen window on console */
775 if (window->ui->console != NULL && window->placement ==
776 ui_wnd_place_full_screen) {
777 rc = console_set_caption(window->ui->console, caption);
778 if (rc != EOK)
779 return rc;
780 }
781
782 /* Set display window caption if running on display service */
783 if (window->dwindow != NULL) {
784 rc = display_window_set_caption(window->dwindow, caption);
785 if (rc != EOK)
786 return rc;
787 }
788
789 return ui_wdecor_set_caption(window->wdecor, caption);
790}
791
792/** Get window's containing UI.
793 *
794 * @param window Window
795 * @return Containing UI
796 */
797ui_t *ui_window_get_ui(ui_window_t *window)
798{
799 return window->ui;
800}
801
802/** Get UI resource from window.
803 *
804 * @param window Window
805 * @return UI resource
806 */
807ui_resource_t *ui_window_get_res(ui_window_t *window)
808{
809 return window->res;
810}
811
812/** Get window GC.
813 *
814 * @param window Window
815 * @return GC (relative to window)
816 */
817gfx_context_t *ui_window_get_gc(ui_window_t *window)
818{
819 return window->gc;
820}
821
822/** Get window position.
823 *
824 * @param window Window
825 * @param pos Place to store position
826 * @return EOK on success or an error code
827 */
828errno_t ui_window_get_pos(ui_window_t *window, gfx_coord2_t *pos)
829{
830 errno_t rc;
831
832 if (window->dwindow != NULL) {
833 rc = display_window_get_pos(window->dwindow, pos);
834 if (rc != EOK)
835 return rc;
836 } else {
837 *pos = window->dpos;
838 }
839
840 return EOK;
841}
842
843/** Get window application area GC
844 *
845 * @param window Window
846 * @param rgc Place to store GC (relative to application area)
847 * @return EOK on success or an error code
848 */
849errno_t ui_window_get_app_gc(ui_window_t *window, gfx_context_t **rgc)
850{
851 gfx_bitmap_params_t params;
852 gfx_bitmap_alloc_t alloc;
853 gfx_rect_t rect;
854 mem_gc_t *memgc;
855 errno_t rc;
856
857 if (window->app_gc == NULL) {
858 assert(window->app_bmp == NULL);
859
860 gfx_bitmap_params_init(&params);
861
862 /*
863 * The bitmap will have the same dimensions as the
864 * application rectangle, but start at 0,0.
865 */
866 ui_window_get_app_rect(window, &rect);
867 gfx_rect_rtranslate(&rect.p0, &rect, &params.rect);
868
869 rc = gfx_bitmap_create(window->gc, &params, NULL,
870 &window->app_bmp);
871 if (rc != EOK)
872 return rc;
873
874 rc = gfx_bitmap_get_alloc(window->app_bmp, &alloc);
875 if (rc != EOK) {
876 gfx_bitmap_destroy(window->app_bmp);
877 return rc;
878 }
879
880 rc = mem_gc_create(&params.rect, &alloc,
881 &ui_window_app_mem_gc_cb, (void *) window, &memgc);
882 if (rc != EOK) {
883 gfx_bitmap_destroy(window->app_bmp);
884 return rc;
885 }
886
887 window->app_mgc = memgc;
888 window->app_gc = mem_gc_get_ctx(memgc);
889 }
890
891 *rgc = window->app_gc;
892 return EOK;
893}
894
895/** Get window application rectangle
896 *
897 * @param window Window
898 * @param rect Place to store application rectangle
899 */
900void ui_window_get_app_rect(ui_window_t *window, gfx_rect_t *rect)
901{
902 ui_wdecor_geom_t geom;
903
904 ui_wdecor_get_geom(window->wdecor, &geom);
905 *rect = geom.app_area_rect;
906}
907
908/** Set cursor when pointer is hovering over a control.
909 *
910 * @param window Window
911 * @param cursor Cursor
912 */
913void ui_window_set_ctl_cursor(ui_window_t *window, ui_stock_cursor_t cursor)
914{
915 display_stock_cursor_t dcursor;
916
917 dcursor = wnd_dcursor_from_cursor(cursor);
918
919 if (window->dwindow != NULL)
920 (void) display_window_set_cursor(window->dwindow, dcursor);
921}
922
923/** Paint window
924 *
925 * @param window Window
926 * @return EOK on success or an error code
927 */
928errno_t ui_window_paint(ui_window_t *window)
929{
930 return ui_window_send_paint(window);
931}
932
933/** Handle window close event. */
934static void dwnd_close_event(void *arg)
935{
936 ui_window_t *window = (ui_window_t *) arg;
937 ui_t *ui = window->ui;
938
939 ui_lock(ui);
940 ui_window_send_close(window);
941 ui_unlock(ui);
942}
943
944/** Handle window focus event. */
945static void dwnd_focus_event(void *arg, unsigned nfocus)
946{
947 ui_window_t *window = (ui_window_t *) arg;
948 ui_t *ui = window->ui;
949
950 ui_lock(ui);
951 (void)nfocus;
952
953 if (window->wdecor != NULL) {
954 ui_wdecor_set_active(window->wdecor, true);
955 ui_wdecor_paint(window->wdecor);
956 }
957
958 ui_window_send_focus(window, nfocus);
959 ui_unlock(ui);
960}
961
962/** Handle window keyboard event */
963static void dwnd_kbd_event(void *arg, kbd_event_t *kbd_event)
964{
965 ui_window_t *window = (ui_window_t *) arg;
966 ui_t *ui = window->ui;
967
968 ui_lock(ui);
969 ui_window_send_kbd(window, kbd_event);
970 ui_unlock(ui);
971}
972
973/** Handle window position event */
974static void dwnd_pos_event(void *arg, pos_event_t *event)
975{
976 ui_window_t *window = (ui_window_t *) arg;
977 ui_t *ui = window->ui;
978 ui_evclaim_t claim;
979
980 /* Make sure we don't process events until fully initialized */
981 if (window->wdecor == NULL)
982 return;
983
984 ui_lock(ui);
985
986 claim = ui_wdecor_pos_event(window->wdecor, event);
987 if (claim == ui_claimed) {
988 ui_unlock(ui);
989 return;
990 }
991
992 ui_window_send_pos(window, event);
993 ui_unlock(ui);
994}
995
996/** Handle window resize event */
997static void dwnd_resize_event(void *arg, gfx_rect_t *rect)
998{
999 ui_window_t *window = (ui_window_t *) arg;
1000 ui_t *ui = window->ui;
1001
1002 /* Make sure we don't process events until fully initialized */
1003 if (window->wdecor == NULL)
1004 return;
1005
1006 if ((window->wdecor->style & ui_wds_resizable) == 0)
1007 return;
1008
1009 ui_lock(ui);
1010 (void) ui_window_resize(window, rect);
1011 (void) ui_window_paint(window);
1012 ui_unlock(ui);
1013}
1014
1015/** Handle window unfocus event. */
1016static void dwnd_unfocus_event(void *arg, unsigned nfocus)
1017{
1018 ui_window_t *window = (ui_window_t *) arg;
1019 ui_t *ui = window->ui;
1020
1021 ui_lock(ui);
1022
1023 if (window->wdecor != NULL && nfocus == 0) {
1024 ui_wdecor_set_active(window->wdecor, false);
1025 ui_wdecor_paint(window->wdecor);
1026 }
1027
1028 ui_window_send_unfocus(window, nfocus);
1029 ui_unlock(ui);
1030}
1031
1032/** Window decoration requested opening of system menu.
1033 *
1034 * @param wdecor Window decoration
1035 * @param arg Argument (window)
1036 * @param idev_id Input device ID
1037 */
1038static void wd_sysmenu(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
1039{
1040 ui_window_t *window = (ui_window_t *) arg;
1041
1042 ui_window_send_sysmenu(window, idev_id);
1043}
1044
1045/** Window decoration requested window minimization.
1046 *
1047 * @param wdecor Window decoration
1048 * @param arg Argument (window)
1049 */
1050static void wd_minimize(ui_wdecor_t *wdecor, void *arg)
1051{
1052 ui_window_t *window = (ui_window_t *) arg;
1053
1054 ui_window_send_minimize(window);
1055}
1056
1057/** Window decoration requested window maximization.
1058 *
1059 * @param wdecor Window decoration
1060 * @param arg Argument (window)
1061 */
1062static void wd_maximize(ui_wdecor_t *wdecor, void *arg)
1063{
1064 ui_window_t *window = (ui_window_t *) arg;
1065
1066 ui_window_send_maximize(window);
1067}
1068
1069/** Window decoration requested window unmaximization.
1070 *
1071 * @param wdecor Window decoration
1072 * @param arg Argument (window)
1073 */
1074static void wd_unmaximize(ui_wdecor_t *wdecor, void *arg)
1075{
1076 ui_window_t *window = (ui_window_t *) arg;
1077
1078 ui_window_send_unmaximize(window);
1079}
1080
1081/** Window decoration requested window closure.
1082 *
1083 * @param wdecor Window decoration
1084 * @param arg Argument (window)
1085 */
1086static void wd_close(ui_wdecor_t *wdecor, void *arg)
1087{
1088 ui_window_t *window = (ui_window_t *) arg;
1089
1090 ui_window_send_close(window);
1091}
1092
1093/** Window decoration requested window move.
1094 *
1095 * @param wdecor Window decoration
1096 * @param arg Argument (window)
1097 * @param pos Position where the title bar was pressed
1098 * @param pos_id Positioning device ID
1099 */
1100static void wd_move(ui_wdecor_t *wdecor, void *arg, gfx_coord2_t *pos,
1101 sysarg_t pos_id)
1102{
1103 ui_window_t *window = (ui_window_t *) arg;
1104
1105 if (window->dwindow != NULL)
1106 (void) display_window_move_req(window->dwindow, pos, pos_id);
1107}
1108
1109/** Window decoration requested window resize.
1110 *
1111 * @param wdecor Window decoration
1112 * @param arg Argument (window)
1113 * @param rsztype Resize type
1114 * @param pos Position where the button was pressed
1115 * @param pos_id Positioning device ID
1116 */
1117static void wd_resize(ui_wdecor_t *wdecor, void *arg,
1118 ui_wdecor_rsztype_t rsztype, gfx_coord2_t *pos, sysarg_t pos_id)
1119{
1120 ui_window_t *window = (ui_window_t *) arg;
1121
1122 if (window->dwindow != NULL) {
1123 (void) display_window_resize_req(window->dwindow, rsztype,
1124 pos, pos_id);
1125 }
1126}
1127
1128/** Get display stock cursor from UI stock cursor.
1129 *
1130 * @param cursor UI stock cursor
1131 * @return Display stock cursor
1132 */
1133display_stock_cursor_t wnd_dcursor_from_cursor(ui_stock_cursor_t cursor)
1134{
1135 display_stock_cursor_t dcursor;
1136
1137 dcursor = dcurs_arrow;
1138
1139 switch (cursor) {
1140 case ui_curs_arrow:
1141 dcursor = dcurs_arrow;
1142 break;
1143 case ui_curs_size_ud:
1144 dcursor = dcurs_size_ud;
1145 break;
1146 case ui_curs_size_lr:
1147 dcursor = dcurs_size_lr;
1148 break;
1149 case ui_curs_size_uldr:
1150 dcursor = dcurs_size_uldr;
1151 break;
1152 case ui_curs_size_urdl:
1153 dcursor = dcurs_size_urdl;
1154 break;
1155 case ui_curs_ibeam:
1156 dcursor = dcurs_ibeam;
1157 break;
1158 }
1159
1160 return dcursor;
1161}
1162
1163/** Window decoration requested changing cursor.
1164 *
1165 * @param wdecor Window decoration
1166 * @param arg Argument (window)
1167 * @param cursor Cursor to set
1168 */
1169static void wd_set_cursor(ui_wdecor_t *wdecor, void *arg,
1170 ui_stock_cursor_t cursor)
1171{
1172 ui_window_t *window = (ui_window_t *) arg;
1173 display_stock_cursor_t dcursor;
1174
1175 if (cursor == window->cursor)
1176 return;
1177
1178 dcursor = wnd_dcursor_from_cursor(cursor);
1179
1180 if (window->dwindow != NULL)
1181 (void) display_window_set_cursor(window->dwindow, dcursor);
1182
1183 window->cursor = cursor;
1184}
1185
1186/** Send window sysmenu event.
1187 *
1188 * @param window Window
1189 * @parma idev_id Input device ID
1190 */
1191void ui_window_send_sysmenu(ui_window_t *window, sysarg_t idev_id)
1192{
1193 if (window->cb != NULL && window->cb->sysmenu != NULL)
1194 window->cb->sysmenu(window, window->arg, idev_id);
1195 else
1196 ui_window_def_sysmenu(window, idev_id);
1197}
1198
1199/** Send window minimize event.
1200 *
1201 * @param window Window
1202 */
1203void ui_window_send_minimize(ui_window_t *window)
1204{
1205 if (window->cb != NULL && window->cb->maximize != NULL)
1206 window->cb->minimize(window, window->arg);
1207 else
1208 ui_window_def_minimize(window);
1209}
1210
1211/** Send window maximize event.
1212 *
1213 * @param window Window
1214 */
1215void ui_window_send_maximize(ui_window_t *window)
1216{
1217 if (window->cb != NULL && window->cb->maximize != NULL)
1218 window->cb->maximize(window, window->arg);
1219 else
1220 ui_window_def_maximize(window);
1221}
1222
1223/** Send window unmaximize event.
1224 *
1225 * @param window Window
1226 */
1227void ui_window_send_unmaximize(ui_window_t *window)
1228{
1229 if (window->cb != NULL && window->cb->unmaximize != NULL)
1230 window->cb->unmaximize(window, window->arg);
1231 else
1232 ui_window_def_unmaximize(window);
1233}
1234
1235/** Send window close event.
1236 *
1237 * @param window Window
1238 */
1239void ui_window_send_close(ui_window_t *window)
1240{
1241 if (window->cb != NULL && window->cb->close != NULL)
1242 window->cb->close(window, window->arg);
1243}
1244
1245/** Send window focus event.
1246 *
1247 * @param window Window
1248 * @param nfocus New number of foci
1249 */
1250void ui_window_send_focus(ui_window_t *window, unsigned nfocus)
1251{
1252 if (window->cb != NULL && window->cb->focus != NULL)
1253 window->cb->focus(window, window->arg, nfocus);
1254}
1255
1256/** Send window keyboard event.
1257 *
1258 * @param window Window
1259 */
1260void ui_window_send_kbd(ui_window_t *window, kbd_event_t *kbd)
1261{
1262 if (window->cb != NULL && window->cb->kbd != NULL)
1263 window->cb->kbd(window, window->arg, kbd);
1264 else
1265 ui_window_def_kbd(window, kbd);
1266}
1267
1268/** Send window paint event.
1269 *
1270 * @param window Window
1271 */
1272errno_t ui_window_send_paint(ui_window_t *window)
1273{
1274 if (window->cb != NULL && window->cb->paint != NULL)
1275 return window->cb->paint(window, window->arg);
1276 else
1277 return ui_window_def_paint(window);
1278}
1279
1280/** Send window position event.
1281 *
1282 * @param window Window
1283 */
1284void ui_window_send_pos(ui_window_t *window, pos_event_t *pos)
1285{
1286 if (window->cb != NULL && window->cb->pos != NULL)
1287 window->cb->pos(window, window->arg, pos);
1288 else
1289 ui_window_def_pos(window, pos);
1290}
1291
1292/** Send window unfocus event.
1293 *
1294 * @param window Window
1295 * @param nfocus Number of remaining foci
1296 */
1297void ui_window_send_unfocus(ui_window_t *window, unsigned nfocus)
1298{
1299 if (window->cb != NULL && window->cb->unfocus != NULL)
1300 window->cb->unfocus(window, window->arg, nfocus);
1301 else
1302 return ui_window_def_unfocus(window, nfocus);
1303}
1304
1305/** Default window sysmenu routine.
1306 *
1307 * @param window Window
1308 * @param idev_id Input device ID
1309 * @return EOK on success or an error code
1310 */
1311errno_t ui_window_def_sysmenu(ui_window_t *window, sysarg_t idev_id)
1312{
1313 errno_t rc;
1314 ui_wdecor_geom_t geom;
1315
1316 if (ui_menu_is_open(window->sysmenu)) {
1317 ui_menu_close(window->sysmenu);
1318 } else {
1319 ui_wdecor_get_geom(window->wdecor, &geom);
1320
1321 rc = ui_menu_open(window->sysmenu, &geom.title_bar_rect,
1322 idev_id);
1323 if (rc != EOK)
1324 goto error;
1325 }
1326
1327 return EOK;
1328error:
1329 return rc;
1330}
1331
1332/** Default window minimize routine.
1333 *
1334 * @param window Window
1335 * @return EOK on success or an error code
1336 */
1337errno_t ui_window_def_minimize(ui_window_t *window)
1338{
1339 errno_t rc;
1340
1341 if (window->dwindow != NULL) {
1342 rc = display_window_minimize(window->dwindow);
1343 if (rc != EOK)
1344 goto error;
1345 }
1346
1347 return EOK;
1348error:
1349 return rc;
1350}
1351
1352/** Default window maximize routine.
1353 *
1354 * @param window Window
1355 * @return EOK on success or an error code
1356 */
1357errno_t ui_window_def_maximize(ui_window_t *window)
1358{
1359 errno_t rc;
1360 gfx_rect_t old_rect;
1361 gfx_rect_t rect;
1362
1363 old_rect = window->rect;
1364
1365 if (window->dwindow != NULL) {
1366 rc = display_window_get_max_rect(window->dwindow, &rect);
1367 if (rc != EOK)
1368 return rc;
1369 } else {
1370 rect = window->ui->rect;
1371 }
1372
1373 ui_wdecor_set_maximized(window->wdecor, true);
1374 ui_menu_entry_set_disabled(window->sysmenu_restore, false);
1375 ui_menu_entry_set_disabled(window->sysmenu_maximize, true);
1376
1377 rc = ui_window_size_change(window, &rect, ui_wsc_maximize);
1378 if (rc != EOK) {
1379 ui_wdecor_set_maximized(window->wdecor, false);
1380 return rc;
1381 }
1382
1383 window->normal_rect = old_rect;
1384 (void) ui_window_paint(window);
1385 return EOK;
1386}
1387
1388/** Default window unmaximize routine.
1389 *
1390 * @param window Window
1391 * @return EOK on success or an error code
1392 */
1393errno_t ui_window_def_unmaximize(ui_window_t *window)
1394{
1395 errno_t rc;
1396
1397 ui_wdecor_set_maximized(window->wdecor, false);
1398 ui_menu_entry_set_disabled(window->sysmenu_restore, true);
1399 ui_menu_entry_set_disabled(window->sysmenu_maximize, false);
1400
1401 rc = ui_window_size_change(window, &window->normal_rect,
1402 ui_wsc_unmaximize);
1403 if (rc != EOK) {
1404 ui_wdecor_set_maximized(window->wdecor, true);
1405 printf("ui_window_size_change->error\n");
1406 return rc;
1407 }
1408
1409 (void) ui_window_paint(window);
1410 return EOK;
1411}
1412
1413/** Default window keyboard event routine.
1414 *
1415 * @param window Window
1416 * @return ui_claimed iff event was claimed
1417 */
1418ui_evclaim_t ui_window_def_kbd(ui_window_t *window, kbd_event_t *kbd)
1419{
1420 ui_evclaim_t claim;
1421
1422 if (window->control != NULL)
1423 claim = ui_control_kbd_event(window->control, kbd);
1424 else
1425 claim = ui_unclaimed;
1426
1427 if (claim == ui_unclaimed)
1428 return ui_wdecor_kbd_event(window->wdecor, kbd);
1429
1430 return ui_unclaimed;
1431}
1432
1433/** Default window paint routine.
1434 *
1435 * @param window Window
1436 * @return EOK on success or an error code
1437 */
1438errno_t ui_window_def_paint(ui_window_t *window)
1439{
1440 gfx_rect_t app_rect;
1441 errno_t rc;
1442
1443 rc = gfx_set_color(window->gc, window->res->wnd_face_color);
1444 if (rc != EOK)
1445 return rc;
1446
1447 ui_window_get_app_rect(window, &app_rect);
1448
1449 rc = gfx_fill_rect(window->gc, &app_rect);
1450 if (rc != EOK)
1451 return rc;
1452
1453 if (window->control != NULL)
1454 return ui_control_paint(window->control);
1455
1456 rc = gfx_update(window->res->gc);
1457 if (rc != EOK)
1458 return rc;
1459
1460 return EOK;
1461}
1462
1463/** Default window position event routine.
1464 *
1465 * @param window Window
1466 */
1467void ui_window_def_pos(ui_window_t *window, pos_event_t *pos)
1468{
1469 if (window->control != NULL)
1470 ui_control_pos_event(window->control, pos);
1471}
1472
1473/** Default window unfocus routine.
1474 *
1475 * @param window Window
1476 * @param nfocus Number of remaining foci
1477 * @return EOK on success or an error code
1478 */
1479void ui_window_def_unfocus(ui_window_t *window, unsigned nfocus)
1480{
1481 if (window->control != NULL)
1482 ui_control_unfocus(window->control, nfocus);
1483}
1484
1485/** Handle system menu left event.
1486 *
1487 * @param sysmenu System menu
1488 * @param arg Argument (ui_window_t *)
1489 * @param idev_id Input device ID
1490 */
1491static void wnd_sysmenu_left(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
1492{
1493 (void)sysmenu;
1494 (void)arg;
1495 (void)idev_id;
1496}
1497
1498/** Handle system menu right event.
1499 *
1500 * @param sysmenu System menu
1501 * @param arg Argument (ui_window_t *)
1502 * @param idev_id Input device ID
1503 */
1504static void wnd_sysmenu_right(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
1505{
1506 (void)sysmenu;
1507 (void)arg;
1508 (void)idev_id;
1509}
1510
1511/** Handle system menu close request event.
1512 *
1513 * @param sysmenu System menu
1514 * @param arg Argument (ui_window_t *)
1515 * @param idev_id Input device ID
1516 */
1517static void wnd_sysmenu_close_req(ui_menu_t *sysmenu, void *arg)
1518{
1519 (void)arg;
1520
1521 ui_menu_close(sysmenu);
1522}
1523
1524/** Handle system menu Restore entry activation.
1525 *
1526 * @param mentry Menu entry
1527 * @param arg Argument (ui_window_t *)
1528 */
1529static void wnd_sysmenu_erestore(ui_menu_entry_t *mentry, void *arg)
1530{
1531 ui_window_t *window = (ui_window_t *)arg;
1532
1533 ui_window_send_unmaximize(window);
1534}
1535
1536/** Handle system menu Minimize entry activation.
1537 *
1538 * @param mentry Menu entry
1539 * @param arg Argument (ui_window_t *)
1540 */
1541static void wnd_sysmenu_eminimize(ui_menu_entry_t *mentry, void *arg)
1542{
1543 ui_window_t *window = (ui_window_t *)arg;
1544
1545 ui_window_send_minimize(window);
1546}
1547
1548/** Handle system menu Maximize entry activation.
1549 *
1550 * @param mentry Menu entry
1551 * @param arg Argument (ui_window_t *)
1552 */
1553static void wnd_sysmenu_emaximize(ui_menu_entry_t *mentry, void *arg)
1554{
1555 ui_window_t *window = (ui_window_t *)arg;
1556
1557 ui_window_send_maximize(window);
1558}
1559
1560/** Handle system menu Close entry activation.
1561 *
1562 * @param mentry Menu entry
1563 * @param arg Argument (ui_window_t *)
1564 */
1565static void wnd_sysmenu_eclose(ui_menu_entry_t *mentry, void *arg)
1566{
1567 ui_window_t *window = (ui_window_t *)arg;
1568
1569 ui_window_send_close(window);
1570}
1571
1572/** Handle system menu press accelerator key event.
1573 *
1574 * @param sysmenu System menu
1575 * @param arg Argument (ui_window_t *)
1576 * @param idev_id Input device ID
1577 */
1578static void wnd_sysmenu_press_accel(ui_menu_t *sysmenu, void *arg,
1579 char32_t c, sysarg_t idev_id)
1580{
1581 (void)sysmenu;
1582 (void)arg;
1583 (void)c;
1584 (void)idev_id;
1585}
1586
1587/** Window invalidate callback
1588 *
1589 * @param arg Argument (ui_window_t *)
1590 * @param rect Rectangle to update
1591 */
1592static void ui_window_invalidate(void *arg, gfx_rect_t *rect)
1593{
1594 ui_window_t *window = (ui_window_t *) arg;
1595 gfx_rect_t env;
1596
1597 gfx_rect_envelope(&window->dirty_rect, rect, &env);
1598 window->dirty_rect = env;
1599}
1600
1601/** Window update callback
1602 *
1603 * @param arg Argument (ui_window_t *)
1604 */
1605static void ui_window_update(void *arg)
1606{
1607 ui_window_t *window = (ui_window_t *) arg;
1608
1609 if (!gfx_rect_is_empty(&window->dirty_rect)) {
1610 (void) gfx_bitmap_render(window->bmp, &window->dirty_rect,
1611 &window->dpos);
1612 }
1613
1614 window->dirty_rect.p0.x = 0;
1615 window->dirty_rect.p0.y = 0;
1616 window->dirty_rect.p1.x = 0;
1617 window->dirty_rect.p1.y = 0;
1618}
1619
1620/** Window cursor get position callback
1621 *
1622 * @param arg Argument (ui_window_t *)
1623 * @param pos Place to store position
1624 */
1625static errno_t ui_window_cursor_get_pos(void *arg, gfx_coord2_t *pos)
1626{
1627 ui_window_t *window = (ui_window_t *) arg;
1628 gfx_coord2_t cpos;
1629 errno_t rc;
1630
1631 rc = gfx_cursor_get_pos(window->realgc, &cpos);
1632 if (rc != EOK)
1633 return rc;
1634
1635 pos->x = cpos.x - window->dpos.x;
1636 pos->y = cpos.y - window->dpos.y;
1637 return EOK;
1638}
1639
1640/** Window cursor set position callback
1641 *
1642 * @param arg Argument (ui_window_t *)
1643 * @param pos New position
1644 */
1645static errno_t ui_window_cursor_set_pos(void *arg, gfx_coord2_t *pos)
1646{
1647 ui_window_t *window = (ui_window_t *) arg;
1648 gfx_coord2_t cpos;
1649
1650 cpos.x = pos->x + window->dpos.x;
1651 cpos.y = pos->y + window->dpos.y;
1652
1653 return gfx_cursor_set_pos(window->realgc, &cpos);
1654}
1655
1656/** Window cursor set visibility callback
1657 *
1658 * @param arg Argument (ui_window_t *)
1659 * @param visible @c true iff cursor is to be made visible
1660 */
1661static errno_t ui_window_cursor_set_visible(void *arg, bool visible)
1662{
1663 ui_window_t *window = (ui_window_t *) arg;
1664
1665 return gfx_cursor_set_visible(window->realgc, visible);
1666}
1667
1668/** Application area invalidate callback
1669 *
1670 * @param arg Argument (ui_window_t *)
1671 * @param rect Rectangle to update
1672 */
1673static void ui_window_app_invalidate(void *arg, gfx_rect_t *rect)
1674{
1675 ui_window_t *window = (ui_window_t *) arg;
1676 gfx_rect_t arect;
1677
1678 ui_window_get_app_rect(window, &arect);
1679
1680 /* Render bitmap rectangle inside the application area */
1681 (void) gfx_bitmap_render(window->app_bmp, rect, &arect.p0);
1682 /*
1683 * TODO Update applications to call gfx_update(), then
1684 * we can defer update to ui_window_app_update().
1685 */
1686 (void) gfx_update(window->res->gc);
1687}
1688
1689/** Application area update callback
1690 *
1691 * @param arg Argument (ui_window_t *)
1692 */
1693static void ui_window_app_update(void *arg)
1694{
1695 ui_window_t *window = (ui_window_t *) arg;
1696
1697 /*
1698 * Not used since display is updated immediately
1699 * in ui_window_app_invalidate
1700 */
1701 (void) window;
1702}
1703
1704/** Window expose callback. */
1705static void ui_window_expose_cb(void *arg)
1706{
1707 ui_window_t *window = (ui_window_t *) arg;
1708
1709 ui_window_paint(window);
1710}
1711
1712/** @}
1713 */
Note: See TracBrowser for help on using the repository browser.