2 * Copyright (c) 2024 Jiri Svoboda
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
36 #include <congfx/console.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>
46 #include <memgfx/memgc.h>
48 #include <ui/control.h>
49 #include <ui/menubar.h>
51 #include <ui/menuentry.h>
52 #include <ui/resource.h>
54 #include <ui/wdecor.h>
55 #include <ui/window.h>
56 #include "../private/control.h"
57 #include "../private/dummygc.h"
58 #include "../private/resource.h"
59 #include "../private/ui.h"
60 #include "../private/wdecor.h"
61 #include "../private/window.h"
63 static void dwnd_close_event(void *);
64 static void dwnd_focus_event(void *, unsigned);
65 static void dwnd_kbd_event(void *, kbd_event_t
*);
66 static void dwnd_pos_event(void *, pos_event_t
*);
67 static void dwnd_resize_event(void *, gfx_rect_t
*);
68 static void dwnd_unfocus_event(void *, unsigned);
70 static display_wnd_cb_t dwnd_cb
= {
71 .close_event
= dwnd_close_event
,
72 .focus_event
= dwnd_focus_event
,
73 .kbd_event
= dwnd_kbd_event
,
74 .pos_event
= dwnd_pos_event
,
75 .resize_event
= dwnd_resize_event
,
76 .unfocus_event
= dwnd_unfocus_event
79 static void wd_sysmenu_open(ui_wdecor_t
*, void *, sysarg_t
);
80 static void wd_sysmenu_left(ui_wdecor_t
*, void *, sysarg_t
);
81 static void wd_sysmenu_right(ui_wdecor_t
*, void *, sysarg_t
);
82 static void wd_sysmenu_accel(ui_wdecor_t
*, void *, char32_t
, sysarg_t
);
83 static void wd_minimize(ui_wdecor_t
*, void *);
84 static void wd_maximize(ui_wdecor_t
*, void *);
85 static void wd_unmaximize(ui_wdecor_t
*, void *);
86 static void wd_close(ui_wdecor_t
*, void *);
87 static void wd_move(ui_wdecor_t
*, void *, gfx_coord2_t
*, sysarg_t
);
88 static void wd_resize(ui_wdecor_t
*, void *, ui_wdecor_rsztype_t
,
89 gfx_coord2_t
*, sysarg_t
);
90 static void wd_set_cursor(ui_wdecor_t
*, void *, ui_stock_cursor_t
);
92 static ui_wdecor_cb_t wdecor_cb
= {
93 .sysmenu_open
= wd_sysmenu_open
,
94 .sysmenu_left
= wd_sysmenu_left
,
95 .sysmenu_right
= wd_sysmenu_right
,
96 .sysmenu_accel
= wd_sysmenu_accel
,
97 .minimize
= wd_minimize
,
98 .maximize
= wd_maximize
,
99 .unmaximize
= wd_unmaximize
,
103 .set_cursor
= wd_set_cursor
106 static void wnd_sysmenu_left(ui_menu_t
*, void *, sysarg_t
);
107 static void wnd_sysmenu_right(ui_menu_t
*, void *, sysarg_t
);
108 static void wnd_sysmenu_close_req(ui_menu_t
*, void *);
109 static void wnd_sysmenu_press_accel(ui_menu_t
*, void *, char32_t
, sysarg_t
);
111 static ui_menu_cb_t wnd_sysmenu_cb
= {
112 .left
= wnd_sysmenu_left
,
113 .right
= wnd_sysmenu_right
,
114 .close_req
= wnd_sysmenu_close_req
,
115 .press_accel
= wnd_sysmenu_press_accel
118 static void wnd_sysmenu_erestore(ui_menu_entry_t
*, void *);
119 static void wnd_sysmenu_eminimize(ui_menu_entry_t
*, void *);
120 static void wnd_sysmenu_emaximize(ui_menu_entry_t
*, void *);
121 static void wnd_sysmenu_eclose(ui_menu_entry_t
*, void *);
123 static void ui_window_invalidate(void *, gfx_rect_t
*);
124 static void ui_window_update(void *);
125 static errno_t
ui_window_cursor_get_pos(void *, gfx_coord2_t
*);
126 static errno_t
ui_window_cursor_set_pos(void *, gfx_coord2_t
*);
127 static errno_t
ui_window_cursor_set_visible(void *, bool);
129 /** Window memory GC callbacks */
130 static mem_gc_cb_t ui_window_mem_gc_cb
= {
131 .invalidate
= ui_window_invalidate
,
132 .update
= ui_window_update
,
133 .cursor_get_pos
= ui_window_cursor_get_pos
,
134 .cursor_set_pos
= ui_window_cursor_set_pos
,
135 .cursor_set_visible
= ui_window_cursor_set_visible
138 static void ui_window_app_invalidate(void *, gfx_rect_t
*);
139 static void ui_window_app_update(void *);
141 /** Application area memory GC callbacks */
142 static mem_gc_cb_t ui_window_app_mem_gc_cb
= {
143 .invalidate
= ui_window_app_invalidate
,
144 .update
= ui_window_app_update
147 static void ui_window_expose_cb(void *);
149 /** Initialize window parameters structure.
151 * Window parameters structure must always be initialized using this function
152 * first. By default, the window will be decorated. To get a non-decorated
153 * window, one needs to clear ui_wds_decorated
154 * (e.g. params->style &= ~ui_wds_decorated).
156 * @param params Window parameters structure
158 void ui_wnd_params_init(ui_wnd_params_t
*params
)
160 memset(params
, 0, sizeof(ui_wnd_params_t
));
162 /* Make window decorated by default. */
163 params
->style
= ui_wds_decorated
;
166 /** Compute where window should be placed on the screen.
168 * This only applies to windows that do not use default placement or
169 * if we are running in full-screen mode.
171 * @param window Window
172 * @param drect Display rectangle
173 * @param params Window parameters
174 * @param pos Place to store position of top-left corner
176 static void ui_window_place(ui_window_t
*window
, gfx_rect_t
*drect
,
177 ui_wnd_params_t
*params
, gfx_coord2_t
*pos
)
180 gfx_coord2_t below_pos
;
181 gfx_rect_t below_rect
;
183 assert(params
->placement
!= ui_wnd_place_default
||
184 ui_is_fullscreen(window
->ui
));
189 switch (params
->placement
) {
190 case ui_wnd_place_default
:
191 assert(ui_is_fullscreen(window
->ui
));
193 gfx_rect_dims(¶ms
->rect
, &dims
);
194 pos
->x
= (drect
->p0
.x
+ drect
->p1
.x
) / 2 - dims
.x
/ 2;
195 pos
->y
= (drect
->p0
.y
+ drect
->p1
.y
) / 2 - dims
.y
/ 2;
197 case ui_wnd_place_top_left
:
198 case ui_wnd_place_full_screen
:
199 pos
->x
= drect
->p0
.x
- params
->rect
.p0
.x
;
200 pos
->y
= drect
->p0
.y
- params
->rect
.p0
.y
;
202 case ui_wnd_place_top_right
:
203 pos
->x
= drect
->p1
.x
- params
->rect
.p1
.x
;
204 pos
->y
= drect
->p0
.y
- params
->rect
.p0
.y
;
206 case ui_wnd_place_bottom_left
:
207 pos
->x
= drect
->p0
.x
- params
->rect
.p0
.x
;
208 pos
->y
= drect
->p1
.y
- params
->rect
.p1
.y
;
210 case ui_wnd_place_bottom_right
:
211 pos
->x
= drect
->p1
.x
- params
->rect
.p1
.x
;
212 pos
->y
= drect
->p1
.y
- params
->rect
.p1
.y
;
214 case ui_wnd_place_popup
:
215 /* Compute rectangle when placed below */
216 below_pos
.x
= params
->prect
.p0
.x
;
217 below_pos
.y
= params
->prect
.p1
.y
;
218 gfx_rect_translate(&below_pos
, ¶ms
->rect
, &below_rect
);
220 /* Does below_rect fit within the display? */
221 if (gfx_rect_is_inside(&below_rect
, drect
)) {
222 /* Place popup window below parent rectangle */
223 pos
->x
= params
->prect
.p0
.x
- params
->rect
.p0
.x
;
224 pos
->y
= params
->prect
.p1
.y
- params
->rect
.p0
.y
;
226 /* Place popup window above parent rectangle */
227 pos
->x
= params
->prect
.p0
.x
;
228 pos
->y
= params
->prect
.p0
.y
-
229 (params
->rect
.p1
.y
- params
->rect
.p0
.y
);
235 /** Create window's system menu.
237 * @param window Window
238 * @return EOK on success or an error code
240 static errno_t
ui_window_sysmenu_create(ui_window_t
*window
)
243 ui_menu_entry_t
*mrestore
;
244 ui_menu_entry_t
*mmin
;
245 ui_menu_entry_t
*mmax
;
246 ui_menu_entry_t
*msep
;
247 ui_menu_entry_t
*mclose
;
249 rc
= ui_menu_create(window
, &window
->sysmenu
);
253 ui_menu_set_cb(window
->sysmenu
, &wnd_sysmenu_cb
, (void *)window
);
255 rc
= ui_menu_entry_create(window
->sysmenu
, "~R~estore",
260 if (!window
->wdecor
->maximized
)
261 ui_menu_entry_set_disabled(mrestore
, true);
263 ui_menu_entry_set_cb(mrestore
, wnd_sysmenu_erestore
, (void *)window
);
265 rc
= ui_menu_entry_create(window
->sysmenu
, "Mi~n~imize",
270 if ((window
->wdecor
->style
& ui_wds_minimize_btn
) == 0)
271 ui_menu_entry_set_disabled(mmin
, true);
273 ui_menu_entry_set_cb(mmin
, wnd_sysmenu_eminimize
, (void *)window
);
275 rc
= ui_menu_entry_create(window
->sysmenu
, "Ma~x~imize",
280 if ((window
->wdecor
->style
& ui_wds_maximize_btn
) == 0 ||
281 window
->wdecor
->maximized
)
282 ui_menu_entry_set_disabled(mmax
, true);
284 ui_menu_entry_set_cb(mmax
, wnd_sysmenu_emaximize
, (void *)window
);
286 rc
= ui_menu_entry_sep_create(window
->sysmenu
, &msep
);
290 rc
= ui_menu_entry_create(window
->sysmenu
, "~C~lose", "Alt-F4",
295 if ((window
->wdecor
->style
& ui_wds_close_btn
) == 0)
296 ui_menu_entry_set_disabled(mclose
, true);
298 ui_menu_entry_set_cb(mclose
, wnd_sysmenu_eclose
, (void *)window
);
300 window
->sysmenu_restore
= mrestore
;
301 window
->sysmenu_minimize
= mmin
;
302 window
->sysmenu_maximize
= mmax
;
309 /** Create new window.
311 * @param ui User interface
312 * @param params Window parameters
313 * @param rwindow Place to store pointer to new window
314 * @return EOK on success or an error code
316 errno_t
ui_window_create(ui_t
*ui
, ui_wnd_params_t
*params
,
317 ui_window_t
**rwindow
)
320 ui_window_t
*pwindow
= NULL
;
322 gfx_coord2_t scr_dims
;
323 display_wnd_params_t dparams
;
324 gfx_context_t
*gc
= NULL
;
325 ui_resource_t
*res
= NULL
;
326 ui_wdecor_t
*wdecor
= NULL
;
327 dummy_gc_t
*dgc
= NULL
;
328 gfx_bitmap_params_t bparams
;
329 gfx_bitmap_alloc_t alloc
;
330 gfx_bitmap_t
*bmp
= NULL
;
332 mem_gc_t
*memgc
= NULL
;
333 xlate_gc_t
*xgc
= NULL
;
336 window
= calloc(1, sizeof(ui_window_t
));
342 display_wnd_params_init(&dparams
);
343 dparams
.rect
= params
->rect
;
344 dparams
.caption
= params
->caption
;
345 /* Only allow making the window larger */
346 gfx_rect_dims(¶ms
->rect
, &dparams
.min_size
);
349 * If idev_id is not specified, use the UI default (probably
350 * obtained from display specification. This creates the
351 * main window in the seat specified on the command line.
353 if (params
->idev_id
!= 0)
354 dparams
.idev_id
= params
->idev_id
;
356 dparams
.idev_id
= ui
->idev_id
;
358 if ((params
->flags
& ui_wndf_popup
) != 0)
359 dparams
.flags
|= wndf_popup
;
360 if ((params
->flags
& ui_wndf_topmost
) != 0)
361 dparams
.flags
|= wndf_topmost
;
362 if ((params
->flags
& ui_wndf_system
) != 0)
363 dparams
.flags
|= wndf_system
;
364 if ((params
->flags
& ui_wndf_avoid
) != 0)
365 dparams
.flags
|= wndf_avoid
;
367 if (ui
->display
!= NULL
) {
368 if (params
->placement
!= ui_wnd_place_default
) {
369 rc
= display_get_info(ui
->display
, &info
);
374 if (params
->placement
== ui_wnd_place_full_screen
) {
375 /* Make window the size of the screen */
376 gfx_rect_dims(&info
.rect
, &scr_dims
);
377 gfx_coord2_add(&dparams
.rect
.p0
, &scr_dims
,
381 if (params
->placement
!= ui_wnd_place_default
) {
382 /* Set initial display window position */
383 ui_window_place(window
, &info
.rect
, params
,
386 dparams
.flags
|= wndf_setpos
;
389 rc
= display_window_create(ui
->display
, &dparams
, &dwnd_cb
,
390 (void *) window
, &window
->dwindow
);
394 rc
= display_window_get_gc(window
->dwindow
, &gc
);
397 } else if (ui
->console
!= NULL
) {
398 gc
= console_gc_get_ctx(ui
->cgc
);
400 if (params
->placement
== ui_wnd_place_full_screen
) {
401 /* Make window the size of the screen */
402 gfx_rect_dims(&ui
->rect
, &scr_dims
);
403 gfx_coord2_add(&dparams
.rect
.p0
, &scr_dims
,
405 (void) console_set_caption(ui
->console
,
409 /* Needed for unit tests */
410 rc
= dummygc_create(&dgc
);
414 gc
= dummygc_get_ctx(dgc
);
417 #ifdef CONFIG_UI_CS_RENDER
418 /* Create window bitmap */
419 gfx_bitmap_params_init(&bparams
);
420 #ifndef CONFIG_WIN_DOUBLE_BUF
421 /* Console does not support direct output */
422 if (ui
->display
!= NULL
)
423 bparams
.flags
|= bmpf_direct_output
;
426 /* Move rectangle so that top-left corner is 0,0 */
427 gfx_rect_rtranslate(&dparams
.rect
.p0
, &dparams
.rect
, &bparams
.rect
);
429 rc
= gfx_bitmap_create(gc
, &bparams
, NULL
, &bmp
);
433 /* Create memory GC */
434 rc
= gfx_bitmap_get_alloc(bmp
, &alloc
);
436 gfx_bitmap_destroy(window
->app_bmp
);
440 rc
= mem_gc_create(&bparams
.rect
, &alloc
, &ui_window_mem_gc_cb
,
441 (void *) window
, &memgc
);
443 gfx_bitmap_destroy(window
->app_bmp
);
449 window
->gc
= mem_gc_get_ctx(memgc
);
453 /* Server-side rendering */
455 /* Full-screen mode? */
456 if (ui
->display
== NULL
) {
457 /* Create translating GC to translate window contents */
460 rc
= xlate_gc_create(&off
, gc
, &xgc
);
465 window
->gc
= xlate_gc_get_ctx(xgc
);
471 (void) ui_window_mem_gc_cb
;
475 if (ui
->display
== NULL
) {
476 ui_window_place(window
, &ui
->rect
, params
, &window
->dpos
);
478 if (window
->xgc
!= NULL
)
479 xlate_gc_set_off(window
->xgc
, &window
->dpos
);
482 rc
= ui_resource_create(window
->gc
, ui_is_textmode(ui
), &res
);
486 rc
= ui_wdecor_create(res
, params
->caption
, params
->style
, &wdecor
);
490 ui_wdecor_set_rect(wdecor
, &dparams
.rect
);
491 ui_wdecor_set_cb(wdecor
, &wdecor_cb
, (void *) window
);
492 ui_wdecor_paint(wdecor
);
494 ui_resource_set_expose_cb(res
, ui_window_expose_cb
, (void *) window
);
496 window
->rect
= dparams
.rect
;
498 window
->wdecor
= wdecor
;
499 window
->cursor
= ui_curs_arrow
;
500 window
->placement
= params
->placement
;
502 rc
= ui_window_sysmenu_create(window
);
508 if (ui_is_fullscreen(ui
))
509 pwindow
= ui_window_get_active(ui
);
511 list_append(&window
->lwindows
, &ui
->windows
);
513 if (ui_is_fullscreen(ui
)) {
514 /* Send unfocus event to previously active window */
516 ui_window_send_unfocus(pwindow
, 0);
522 ui_wdecor_destroy(wdecor
);
524 ui_resource_destroy(res
);
526 mem_gc_delete(memgc
);
528 xlate_gc_delete(xgc
);
530 gfx_bitmap_destroy(bmp
);
532 dummygc_destroy(dgc
);
539 * @param window Window or @c NULL
541 void ui_window_destroy(ui_window_t
*window
)
544 ui_window_t
*nwindow
;
551 list_remove(&window
->lwindows
);
552 ui_control_destroy(window
->control
);
553 ui_menu_destroy(window
->sysmenu
);
554 ui_wdecor_destroy(window
->wdecor
);
555 ui_resource_destroy(window
->res
);
556 if (window
->app_mgc
!= NULL
)
557 mem_gc_delete(window
->app_mgc
);
558 if (window
->app_bmp
!= NULL
)
559 gfx_bitmap_destroy(window
->app_bmp
);
560 if (window
->mgc
!= NULL
) {
561 mem_gc_delete(window
->mgc
);
564 if (window
->bmp
!= NULL
)
565 gfx_bitmap_destroy(window
->bmp
);
566 if (window
->dwindow
!= NULL
)
567 display_window_destroy(window
->dwindow
);
569 /* Need to repaint if windows are emulated */
570 if (ui_is_fullscreen(ui
)) {
572 /* Send focus event to newly active window */
573 nwindow
= ui_window_get_active(ui
);
575 ui_window_send_focus(nwindow
, 0);
578 if (ui
->console
!= NULL
&&
579 window
->placement
== ui_wnd_place_full_screen
) {
580 (void) console_set_caption(ui
->console
, "");
586 /** Add control to window.
588 * Only one control can be added to a window. If more than one control
589 * is added, the results are undefined.
591 * @param window Window
592 * @param control Control
594 void ui_window_add(ui_window_t
*window
, ui_control_t
*control
)
596 assert(window
->control
== NULL
);
598 window
->control
= control
;
599 control
->elemp
= (void *) window
;
602 /** Remove control from window.
604 * @param window Window
605 * @param control Control
607 void ui_window_remove(ui_window_t
*window
, ui_control_t
*control
)
609 assert(window
->control
== control
);
610 assert((ui_window_t
*) control
->elemp
== window
);
612 window
->control
= NULL
;
613 control
->elemp
= NULL
;
616 /** Get active window (only valid in fullscreen mode).
618 * @param ui User interface
619 * @return Active window
621 ui_window_t
*ui_window_get_active(ui_t
*ui
)
625 link
= list_last(&ui
->windows
);
629 return list_get_instance(link
, ui_window_t
, lwindows
);
632 /** Resize or (un)maximize window.
634 * @param window Window
635 * @param rect Rectangle
636 * @param scop Size change operation
638 * @return EOK on success or an error code
640 errno_t
ui_window_size_change(ui_window_t
*window
, gfx_rect_t
*rect
,
646 gfx_bitmap_t
*app_bmp
= NULL
;
647 gfx_bitmap_t
*win_bmp
= NULL
;
648 gfx_bitmap_params_t app_params
;
649 gfx_bitmap_params_t win_params
;
650 gfx_bitmap_alloc_t app_alloc
;
651 gfx_bitmap_alloc_t win_alloc
;
655 * Move rect so that p0=0,0 - keep window's coordinate system origin
656 * locked to top-left corner of the window.
659 gfx_rect_rtranslate(&offs
, rect
, &nrect
);
661 /* mgc != NULL iff client-side rendering */
662 if (window
->mgc
!= NULL
) {
663 #ifdef CONFIG_WIN_DOUBLE_BUF
665 * Create new window bitmap in advance. If direct mapping,
666 * will need do it after resizing the window.
668 assert(window
->bmp
!= NULL
);
669 gfx_bitmap_params_init(&win_params
);
670 win_params
.rect
= nrect
;
672 rc
= gfx_bitmap_create(window
->realgc
, &win_params
, NULL
,
677 rc
= gfx_bitmap_get_alloc(win_bmp
, &win_alloc
);
683 /* Application area GC? */
684 if (window
->app_gc
!= NULL
) {
685 /* Resize application bitmap */
686 assert(window
->app_bmp
!= NULL
);
688 gfx_bitmap_params_init(&app_params
);
691 * The bitmap will have the same dimensions as the
692 * application rectangle, but start at 0,0.
694 ui_wdecor_app_from_rect(window
->wdecor
->style
, &nrect
, &arect
);
695 gfx_rect_rtranslate(&arect
.p0
, &arect
, &app_params
.rect
);
697 rc
= gfx_bitmap_create(window
->gc
, &app_params
, NULL
,
702 rc
= gfx_bitmap_get_alloc(app_bmp
, &app_alloc
);
707 /* dwindow can be NULL in case of unit tests or fullscreen mode */
708 if (window
->dwindow
!= NULL
) {
711 rc
= display_window_resize(window
->dwindow
, &offs
,
716 case ui_wsc_maximize
:
717 rc
= display_window_maximize(window
->dwindow
);
721 case ui_wsc_unmaximize
:
722 rc
= display_window_unmaximize(window
->dwindow
);
729 /* Client side rendering? */
730 if (window
->mgc
!= NULL
) {
731 #ifndef CONFIG_WIN_DOUBLE_BUF
732 /* Window is resized, now we can map the window bitmap again */
733 gfx_bitmap_params_init(&win_params
);
734 win_params
.flags
|= bmpf_direct_output
;
735 win_params
.rect
= nrect
;
737 rc
= gfx_bitmap_create(window
->realgc
, &win_params
, NULL
,
742 rc
= gfx_bitmap_get_alloc(win_bmp
, &win_alloc
);
746 mem_gc_retarget(window
->mgc
, &win_params
.rect
, &win_alloc
);
748 gfx_bitmap_destroy(window
->bmp
);
749 window
->bmp
= win_bmp
;
752 window
->rect
= nrect
;
753 ui_wdecor_set_rect(window
->wdecor
, &nrect
);
754 ui_wdecor_paint(window
->wdecor
);
755 gfx_update(window
->gc
);
757 /* Application area GC? */
758 if (window
->app_gc
!= NULL
) {
759 mem_gc_retarget(window
->app_mgc
, &app_params
.rect
, &app_alloc
);
761 gfx_bitmap_destroy(window
->app_bmp
);
762 window
->app_bmp
= app_bmp
;
768 gfx_bitmap_destroy(app_bmp
);
770 gfx_bitmap_destroy(win_bmp
);
774 /** Resize/move window.
776 * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
777 * the top-left corner of the window will move on the screen accordingly.
779 * @param window Window
780 * @param rect Rectangle
782 * @return EOK on success or an error code
784 errno_t
ui_window_resize(ui_window_t
*window
, gfx_rect_t
*rect
)
786 return ui_window_size_change(window
, rect
, ui_wsc_resize
);
789 /** Set window callbacks.
791 * @param window Window
792 * @param cb Window callbacks
793 * @param arg Callback argument
795 void ui_window_set_cb(ui_window_t
*window
, ui_window_cb_t
*cb
, void *arg
)
801 /** Change window caption.
803 * @param window Window
804 * @param caption New caption
806 * @return EOK on success or an error code
808 errno_t
ui_window_set_caption(ui_window_t
*window
, const char *caption
)
812 /* Set console caption if fullscreen window on console */
813 if (window
->ui
->console
!= NULL
&& window
->placement
==
814 ui_wnd_place_full_screen
) {
815 rc
= console_set_caption(window
->ui
->console
, caption
);
820 /* Set display window caption if running on display service */
821 if (window
->dwindow
!= NULL
) {
822 rc
= display_window_set_caption(window
->dwindow
, caption
);
827 return ui_wdecor_set_caption(window
->wdecor
, caption
);
830 /** Get window's containing UI.
832 * @param window Window
833 * @return Containing UI
835 ui_t
*ui_window_get_ui(ui_window_t
*window
)
840 /** Get UI resource from window.
842 * @param window Window
843 * @return UI resource
845 ui_resource_t
*ui_window_get_res(ui_window_t
*window
)
852 * @param window Window
853 * @return GC (relative to window)
855 gfx_context_t
*ui_window_get_gc(ui_window_t
*window
)
860 /** Get window position.
862 * @param window Window
863 * @param pos Place to store position
864 * @return EOK on success or an error code
866 errno_t
ui_window_get_pos(ui_window_t
*window
, gfx_coord2_t
*pos
)
870 if (window
->dwindow
!= NULL
) {
871 rc
= display_window_get_pos(window
->dwindow
, pos
);
881 /** Get window application area GC
883 * @param window Window
884 * @param rgc Place to store GC (relative to application area)
885 * @return EOK on success or an error code
887 errno_t
ui_window_get_app_gc(ui_window_t
*window
, gfx_context_t
**rgc
)
889 gfx_bitmap_params_t params
;
890 gfx_bitmap_alloc_t alloc
;
895 if (window
->app_gc
== NULL
) {
896 assert(window
->app_bmp
== NULL
);
898 gfx_bitmap_params_init(¶ms
);
901 * The bitmap will have the same dimensions as the
902 * application rectangle, but start at 0,0.
904 ui_window_get_app_rect(window
, &rect
);
905 gfx_rect_rtranslate(&rect
.p0
, &rect
, ¶ms
.rect
);
907 rc
= gfx_bitmap_create(window
->gc
, ¶ms
, NULL
,
912 rc
= gfx_bitmap_get_alloc(window
->app_bmp
, &alloc
);
914 gfx_bitmap_destroy(window
->app_bmp
);
918 rc
= mem_gc_create(¶ms
.rect
, &alloc
,
919 &ui_window_app_mem_gc_cb
, (void *) window
, &memgc
);
921 gfx_bitmap_destroy(window
->app_bmp
);
925 window
->app_mgc
= memgc
;
926 window
->app_gc
= mem_gc_get_ctx(memgc
);
929 *rgc
= window
->app_gc
;
933 /** Get window application rectangle
935 * @param window Window
936 * @param rect Place to store application rectangle
938 void ui_window_get_app_rect(ui_window_t
*window
, gfx_rect_t
*rect
)
940 ui_wdecor_geom_t geom
;
942 ui_wdecor_get_geom(window
->wdecor
, &geom
);
943 *rect
= geom
.app_area_rect
;
946 /** Set cursor when pointer is hovering over a control.
948 * @param window Window
949 * @param cursor Cursor
951 void ui_window_set_ctl_cursor(ui_window_t
*window
, ui_stock_cursor_t cursor
)
953 display_stock_cursor_t dcursor
;
955 dcursor
= wnd_dcursor_from_cursor(cursor
);
957 if (window
->dwindow
!= NULL
)
958 (void) display_window_set_cursor(window
->dwindow
, dcursor
);
963 * @param window Window
964 * @return EOK on success or an error code
966 errno_t
ui_window_paint(ui_window_t
*window
)
968 return ui_window_send_paint(window
);
971 /** Handle window close event. */
972 static void dwnd_close_event(void *arg
)
974 ui_window_t
*window
= (ui_window_t
*) arg
;
975 ui_t
*ui
= window
->ui
;
978 ui_window_send_close(window
);
982 /** Handle window focus event. */
983 static void dwnd_focus_event(void *arg
, unsigned nfocus
)
985 ui_window_t
*window
= (ui_window_t
*) arg
;
986 ui_t
*ui
= window
->ui
;
991 if (window
->wdecor
!= NULL
) {
992 ui_wdecor_set_active(window
->wdecor
, true);
993 ui_wdecor_paint(window
->wdecor
);
996 ui_window_send_focus(window
, nfocus
);
1000 /** Handle window keyboard event */
1001 static void dwnd_kbd_event(void *arg
, kbd_event_t
*kbd_event
)
1003 ui_window_t
*window
= (ui_window_t
*) arg
;
1004 ui_t
*ui
= window
->ui
;
1007 ui_window_send_kbd(window
, kbd_event
);
1011 /** Handle window position event */
1012 static void dwnd_pos_event(void *arg
, pos_event_t
*event
)
1014 ui_window_t
*window
= (ui_window_t
*) arg
;
1015 ui_t
*ui
= window
->ui
;
1018 /* Make sure we don't process events until fully initialized */
1019 if (window
->wdecor
== NULL
)
1024 claim
= ui_wdecor_pos_event(window
->wdecor
, event
);
1025 if (claim
== ui_claimed
) {
1030 ui_window_send_pos(window
, event
);
1034 /** Handle window resize event */
1035 static void dwnd_resize_event(void *arg
, gfx_rect_t
*rect
)
1037 ui_window_t
*window
= (ui_window_t
*) arg
;
1038 ui_t
*ui
= window
->ui
;
1040 /* Make sure we don't process events until fully initialized */
1041 if (window
->wdecor
== NULL
)
1044 if ((window
->wdecor
->style
& ui_wds_resizable
) == 0)
1048 (void) ui_window_resize(window
, rect
);
1049 (void) ui_window_paint(window
);
1053 /** Handle window unfocus event. */
1054 static void dwnd_unfocus_event(void *arg
, unsigned nfocus
)
1056 ui_window_t
*window
= (ui_window_t
*) arg
;
1057 ui_t
*ui
= window
->ui
;
1061 if (window
->wdecor
!= NULL
&& nfocus
== 0) {
1062 ui_wdecor_set_active(window
->wdecor
, false);
1063 ui_wdecor_paint(window
->wdecor
);
1066 ui_window_send_unfocus(window
, nfocus
);
1070 /** Window decoration requested opening of system menu.
1072 * @param wdecor Window decoration
1073 * @param arg Argument (window)
1074 * @param idev_id Input device ID
1076 static void wd_sysmenu_open(ui_wdecor_t
*wdecor
, void *arg
, sysarg_t idev_id
)
1078 ui_window_t
*window
= (ui_window_t
*) arg
;
1080 ui_window_send_sysmenu(window
, idev_id
);
1083 /** Window decoration requested moving left from system menu handle.
1085 * @param wdecor Window decoration
1086 * @param arg Argument (window)
1087 * @param idev_id Input device ID
1089 static void wd_sysmenu_left(ui_wdecor_t
*wdecor
, void *arg
, sysarg_t idev_id
)
1091 ui_window_t
*window
= (ui_window_t
*) arg
;
1093 if (window
->mbar
!= NULL
) {
1094 ui_wdecor_sysmenu_hdl_set_active(window
->wdecor
, false);
1095 ui_menu_close(window
->sysmenu
);
1096 ui_menu_bar_select_last(window
->mbar
, false, idev_id
);
1100 /** Window decoration requested moving right from system menu handle.
1102 * @param wdecor Window decoration
1103 * @param arg Argument (window)
1104 * @param idev_id Input device ID
1106 static void wd_sysmenu_right(ui_wdecor_t
*wdecor
, void *arg
, sysarg_t idev_id
)
1108 ui_window_t
*window
= (ui_window_t
*) arg
;
1110 if (window
->mbar
!= NULL
) {
1111 ui_wdecor_sysmenu_hdl_set_active(window
->wdecor
, false);
1112 ui_menu_close(window
->sysmenu
);
1113 ui_menu_bar_select_first(window
->mbar
, false, idev_id
);
1117 /** Window decoration detected accelerator press from system menu handle.
1119 * @param wdecor Window decoration
1120 * @param arg Argument (window)
1121 * @param c Accelerator key
1122 * @param idev_id Input device ID
1124 static void wd_sysmenu_accel(ui_wdecor_t
*wdecor
, void *arg
, char32_t c
,
1127 ui_window_t
*window
= (ui_window_t
*) arg
;
1129 if (window
->mbar
!= NULL
) {
1130 ui_wdecor_sysmenu_hdl_set_active(window
->wdecor
, false);
1131 ui_menu_close(window
->sysmenu
);
1132 ui_menu_bar_press_accel(window
->mbar
, c
, idev_id
);
1136 /** Window decoration requested window minimization.
1138 * @param wdecor Window decoration
1139 * @param arg Argument (window)
1141 static void wd_minimize(ui_wdecor_t
*wdecor
, void *arg
)
1143 ui_window_t
*window
= (ui_window_t
*) arg
;
1145 ui_window_send_minimize(window
);
1148 /** Window decoration requested window maximization.
1150 * @param wdecor Window decoration
1151 * @param arg Argument (window)
1153 static void wd_maximize(ui_wdecor_t
*wdecor
, void *arg
)
1155 ui_window_t
*window
= (ui_window_t
*) arg
;
1157 ui_window_send_maximize(window
);
1160 /** Window decoration requested window unmaximization.
1162 * @param wdecor Window decoration
1163 * @param arg Argument (window)
1165 static void wd_unmaximize(ui_wdecor_t
*wdecor
, void *arg
)
1167 ui_window_t
*window
= (ui_window_t
*) arg
;
1169 ui_window_send_unmaximize(window
);
1172 /** Window decoration requested window closure.
1174 * @param wdecor Window decoration
1175 * @param arg Argument (window)
1177 static void wd_close(ui_wdecor_t
*wdecor
, void *arg
)
1179 ui_window_t
*window
= (ui_window_t
*) arg
;
1181 ui_window_send_close(window
);
1184 /** Window decoration requested window move.
1186 * @param wdecor Window decoration
1187 * @param arg Argument (window)
1188 * @param pos Position where the title bar was pressed
1189 * @param pos_id Positioning device ID
1191 static void wd_move(ui_wdecor_t
*wdecor
, void *arg
, gfx_coord2_t
*pos
,
1194 ui_window_t
*window
= (ui_window_t
*) arg
;
1196 if (window
->dwindow
!= NULL
)
1197 (void) display_window_move_req(window
->dwindow
, pos
, pos_id
);
1200 /** Window decoration requested window resize.
1202 * @param wdecor Window decoration
1203 * @param arg Argument (window)
1204 * @param rsztype Resize type
1205 * @param pos Position where the button was pressed
1206 * @param pos_id Positioning device ID
1208 static void wd_resize(ui_wdecor_t
*wdecor
, void *arg
,
1209 ui_wdecor_rsztype_t rsztype
, gfx_coord2_t
*pos
, sysarg_t pos_id
)
1211 ui_window_t
*window
= (ui_window_t
*) arg
;
1213 if (window
->dwindow
!= NULL
) {
1214 (void) display_window_resize_req(window
->dwindow
,
1215 (display_wnd_rsztype_t
) rsztype
, // Same constants in the enums
1220 /** Get display stock cursor from UI stock cursor.
1222 * @param cursor UI stock cursor
1223 * @return Display stock cursor
1225 display_stock_cursor_t
wnd_dcursor_from_cursor(ui_stock_cursor_t cursor
)
1227 display_stock_cursor_t dcursor
;
1229 dcursor
= dcurs_arrow
;
1233 dcursor
= dcurs_arrow
;
1235 case ui_curs_size_ud
:
1236 dcursor
= dcurs_size_ud
;
1238 case ui_curs_size_lr
:
1239 dcursor
= dcurs_size_lr
;
1241 case ui_curs_size_uldr
:
1242 dcursor
= dcurs_size_uldr
;
1244 case ui_curs_size_urdl
:
1245 dcursor
= dcurs_size_urdl
;
1248 dcursor
= dcurs_ibeam
;
1255 /** Window decoration requested changing cursor.
1257 * @param wdecor Window decoration
1258 * @param arg Argument (window)
1259 * @param cursor Cursor to set
1261 static void wd_set_cursor(ui_wdecor_t
*wdecor
, void *arg
,
1262 ui_stock_cursor_t cursor
)
1264 ui_window_t
*window
= (ui_window_t
*) arg
;
1265 display_stock_cursor_t dcursor
;
1267 if (cursor
== window
->cursor
)
1270 dcursor
= wnd_dcursor_from_cursor(cursor
);
1272 if (window
->dwindow
!= NULL
)
1273 (void) display_window_set_cursor(window
->dwindow
, dcursor
);
1275 window
->cursor
= cursor
;
1278 /** Send window sysmenu event.
1280 * @param window Window
1281 * @parma idev_id Input device ID
1283 void ui_window_send_sysmenu(ui_window_t
*window
, sysarg_t idev_id
)
1285 if (window
->cb
!= NULL
&& window
->cb
->sysmenu
!= NULL
)
1286 window
->cb
->sysmenu(window
, window
->arg
, idev_id
);
1288 ui_window_def_sysmenu(window
, idev_id
);
1291 /** Send window minimize event.
1293 * @param window Window
1295 void ui_window_send_minimize(ui_window_t
*window
)
1297 if (window
->cb
!= NULL
&& window
->cb
->maximize
!= NULL
)
1298 window
->cb
->minimize(window
, window
->arg
);
1300 ui_window_def_minimize(window
);
1303 /** Send window maximize event.
1305 * @param window Window
1307 void ui_window_send_maximize(ui_window_t
*window
)
1309 if (window
->cb
!= NULL
&& window
->cb
->maximize
!= NULL
)
1310 window
->cb
->maximize(window
, window
->arg
);
1312 ui_window_def_maximize(window
);
1315 /** Send window unmaximize event.
1317 * @param window Window
1319 void ui_window_send_unmaximize(ui_window_t
*window
)
1321 if (window
->cb
!= NULL
&& window
->cb
->unmaximize
!= NULL
)
1322 window
->cb
->unmaximize(window
, window
->arg
);
1324 ui_window_def_unmaximize(window
);
1327 /** Send window close event.
1329 * @param window Window
1331 void ui_window_send_close(ui_window_t
*window
)
1333 if (window
->cb
!= NULL
&& window
->cb
->close
!= NULL
)
1334 window
->cb
->close(window
, window
->arg
);
1337 /** Send window focus event.
1339 * @param window Window
1340 * @param nfocus New number of foci
1342 void ui_window_send_focus(ui_window_t
*window
, unsigned nfocus
)
1344 if (window
->cb
!= NULL
&& window
->cb
->focus
!= NULL
)
1345 window
->cb
->focus(window
, window
->arg
, nfocus
);
1348 /** Send window keyboard event.
1350 * @param window Window
1352 void ui_window_send_kbd(ui_window_t
*window
, kbd_event_t
*kbd
)
1354 if (window
->cb
!= NULL
&& window
->cb
->kbd
!= NULL
)
1355 window
->cb
->kbd(window
, window
->arg
, kbd
);
1357 ui_window_def_kbd(window
, kbd
);
1360 /** Send window paint event.
1362 * @param window Window
1364 errno_t
ui_window_send_paint(ui_window_t
*window
)
1366 if (window
->cb
!= NULL
&& window
->cb
->paint
!= NULL
)
1367 return window
->cb
->paint(window
, window
->arg
);
1369 return ui_window_def_paint(window
);
1372 /** Send window position event.
1374 * @param window Window
1376 void ui_window_send_pos(ui_window_t
*window
, pos_event_t
*pos
)
1378 if (window
->cb
!= NULL
&& window
->cb
->pos
!= NULL
)
1379 window
->cb
->pos(window
, window
->arg
, pos
);
1381 ui_window_def_pos(window
, pos
);
1384 /** Send window unfocus event.
1386 * @param window Window
1387 * @param nfocus Number of remaining foci
1389 void ui_window_send_unfocus(ui_window_t
*window
, unsigned nfocus
)
1391 if (window
->cb
!= NULL
&& window
->cb
->unfocus
!= NULL
)
1392 window
->cb
->unfocus(window
, window
->arg
, nfocus
);
1394 return ui_window_def_unfocus(window
, nfocus
);
1397 /** Default window sysmenu routine.
1399 * @param window Window
1400 * @param idev_id Input device ID
1401 * @return EOK on success or an error code
1403 errno_t
ui_window_def_sysmenu(ui_window_t
*window
, sysarg_t idev_id
)
1406 ui_wdecor_geom_t geom
;
1408 if (ui_menu_is_open(window
->sysmenu
)) {
1409 ui_menu_close(window
->sysmenu
);
1411 ui_wdecor_get_geom(window
->wdecor
, &geom
);
1413 rc
= ui_menu_open(window
->sysmenu
, &geom
.title_bar_rect
,
1424 /** Default window minimize routine.
1426 * @param window Window
1427 * @return EOK on success or an error code
1429 errno_t
ui_window_def_minimize(ui_window_t
*window
)
1433 if (window
->dwindow
!= NULL
) {
1434 rc
= display_window_minimize(window
->dwindow
);
1444 /** Default window maximize routine.
1446 * @param window Window
1447 * @return EOK on success or an error code
1449 errno_t
ui_window_def_maximize(ui_window_t
*window
)
1452 gfx_rect_t old_rect
;
1455 old_rect
= window
->rect
;
1457 if (window
->dwindow
!= NULL
) {
1458 rc
= display_window_get_max_rect(window
->dwindow
, &rect
);
1462 rect
= window
->ui
->rect
;
1465 ui_wdecor_set_maximized(window
->wdecor
, true);
1466 ui_menu_entry_set_disabled(window
->sysmenu_restore
, false);
1467 ui_menu_entry_set_disabled(window
->sysmenu_maximize
, true);
1469 rc
= ui_window_size_change(window
, &rect
, ui_wsc_maximize
);
1471 ui_wdecor_set_maximized(window
->wdecor
, false);
1475 window
->normal_rect
= old_rect
;
1476 (void) ui_window_paint(window
);
1480 /** Default window unmaximize routine.
1482 * @param window Window
1483 * @return EOK on success or an error code
1485 errno_t
ui_window_def_unmaximize(ui_window_t
*window
)
1489 ui_wdecor_set_maximized(window
->wdecor
, false);
1490 ui_menu_entry_set_disabled(window
->sysmenu_restore
, true);
1491 ui_menu_entry_set_disabled(window
->sysmenu_maximize
, false);
1493 rc
= ui_window_size_change(window
, &window
->normal_rect
,
1496 ui_wdecor_set_maximized(window
->wdecor
, true);
1497 printf("ui_window_size_change->error\n");
1501 (void) ui_window_paint(window
);
1505 /** Default window keyboard event routine.
1507 * @param window Window
1508 * @return ui_claimed iff event was claimed
1510 ui_evclaim_t
ui_window_def_kbd(ui_window_t
*window
, kbd_event_t
*kbd
)
1514 if (window
->control
!= NULL
)
1515 claim
= ui_control_kbd_event(window
->control
, kbd
);
1517 claim
= ui_unclaimed
;
1519 if (claim
== ui_unclaimed
)
1520 return ui_wdecor_kbd_event(window
->wdecor
, kbd
);
1522 return ui_unclaimed
;
1525 /** Default window paint routine.
1527 * @param window Window
1528 * @return EOK on success or an error code
1530 errno_t
ui_window_def_paint(ui_window_t
*window
)
1532 gfx_rect_t app_rect
;
1535 rc
= gfx_set_color(window
->gc
, window
->res
->wnd_face_color
);
1539 ui_window_get_app_rect(window
, &app_rect
);
1541 rc
= gfx_fill_rect(window
->gc
, &app_rect
);
1545 if (window
->control
!= NULL
)
1546 return ui_control_paint(window
->control
);
1548 rc
= gfx_update(window
->res
->gc
);
1555 /** Default window position event routine.
1557 * @param window Window
1559 void ui_window_def_pos(ui_window_t
*window
, pos_event_t
*pos
)
1561 if (window
->control
!= NULL
)
1562 ui_control_pos_event(window
->control
, pos
);
1565 /** Default window unfocus routine.
1567 * @param window Window
1568 * @param nfocus Number of remaining foci
1569 * @return EOK on success or an error code
1571 void ui_window_def_unfocus(ui_window_t
*window
, unsigned nfocus
)
1573 if (window
->control
!= NULL
)
1574 ui_control_unfocus(window
->control
, nfocus
);
1577 /** Handle system menu left event.
1579 * @param sysmenu System menu
1580 * @param arg Argument (ui_window_t *)
1581 * @param idev_id Input device ID
1583 static void wnd_sysmenu_left(ui_menu_t
*sysmenu
, void *arg
, sysarg_t idev_id
)
1585 ui_window_t
*window
= (ui_window_t
*)arg
;
1587 if (window
->mbar
!= NULL
) {
1588 ui_wdecor_sysmenu_hdl_set_active(window
->wdecor
, false);
1589 ui_menu_close(sysmenu
);
1590 ui_menu_bar_select_last(window
->mbar
, true, idev_id
);
1594 /** Handle system menu right event.
1596 * @param sysmenu System menu
1597 * @param arg Argument (ui_window_t *)
1598 * @param idev_id Input device ID
1600 static void wnd_sysmenu_right(ui_menu_t
*sysmenu
, void *arg
, sysarg_t idev_id
)
1602 ui_window_t
*window
= (ui_window_t
*)arg
;
1604 if (window
->mbar
!= NULL
) {
1605 ui_wdecor_sysmenu_hdl_set_active(window
->wdecor
, false);
1606 ui_menu_close(sysmenu
);
1607 ui_menu_bar_select_first(window
->mbar
, true, idev_id
);
1611 /** Handle system menu close request event.
1613 * @param sysmenu System menu
1614 * @param arg Argument (ui_window_t *)
1615 * @param idev_id Input device ID
1617 static void wnd_sysmenu_close_req(ui_menu_t
*sysmenu
, void *arg
)
1619 ui_window_t
*window
= (ui_window_t
*)arg
;
1621 ui_wdecor_sysmenu_hdl_set_active(window
->wdecor
, false);
1622 ui_menu_close(sysmenu
);
1625 /** Handle system menu Restore entry activation.
1627 * @param mentry Menu entry
1628 * @param arg Argument (ui_window_t *)
1630 static void wnd_sysmenu_erestore(ui_menu_entry_t
*mentry
, void *arg
)
1632 ui_window_t
*window
= (ui_window_t
*)arg
;
1634 ui_window_send_unmaximize(window
);
1637 /** Handle system menu Minimize entry activation.
1639 * @param mentry Menu entry
1640 * @param arg Argument (ui_window_t *)
1642 static void wnd_sysmenu_eminimize(ui_menu_entry_t
*mentry
, void *arg
)
1644 ui_window_t
*window
= (ui_window_t
*)arg
;
1646 ui_window_send_minimize(window
);
1649 /** Handle system menu Maximize entry activation.
1651 * @param mentry Menu entry
1652 * @param arg Argument (ui_window_t *)
1654 static void wnd_sysmenu_emaximize(ui_menu_entry_t
*mentry
, void *arg
)
1656 ui_window_t
*window
= (ui_window_t
*)arg
;
1658 ui_window_send_maximize(window
);
1661 /** Handle system menu Close entry activation.
1663 * @param mentry Menu entry
1664 * @param arg Argument (ui_window_t *)
1666 static void wnd_sysmenu_eclose(ui_menu_entry_t
*mentry
, void *arg
)
1668 ui_window_t
*window
= (ui_window_t
*)arg
;
1670 ui_window_send_close(window
);
1673 /** Handle system menu press accelerator key event.
1675 * @param sysmenu System menu
1676 * @param arg Argument (ui_window_t *)
1677 * @param idev_id Input device ID
1679 static void wnd_sysmenu_press_accel(ui_menu_t
*sysmenu
, void *arg
,
1680 char32_t c
, sysarg_t idev_id
)
1688 /** Window invalidate callback
1690 * @param arg Argument (ui_window_t *)
1691 * @param rect Rectangle to update
1693 static void ui_window_invalidate(void *arg
, gfx_rect_t
*rect
)
1695 ui_window_t
*window
= (ui_window_t
*) arg
;
1698 gfx_rect_envelope(&window
->dirty_rect
, rect
, &env
);
1699 window
->dirty_rect
= env
;
1702 /** Window update callback
1704 * @param arg Argument (ui_window_t *)
1706 static void ui_window_update(void *arg
)
1708 ui_window_t
*window
= (ui_window_t
*) arg
;
1710 if (!gfx_rect_is_empty(&window
->dirty_rect
)) {
1711 (void) gfx_bitmap_render(window
->bmp
, &window
->dirty_rect
,
1715 window
->dirty_rect
.p0
.x
= 0;
1716 window
->dirty_rect
.p0
.y
= 0;
1717 window
->dirty_rect
.p1
.x
= 0;
1718 window
->dirty_rect
.p1
.y
= 0;
1721 /** Window cursor get position callback
1723 * @param arg Argument (ui_window_t *)
1724 * @param pos Place to store position
1726 static errno_t
ui_window_cursor_get_pos(void *arg
, gfx_coord2_t
*pos
)
1728 ui_window_t
*window
= (ui_window_t
*) arg
;
1732 rc
= gfx_cursor_get_pos(window
->realgc
, &cpos
);
1736 pos
->x
= cpos
.x
- window
->dpos
.x
;
1737 pos
->y
= cpos
.y
- window
->dpos
.y
;
1741 /** Window cursor set position callback
1743 * @param arg Argument (ui_window_t *)
1744 * @param pos New position
1746 static errno_t
ui_window_cursor_set_pos(void *arg
, gfx_coord2_t
*pos
)
1748 ui_window_t
*window
= (ui_window_t
*) arg
;
1751 cpos
.x
= pos
->x
+ window
->dpos
.x
;
1752 cpos
.y
= pos
->y
+ window
->dpos
.y
;
1754 return gfx_cursor_set_pos(window
->realgc
, &cpos
);
1757 /** Window cursor set visibility callback
1759 * @param arg Argument (ui_window_t *)
1760 * @param visible @c true iff cursor is to be made visible
1762 static errno_t
ui_window_cursor_set_visible(void *arg
, bool visible
)
1764 ui_window_t
*window
= (ui_window_t
*) arg
;
1766 return gfx_cursor_set_visible(window
->realgc
, visible
);
1769 /** Application area invalidate callback
1771 * @param arg Argument (ui_window_t *)
1772 * @param rect Rectangle to update
1774 static void ui_window_app_invalidate(void *arg
, gfx_rect_t
*rect
)
1776 ui_window_t
*window
= (ui_window_t
*) arg
;
1779 ui_window_get_app_rect(window
, &arect
);
1781 /* Render bitmap rectangle inside the application area */
1782 (void) gfx_bitmap_render(window
->app_bmp
, rect
, &arect
.p0
);
1784 * TODO Update applications to call gfx_update(), then
1785 * we can defer update to ui_window_app_update().
1787 (void) gfx_update(window
->res
->gc
);
1790 /** Application area update callback
1792 * @param arg Argument (ui_window_t *)
1794 static void ui_window_app_update(void *arg
)
1796 ui_window_t
*window
= (ui_window_t
*) arg
;
1799 * Not used since display is updated immediately
1800 * in ui_window_app_invalidate
1805 /** Window expose callback. */
1806 static void ui_window_expose_cb(void *arg
)
1808 ui_window_t
*window
= (ui_window_t
*) arg
;
1810 ui_window_paint(window
);