Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ui/src/window.c

    r25f26600 r8279aab  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3434 */
    3535
     36#include <congfx/console.h>
    3637#include <display.h>
    3738#include <errno.h>
    3839#include <gfx/bitmap.h>
    3940#include <gfx/context.h>
     41#include <gfx/cursor.h>
    4042#include <gfx/render.h>
    4143#include <io/kbd_event.h>
     
    4547#include <stdlib.h>
    4648#include <ui/control.h>
     49#include <ui/menubar.h>
     50#include <ui/menu.h>
     51#include <ui/menuentry.h>
    4752#include <ui/resource.h>
     53#include <ui/ui.h>
    4854#include <ui/wdecor.h>
    4955#include <ui/window.h>
     
    5662
    5763static void dwnd_close_event(void *);
    58 static void dwnd_focus_event(void *);
     64static void dwnd_focus_event(void *, unsigned);
    5965static void dwnd_kbd_event(void *, kbd_event_t *);
    6066static void dwnd_pos_event(void *, pos_event_t *);
    6167static void dwnd_resize_event(void *, gfx_rect_t *);
    62 static void dwnd_unfocus_event(void *);
     68static void dwnd_unfocus_event(void *, unsigned);
    6369
    6470static display_wnd_cb_t dwnd_cb = {
     
    7177};
    7278
     79static void wd_sysmenu_open(ui_wdecor_t *, void *, sysarg_t);
     80static void wd_sysmenu_left(ui_wdecor_t *, void *, sysarg_t);
     81static void wd_sysmenu_right(ui_wdecor_t *, void *, sysarg_t);
     82static void wd_sysmenu_accel(ui_wdecor_t *, void *, char32_t, sysarg_t);
     83static void wd_minimize(ui_wdecor_t *, void *);
     84static void wd_maximize(ui_wdecor_t *, void *);
     85static void wd_unmaximize(ui_wdecor_t *, void *);
    7386static void wd_close(ui_wdecor_t *, void *);
    74 static void wd_move(ui_wdecor_t *, void *, gfx_coord2_t *);
     87static void wd_move(ui_wdecor_t *, void *, gfx_coord2_t *, sysarg_t);
    7588static void wd_resize(ui_wdecor_t *, void *, ui_wdecor_rsztype_t,
    76     gfx_coord2_t *);
     89    gfx_coord2_t *, sysarg_t);
    7790static void wd_set_cursor(ui_wdecor_t *, void *, ui_stock_cursor_t);
    7891
    7992static 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,
    80100        .close = wd_close,
    81101        .move = wd_move,
     
    84104};
    85105
    86 static void ui_window_app_update(void *, gfx_rect_t *);
     106static void wnd_sysmenu_left(ui_menu_t *, void *, sysarg_t);
     107static void wnd_sysmenu_right(ui_menu_t *, void *, sysarg_t);
     108static void wnd_sysmenu_close_req(ui_menu_t *, void *);
     109static void wnd_sysmenu_press_accel(ui_menu_t *, void *, char32_t, sysarg_t);
     110
     111static 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
     116};
     117
     118static void wnd_sysmenu_erestore(ui_menu_entry_t *, void *);
     119static void wnd_sysmenu_eminimize(ui_menu_entry_t *, void *);
     120static void wnd_sysmenu_emaximize(ui_menu_entry_t *, void *);
     121static void wnd_sysmenu_eclose(ui_menu_entry_t *, void *);
     122
     123static void ui_window_invalidate(void *, gfx_rect_t *);
     124static void ui_window_update(void *);
     125static errno_t ui_window_cursor_get_pos(void *, gfx_coord2_t *);
     126static errno_t ui_window_cursor_set_pos(void *, gfx_coord2_t *);
     127static errno_t ui_window_cursor_set_visible(void *, bool);
     128
     129/** Window memory GC callbacks */
     130static 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
     136};
     137
     138static void ui_window_app_invalidate(void *, gfx_rect_t *);
     139static void ui_window_app_update(void *);
     140
     141/** Application area memory GC callbacks */
     142static mem_gc_cb_t ui_window_app_mem_gc_cb = {
     143        .invalidate = ui_window_app_invalidate,
     144        .update = ui_window_app_update
     145};
     146
     147static void ui_window_expose_cb(void *);
    87148
    88149/** Initialize window parameters structure.
     
    103164}
    104165
     166/** Compute where window should be placed on the screen.
     167 *
     168 * This only applies to windows that do not use default placement or
     169 * if we are running in full-screen mode.
     170 *
     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
     175 */
     176static void ui_window_place(ui_window_t *window, gfx_rect_t *drect,
     177    ui_wnd_params_t *params, gfx_coord2_t *pos)
     178{
     179        gfx_coord2_t dims;
     180        gfx_coord2_t below_pos;
     181        gfx_rect_t below_rect;
     182
     183        assert(params->placement != ui_wnd_place_default ||
     184            ui_is_fullscreen(window->ui));
     185
     186        pos->x = 0;
     187        pos->y = 0;
     188
     189        switch (params->placement) {
     190        case ui_wnd_place_default:
     191        case ui_wnd_place_center:
     192                assert(params->placement != ui_wnd_place_default ||
     193                    ui_is_fullscreen(window->ui));
     194                /* Center window */
     195                gfx_rect_dims(&params->rect, &dims);
     196                pos->x = (drect->p0.x + drect->p1.x) / 2 - dims.x / 2;
     197                pos->y = (drect->p0.y + drect->p1.y) / 2 - dims.y / 2;
     198                break;
     199        case ui_wnd_place_top_left:
     200        case ui_wnd_place_full_screen:
     201                pos->x = drect->p0.x - params->rect.p0.x;
     202                pos->y = drect->p0.y - params->rect.p0.y;
     203                break;
     204        case ui_wnd_place_top_right:
     205                pos->x = drect->p1.x - params->rect.p1.x;
     206                pos->y = drect->p0.y - params->rect.p0.y;
     207                break;
     208        case ui_wnd_place_bottom_left:
     209                pos->x = drect->p0.x - params->rect.p0.x;
     210                pos->y = drect->p1.y - params->rect.p1.y;
     211                break;
     212        case ui_wnd_place_bottom_right:
     213                pos->x = drect->p1.x - params->rect.p1.x;
     214                pos->y = drect->p1.y - params->rect.p1.y;
     215                break;
     216        case ui_wnd_place_popup:
     217                /* Compute rectangle when placed below */
     218                below_pos.x = params->prect.p0.x;
     219                below_pos.y = params->prect.p1.y;
     220                gfx_rect_translate(&below_pos, &params->rect, &below_rect);
     221
     222                /* Does below_rect fit within the display? */
     223                if (gfx_rect_is_inside(&below_rect, drect)) {
     224                        /* Place popup window below parent rectangle */
     225                        pos->x = params->prect.p0.x - params->rect.p0.x;
     226                        pos->y = params->prect.p1.y - params->rect.p0.y;
     227                } else {
     228                        /* Place popup window above parent rectangle */
     229                        pos->x = params->prect.p0.x;
     230                        pos->y = params->prect.p0.y -
     231                            (params->rect.p1.y - params->rect.p0.y);
     232                }
     233                break;
     234        }
     235}
     236
     237/** Create window's system menu.
     238 *
     239 * @param window Window
     240 * @return EOK on success or an error code
     241 */
     242static errno_t ui_window_sysmenu_create(ui_window_t *window)
     243{
     244        errno_t rc;
     245        ui_menu_entry_t *mrestore;
     246        ui_menu_entry_t *mmin;
     247        ui_menu_entry_t *mmax;
     248        ui_menu_entry_t *msep;
     249        ui_menu_entry_t *mclose;
     250
     251        rc = ui_menu_create(window, &window->sysmenu);
     252        if (rc != EOK)
     253                goto error;
     254
     255        ui_menu_set_cb(window->sysmenu, &wnd_sysmenu_cb, (void *)window);
     256
     257        rc = ui_menu_entry_create(window->sysmenu, "~R~estore",
     258            "", &mrestore);
     259        if (rc != EOK)
     260                goto error;
     261
     262        if (!window->wdecor->maximized)
     263                ui_menu_entry_set_disabled(mrestore, true);
     264
     265        ui_menu_entry_set_cb(mrestore, wnd_sysmenu_erestore, (void *)window);
     266
     267        rc = ui_menu_entry_create(window->sysmenu, "Mi~n~imize",
     268            "", &mmin);
     269        if (rc != EOK)
     270                goto error;
     271
     272        if ((window->wdecor->style & ui_wds_minimize_btn) == 0)
     273                ui_menu_entry_set_disabled(mmin, true);
     274
     275        ui_menu_entry_set_cb(mmin, wnd_sysmenu_eminimize, (void *)window);
     276
     277        rc = ui_menu_entry_create(window->sysmenu, "Ma~x~imize",
     278            "", &mmax);
     279        if (rc != EOK)
     280                goto error;
     281
     282        if ((window->wdecor->style & ui_wds_maximize_btn) == 0 ||
     283            window->wdecor->maximized)
     284                ui_menu_entry_set_disabled(mmax, true);
     285
     286        ui_menu_entry_set_cb(mmax, wnd_sysmenu_emaximize, (void *)window);
     287
     288        rc = ui_menu_entry_sep_create(window->sysmenu, &msep);
     289        if (rc != EOK)
     290                goto error;
     291
     292        rc = ui_menu_entry_create(window->sysmenu, "~C~lose", "Alt-F4",
     293            &mclose);
     294        if (rc != EOK)
     295                goto error;
     296
     297        if ((window->wdecor->style & ui_wds_close_btn) == 0)
     298                ui_menu_entry_set_disabled(mclose, true);
     299
     300        ui_menu_entry_set_cb(mclose, wnd_sysmenu_eclose, (void *)window);
     301
     302        window->sysmenu_restore = mrestore;
     303        window->sysmenu_minimize = mmin;
     304        window->sysmenu_maximize = mmax;
     305
     306        return EOK;
     307error:
     308        return rc;
     309}
     310
    105311/** Create new window.
    106312 *
     
    114320{
    115321        ui_window_t *window;
     322        ui_window_t *pwindow = NULL;
    116323        display_info_t info;
    117         gfx_coord2_t pos;
    118324        gfx_coord2_t scr_dims;
    119325        display_wnd_params_t dparams;
    120         display_window_t *dwindow = NULL;
    121326        gfx_context_t *gc = NULL;
    122327        ui_resource_t *res = NULL;
    123328        ui_wdecor_t *wdecor = NULL;
    124329        dummy_gc_t *dgc = NULL;
     330        gfx_bitmap_params_t bparams;
     331        gfx_bitmap_alloc_t alloc;
     332        gfx_bitmap_t *bmp = NULL;
     333        gfx_coord2_t off;
     334        mem_gc_t *memgc = NULL;
     335        xlate_gc_t *xgc = NULL;
    125336        errno_t rc;
    126337
     
    129340                return ENOMEM;
    130341
     342        window->ui = ui;
     343
    131344        display_wnd_params_init(&dparams);
    132345        dparams.rect = params->rect;
    133         /* Only allow making the window larger */
    134         gfx_rect_dims(&params->rect, &dparams.min_size);
     346        dparams.caption = params->caption;
     347        dparams.min_size = params->min_size;
     348
     349        /*
     350         * If idev_id is not specified, use the UI default (probably
     351         * obtained from display specification. This creates the
     352         * main window in the seat specified on the command line.
     353         */
     354        if (params->idev_id != 0)
     355                dparams.idev_id = params->idev_id;
     356        else
     357                dparams.idev_id = ui->idev_id;
     358
     359        if ((params->flags & ui_wndf_popup) != 0)
     360                dparams.flags |= wndf_popup;
     361        if ((params->flags & ui_wndf_nofocus) != 0)
     362                dparams.flags |= wndf_nofocus;
     363        if ((params->flags & ui_wndf_topmost) != 0)
     364                dparams.flags |= wndf_topmost;
     365        if ((params->flags & ui_wndf_system) != 0)
     366                dparams.flags |= wndf_system;
     367        if ((params->flags & ui_wndf_avoid) != 0)
     368                dparams.flags |= wndf_avoid;
    135369
    136370        if (ui->display != NULL) {
     
    148382                }
    149383
     384                if (params->placement != ui_wnd_place_default) {
     385                        /* Set initial display window position */
     386                        ui_window_place(window, &info.rect, params,
     387                            &dparams.pos);
     388
     389                        dparams.flags |= wndf_setpos;
     390                }
     391
    150392                rc = display_window_create(ui->display, &dparams, &dwnd_cb,
    151                     (void *) window, &dwindow);
     393                    (void *) window, &window->dwindow);
    152394                if (rc != EOK)
    153395                        goto error;
    154396
    155                 if (params->placement != ui_wnd_place_default) {
    156                         pos.x = 0;
    157                         pos.y = 0;
    158 
    159                         switch (params->placement) {
    160                         case ui_wnd_place_default:
    161                                 assert(false);
    162                         case ui_wnd_place_top_left:
    163                         case ui_wnd_place_full_screen:
    164                                 pos.x = info.rect.p0.x - params->rect.p0.x;
    165                                 pos.y = info.rect.p0.y - params->rect.p0.y;
    166                                 break;
    167                         case ui_wnd_place_top_right:
    168                                 pos.x = info.rect.p1.x - params->rect.p1.x;
    169                                 pos.y = info.rect.p0.y - params->rect.p0.y;
    170                                 break;
    171                         case ui_wnd_place_bottom_left:
    172                                 pos.x = info.rect.p0.x - params->rect.p0.x;
    173                                 pos.y = info.rect.p1.y - params->rect.p1.y;
    174                                 break;
    175                         case ui_wnd_place_bottom_right:
    176                                 pos.x = info.rect.p1.x - params->rect.p1.x;
    177                                 pos.y = info.rect.p1.y - params->rect.p1.y;
    178                                 break;
    179                         }
    180 
    181                         rc = display_window_move(dwindow, &pos);
    182                         if (rc != EOK)
    183                                 goto error;
    184                 }
    185 
    186                 rc = display_window_get_gc(dwindow, &gc);
     397                rc = display_window_get_gc(window->dwindow, &gc);
    187398                if (rc != EOK)
    188399                        goto error;
     400        } else if (ui->console != NULL) {
     401                gc = console_gc_get_ctx(ui->cgc);
     402
     403                if (params->placement == ui_wnd_place_full_screen) {
     404                        /* Make window the size of the screen */
     405                        gfx_rect_dims(&ui->rect, &scr_dims);
     406                        gfx_coord2_add(&dparams.rect.p0, &scr_dims,
     407                            &dparams.rect.p1);
     408                        (void) console_set_caption(ui->console,
     409                            params->caption);
     410                }
    189411        } else {
    190412                /* Needed for unit tests */
     
    196418        }
    197419
    198         rc = ui_resource_create(gc, &res);
     420#ifdef CONFIG_UI_CS_RENDER
     421        /* Create window bitmap */
     422        gfx_bitmap_params_init(&bparams);
     423#ifndef CONFIG_WIN_DOUBLE_BUF
     424        /* Console does not support direct output */
     425        if (ui->display != NULL)
     426                bparams.flags |= bmpf_direct_output;
     427#endif
     428
     429        /* Move rectangle so that top-left corner is 0,0 */
     430        gfx_rect_rtranslate(&dparams.rect.p0, &dparams.rect, &bparams.rect);
     431
     432        rc = gfx_bitmap_create(gc, &bparams, NULL, &bmp);
     433        if (rc != EOK)
     434                goto error;
     435
     436        /* Create memory GC */
     437        rc = gfx_bitmap_get_alloc(bmp, &alloc);
     438        if (rc != EOK) {
     439                gfx_bitmap_destroy(window->app_bmp);
     440                return rc;
     441        }
     442
     443        rc = mem_gc_create(&bparams.rect, &alloc, &ui_window_mem_gc_cb,
     444            (void *) window, &memgc);
     445        if (rc != EOK) {
     446                gfx_bitmap_destroy(window->app_bmp);
     447                return rc;
     448        }
     449
     450        window->bmp = bmp;
     451        window->mgc = memgc;
     452        window->gc = mem_gc_get_ctx(memgc);
     453        window->realgc = gc;
     454        (void) off;
     455#else
     456        /* Server-side rendering */
     457
     458        /* Full-screen mode? */
     459        if (ui->display == NULL) {
     460                /* Create translating GC to translate window contents */
     461                off.x = 0;
     462                off.y = 0;
     463                rc = xlate_gc_create(&off, gc, &xgc);
     464                if (rc != EOK)
     465                        goto error;
     466
     467                window->xgc = xgc;
     468                window->gc = xlate_gc_get_ctx(xgc);
     469                window->realgc = gc;
     470        } else {
     471                window->gc = gc;
     472        }
     473
     474        (void) ui_window_mem_gc_cb;
     475        (void) alloc;
     476        (void) bparams;
     477#endif
     478        if (ui->display == NULL) {
     479                ui_window_place(window, &ui->rect, params, &window->dpos);
     480
     481                if (window->xgc != NULL)
     482                        xlate_gc_set_off(window->xgc, &window->dpos);
     483        }
     484
     485        rc = ui_resource_create(window->gc, ui_is_textmode(ui), &res);
    199486        if (rc != EOK)
    200487                goto error;
     
    208495        ui_wdecor_paint(wdecor);
    209496
    210         window->ui = ui;
    211         window->dwindow = dwindow;
     497        ui_resource_set_expose_cb(res, ui_window_expose_cb, (void *) window);
     498
    212499        window->rect = dparams.rect;
    213         window->gc = gc;
    214500        window->res = res;
    215501        window->wdecor = wdecor;
    216502        window->cursor = ui_curs_arrow;
     503        window->placement = params->placement;
     504
     505        rc = ui_window_sysmenu_create(window);
     506        if (rc != EOK)
     507                goto error;
     508
    217509        *rwindow = window;
     510
     511        if (ui_is_fullscreen(ui))
     512                pwindow = ui_window_get_active(ui);
     513
     514        list_append(&window->lwindows, &ui->windows);
     515
     516        if (ui_is_fullscreen(ui)) {
     517                /* Send unfocus event to previously active window */
     518                if (pwindow != NULL)
     519                        ui_window_send_unfocus(pwindow, 0);
     520        }
     521
    218522        return EOK;
    219523error:
     
    222526        if (res != NULL)
    223527                ui_resource_destroy(res);
     528        if (memgc != NULL)
     529                mem_gc_delete(memgc);
     530        if (xgc != NULL)
     531                xlate_gc_delete(xgc);
     532        if (bmp != NULL)
     533                gfx_bitmap_destroy(bmp);
    224534        if (dgc != NULL)
    225535                dummygc_destroy(dgc);
    226         if (dwindow != NULL)
    227                 display_window_destroy(dwindow);
    228536        free(window);
    229537        return rc;
     
    236544void ui_window_destroy(ui_window_t *window)
    237545{
     546        ui_t *ui;
     547        ui_window_t *nwindow;
     548
    238549        if (window == NULL)
    239550                return;
    240551
     552        ui = window->ui;
     553
     554        list_remove(&window->lwindows);
    241555        ui_control_destroy(window->control);
     556        ui_menu_destroy(window->sysmenu);
    242557        ui_wdecor_destroy(window->wdecor);
    243558        ui_resource_destroy(window->res);
    244         gfx_context_delete(window->gc);
    245         display_window_destroy(window->dwindow);
     559        if (window->app_mgc != NULL)
     560                mem_gc_delete(window->app_mgc);
     561        if (window->app_bmp != NULL)
     562                gfx_bitmap_destroy(window->app_bmp);
     563        if (window->mgc != NULL) {
     564                mem_gc_delete(window->mgc);
     565                window->gc = NULL;
     566        }
     567        if (window->bmp != NULL)
     568                gfx_bitmap_destroy(window->bmp);
     569        if (window->dwindow != NULL)
     570                display_window_destroy(window->dwindow);
     571
     572        /* Need to repaint if windows are emulated */
     573        if (ui_is_fullscreen(ui)) {
     574                ui_paint(ui);
     575                /* Send focus event to newly active window */
     576                nwindow = ui_window_get_active(ui);
     577                if (nwindow != NULL)
     578                        ui_window_send_focus(nwindow, 0);
     579        }
     580
     581        if (ui->console != NULL &&
     582            window->placement == ui_wnd_place_full_screen) {
     583                (void) console_set_caption(ui->console, "");
     584        }
     585
    246586        free(window);
    247587}
     
    252592 * is added, the results are undefined.
    253593 *
    254  * @param fixed Fixed layout
     594 * @param window Window
    255595 * @param control Control
    256  * @return EOK on success, ENOMEM if out of memory
    257596 */
    258597void ui_window_add(ui_window_t *window, ui_control_t *control)
     
    278617}
    279618
    280 /** Resize/move window.
    281  *
    282  * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
    283  * the top-left corner of the window will move on the screen accordingly.
     619/** Get active window (only valid in fullscreen mode).
     620 *
     621 * @param ui User interface
     622 * @return Active window
     623 */
     624ui_window_t *ui_window_get_active(ui_t *ui)
     625{
     626        link_t *link;
     627
     628        link = list_last(&ui->windows);
     629        if (link == NULL)
     630                return NULL;
     631
     632        return list_get_instance(link, ui_window_t, lwindows);
     633}
     634
     635/** Resize or (un)maximize window.
    284636 *
    285637 * @param window Window
    286638 * @param rect Rectangle
     639 * @param scop Size change operation
    287640 *
    288641 * @return EOK on success or an error code
    289642 */
    290 errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
     643errno_t ui_window_size_change(ui_window_t *window, gfx_rect_t *rect,
     644    ui_wnd_sc_op_t scop)
    291645{
    292646        gfx_coord2_t offs;
     
    294648        gfx_rect_t arect;
    295649        gfx_bitmap_t *app_bmp = NULL;
    296         gfx_bitmap_params_t params;
    297         gfx_bitmap_alloc_t alloc;
     650        gfx_bitmap_t *win_bmp = NULL;
     651        gfx_bitmap_params_t app_params;
     652        gfx_bitmap_params_t win_params;
     653        gfx_bitmap_alloc_t app_alloc;
     654        gfx_bitmap_alloc_t win_alloc;
    298655        errno_t rc;
    299656
     
    305662        gfx_rect_rtranslate(&offs, rect, &nrect);
    306663
     664        /* mgc != NULL iff client-side rendering */
     665        if (window->mgc != NULL) {
     666#ifdef CONFIG_WIN_DOUBLE_BUF
     667                /*
     668                 * Create new window bitmap in advance. If direct mapping,
     669                 * will need do it after resizing the window.
     670                 */
     671                assert(window->bmp != NULL);
     672                gfx_bitmap_params_init(&win_params);
     673                win_params.rect = nrect;
     674
     675                rc = gfx_bitmap_create(window->realgc, &win_params, NULL,
     676                    &win_bmp);
     677                if (rc != EOK)
     678                        goto error;
     679
     680                rc = gfx_bitmap_get_alloc(win_bmp, &win_alloc);
     681                if (rc != EOK)
     682                        goto error;
     683#endif
     684        }
     685
     686        /* Application area GC? */
    307687        if (window->app_gc != NULL) {
     688                /* Resize application bitmap */
    308689                assert(window->app_bmp != NULL);
    309690
    310                 gfx_bitmap_params_init(&params);
     691                gfx_bitmap_params_init(&app_params);
    311692
    312693                /*
     
    315696                 */
    316697                ui_wdecor_app_from_rect(window->wdecor->style, &nrect, &arect);
    317                 gfx_rect_rtranslate(&arect.p0, &arect, &params.rect);
    318 
    319                 rc = gfx_bitmap_create(window->gc, &params, NULL,
     698                gfx_rect_rtranslate(&arect.p0, &arect, &app_params.rect);
     699
     700                rc = gfx_bitmap_create(window->gc, &app_params, NULL,
    320701                    &app_bmp);
    321702                if (rc != EOK)
    322703                        goto error;
    323704
    324                 rc = gfx_bitmap_get_alloc(app_bmp, &alloc);
     705                rc = gfx_bitmap_get_alloc(app_bmp, &app_alloc);
    325706                if (rc != EOK)
    326707                        goto error;
    327708        }
    328709
    329         /* dwindow can be NULL in case of unit tests */
     710        /* dwindow can be NULL in case of unit tests or fullscreen mode */
    330711        if (window->dwindow != NULL) {
    331                 rc = display_window_resize(window->dwindow, &offs, &nrect);
     712                switch (scop) {
     713                case ui_wsc_resize:
     714                        rc = display_window_resize(window->dwindow, &offs,
     715                            &nrect);
     716                        if (rc != EOK)
     717                                goto error;
     718                        break;
     719                case ui_wsc_maximize:
     720                        rc = display_window_maximize(window->dwindow);
     721                        if (rc != EOK)
     722                                goto error;
     723                        break;
     724                case ui_wsc_unmaximize:
     725                        rc = display_window_unmaximize(window->dwindow);
     726                        if (rc != EOK)
     727                                goto error;
     728                        break;
     729                }
     730        }
     731
     732        /* Client side rendering? */
     733        if (window->mgc != NULL) {
     734#ifndef CONFIG_WIN_DOUBLE_BUF
     735                /* Window is resized, now we can map the window bitmap again */
     736                gfx_bitmap_params_init(&win_params);
     737                win_params.flags |= bmpf_direct_output;
     738                win_params.rect = nrect;
     739
     740                rc = gfx_bitmap_create(window->realgc, &win_params, NULL,
     741                    &win_bmp);
    332742                if (rc != EOK)
    333743                        goto error;
    334         }
    335 
     744
     745                rc = gfx_bitmap_get_alloc(win_bmp, &win_alloc);
     746                if (rc != EOK)
     747                        goto error;
     748#endif
     749                mem_gc_retarget(window->mgc, &win_params.rect, &win_alloc);
     750
     751                gfx_bitmap_destroy(window->bmp);
     752                window->bmp = win_bmp;
     753        }
     754
     755        window->rect = nrect;
    336756        ui_wdecor_set_rect(window->wdecor, &nrect);
    337757        ui_wdecor_paint(window->wdecor);
    338 
     758        gfx_update(window->gc);
     759
     760        /* Application area GC? */
    339761        if (window->app_gc != NULL) {
    340                 mem_gc_retarget(window->app_mgc, &params.rect, &alloc);
     762                mem_gc_retarget(window->app_mgc, &app_params.rect, &app_alloc);
    341763
    342764                gfx_bitmap_destroy(window->app_bmp);
     
    348770        if (app_bmp != NULL)
    349771                gfx_bitmap_destroy(app_bmp);
     772        if (win_bmp != NULL)
     773                gfx_bitmap_destroy(win_bmp);
    350774        return rc;
    351775}
    352776
     777/** Resize/move window.
     778 *
     779 * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
     780 * the top-left corner of the window will move on the screen accordingly.
     781 *
     782 * @param window Window
     783 * @param rect Rectangle
     784 *
     785 * @return EOK on success or an error code
     786 */
     787errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
     788{
     789        return ui_window_size_change(window, rect, ui_wsc_resize);
     790}
     791
    353792/** Set window callbacks.
    354793 *
    355794 * @param window Window
    356  * @param cb Window decoration callbacks
     795 * @param cb Window callbacks
    357796 * @param arg Callback argument
    358797 */
     
    363802}
    364803
     804/** Change window caption.
     805 *
     806 * @param window Window
     807 * @param caption New caption
     808 *
     809 * @return EOK on success or an error code
     810 */
     811errno_t ui_window_set_caption(ui_window_t *window, const char *caption)
     812{
     813        errno_t rc;
     814
     815        /* Set console caption if fullscreen window on console */
     816        if (window->ui->console != NULL && window->placement ==
     817            ui_wnd_place_full_screen) {
     818                rc = console_set_caption(window->ui->console, caption);
     819                if (rc != EOK)
     820                        return rc;
     821        }
     822
     823        /* Set display window caption if running on display service */
     824        if (window->dwindow != NULL) {
     825                rc = display_window_set_caption(window->dwindow, caption);
     826                if (rc != EOK)
     827                        return rc;
     828        }
     829
     830        return ui_wdecor_set_caption(window->wdecor, caption);
     831}
     832
     833/** Get window's containing UI.
     834 *
     835 * @param window Window
     836 * @return Containing UI
     837 */
     838ui_t *ui_window_get_ui(ui_window_t *window)
     839{
     840        return window->ui;
     841}
     842
    365843/** Get UI resource from window.
    366844 *
     
    381859{
    382860        return window->gc;
     861}
     862
     863/** Get window position.
     864 *
     865 * @param window Window
     866 * @param pos Place to store position
     867 * @return EOK on success or an error code
     868 */
     869errno_t ui_window_get_pos(ui_window_t *window, gfx_coord2_t *pos)
     870{
     871        errno_t rc;
     872
     873        if (window->dwindow != NULL) {
     874                rc = display_window_get_pos(window->dwindow, pos);
     875                if (rc != EOK)
     876                        return rc;
     877        } else {
     878                *pos = window->dpos;
     879        }
     880
     881        return EOK;
    383882}
    384883
     
    420919                }
    421920
    422                 rc = mem_gc_create(&params.rect, &alloc, ui_window_app_update,
    423                     (void *) window, &memgc);
     921                rc = mem_gc_create(&params.rect, &alloc,
     922                    &ui_window_app_mem_gc_cb, (void *) window, &memgc);
    424923                if (rc != EOK) {
    425924                        gfx_bitmap_destroy(window->app_bmp);
     
    448947}
    449948
     949/** Set cursor when pointer is hovering over a control.
     950 *
     951 * @param window Window
     952 * @param cursor Cursor
     953 */
     954void ui_window_set_ctl_cursor(ui_window_t *window, ui_stock_cursor_t cursor)
     955{
     956        display_stock_cursor_t dcursor;
     957
     958        dcursor = wnd_dcursor_from_cursor(cursor);
     959
     960        if (window->dwindow != NULL)
     961                (void) display_window_set_cursor(window->dwindow, dcursor);
     962}
     963
    450964/** Paint window
    451965 *
     
    462976{
    463977        ui_window_t *window = (ui_window_t *) arg;
    464 
     978        ui_t *ui = window->ui;
     979
     980        fibril_mutex_lock(&ui->lock);
    465981        ui_window_send_close(window);
     982        fibril_mutex_unlock(&ui->lock);
    466983}
    467984
    468985/** Handle window focus event. */
    469 static void dwnd_focus_event(void *arg)
    470 {
    471         ui_window_t *window = (ui_window_t *) arg;
     986static void dwnd_focus_event(void *arg, unsigned nfocus)
     987{
     988        ui_window_t *window = (ui_window_t *) arg;
     989        ui_t *ui = window->ui;
     990
     991        fibril_mutex_lock(&ui->lock);
     992        (void)nfocus;
    472993
    473994        if (window->wdecor != NULL) {
     
    476997        }
    477998
    478         ui_window_send_focus(window);
     999        ui_window_send_focus(window, nfocus);
     1000        fibril_mutex_unlock(&ui->lock);
    4791001}
    4801002
     
    4831005{
    4841006        ui_window_t *window = (ui_window_t *) arg;
    485 
    486         (void) window;
     1007        ui_t *ui = window->ui;
     1008
     1009        fibril_mutex_lock(&ui->lock);
    4871010        ui_window_send_kbd(window, kbd_event);
     1011        fibril_mutex_unlock(&ui->lock);
    4881012}
    4891013
     
    4921016{
    4931017        ui_window_t *window = (ui_window_t *) arg;
     1018        ui_t *ui = window->ui;
     1019        ui_evclaim_t claim;
    4941020
    4951021        /* Make sure we don't process events until fully initialized */
     
    4971023                return;
    4981024
    499         ui_wdecor_pos_event(window->wdecor, event);
     1025        fibril_mutex_lock(&ui->lock);
     1026
     1027        claim = ui_wdecor_pos_event(window->wdecor, event);
     1028        if (claim == ui_claimed) {
     1029                fibril_mutex_unlock(&ui->lock);
     1030                return;
     1031        }
     1032
    5001033        ui_window_send_pos(window, event);
     1034        fibril_mutex_unlock(&ui->lock);
    5011035}
    5021036
     
    5051039{
    5061040        ui_window_t *window = (ui_window_t *) arg;
     1041        ui_t *ui = window->ui;
    5071042
    5081043        /* Make sure we don't process events until fully initialized */
     
    5131048                return;
    5141049
     1050        fibril_mutex_lock(&ui->lock);
    5151051        (void) ui_window_resize(window, rect);
    516         (void) ui_window_paint(window);
     1052        ui_window_send_resize(window);
     1053        fibril_mutex_unlock(&ui->lock);
    5171054}
    5181055
    5191056/** Handle window unfocus event. */
    520 static void dwnd_unfocus_event(void *arg)
    521 {
    522         ui_window_t *window = (ui_window_t *) arg;
    523 
    524         if (window->wdecor != NULL) {
     1057static void dwnd_unfocus_event(void *arg, unsigned nfocus)
     1058{
     1059        ui_window_t *window = (ui_window_t *) arg;
     1060        ui_t *ui = window->ui;
     1061
     1062        fibril_mutex_lock(&ui->lock);
     1063
     1064        if (window->wdecor != NULL && nfocus == 0) {
    5251065                ui_wdecor_set_active(window->wdecor, false);
    5261066                ui_wdecor_paint(window->wdecor);
    5271067        }
    5281068
    529         ui_window_send_unfocus(window);
     1069        ui_window_send_unfocus(window, nfocus);
     1070        fibril_mutex_unlock(&ui->lock);
     1071}
     1072
     1073/** Window decoration requested opening of system menu.
     1074 *
     1075 * @param wdecor Window decoration
     1076 * @param arg Argument (window)
     1077 * @param idev_id Input device ID
     1078 */
     1079static void wd_sysmenu_open(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1080{
     1081        ui_window_t *window = (ui_window_t *) arg;
     1082
     1083        ui_window_send_sysmenu(window, idev_id);
     1084}
     1085
     1086/** Window decoration requested moving left from system menu handle.
     1087 *
     1088 * @param wdecor Window decoration
     1089 * @param arg Argument (window)
     1090 * @param idev_id Input device ID
     1091 */
     1092static void wd_sysmenu_left(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1093{
     1094        ui_window_t *window = (ui_window_t *) arg;
     1095
     1096        if (window->mbar != NULL) {
     1097                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1098                ui_menu_close(window->sysmenu);
     1099                ui_menu_bar_select_last(window->mbar, false, idev_id);
     1100        }
     1101}
     1102
     1103/** Window decoration requested moving right from system menu handle.
     1104 *
     1105 * @param wdecor Window decoration
     1106 * @param arg Argument (window)
     1107 * @param idev_id Input device ID
     1108 */
     1109static void wd_sysmenu_right(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1110{
     1111        ui_window_t *window = (ui_window_t *) arg;
     1112
     1113        if (window->mbar != NULL) {
     1114                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1115                ui_menu_close(window->sysmenu);
     1116                ui_menu_bar_select_first(window->mbar, false, idev_id);
     1117        }
     1118}
     1119
     1120/** Window decoration detected accelerator press from system menu handle.
     1121 *
     1122 * @param wdecor Window decoration
     1123 * @param arg Argument (window)
     1124 * @param c Accelerator key
     1125 * @param idev_id Input device ID
     1126 */
     1127static void wd_sysmenu_accel(ui_wdecor_t *wdecor, void *arg, char32_t c,
     1128    sysarg_t idev_id)
     1129{
     1130        ui_window_t *window = (ui_window_t *) arg;
     1131
     1132        if (window->mbar != NULL) {
     1133                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1134                ui_menu_close(window->sysmenu);
     1135                ui_menu_bar_press_accel(window->mbar, c, idev_id);
     1136        }
     1137}
     1138
     1139/** Window decoration requested window minimization.
     1140 *
     1141 * @param wdecor Window decoration
     1142 * @param arg Argument (window)
     1143 */
     1144static void wd_minimize(ui_wdecor_t *wdecor, void *arg)
     1145{
     1146        ui_window_t *window = (ui_window_t *) arg;
     1147
     1148        ui_window_send_minimize(window);
     1149}
     1150
     1151/** Window decoration requested window maximization.
     1152 *
     1153 * @param wdecor Window decoration
     1154 * @param arg Argument (window)
     1155 */
     1156static void wd_maximize(ui_wdecor_t *wdecor, void *arg)
     1157{
     1158        ui_window_t *window = (ui_window_t *) arg;
     1159
     1160        ui_window_send_maximize(window);
     1161}
     1162
     1163/** Window decoration requested window unmaximization.
     1164 *
     1165 * @param wdecor Window decoration
     1166 * @param arg Argument (window)
     1167 */
     1168static void wd_unmaximize(ui_wdecor_t *wdecor, void *arg)
     1169{
     1170        ui_window_t *window = (ui_window_t *) arg;
     1171
     1172        ui_window_send_unmaximize(window);
    5301173}
    5311174
     
    5471190 * @param arg Argument (window)
    5481191 * @param pos Position where the title bar was pressed
    549  */
    550 static void wd_move(ui_wdecor_t *wdecor, void *arg, gfx_coord2_t *pos)
    551 {
    552         ui_window_t *window = (ui_window_t *) arg;
    553 
    554         (void) display_window_move_req(window->dwindow, pos);
     1192 * @param pos_id Positioning device ID
     1193 */
     1194static void wd_move(ui_wdecor_t *wdecor, void *arg, gfx_coord2_t *pos,
     1195    sysarg_t pos_id)
     1196{
     1197        ui_window_t *window = (ui_window_t *) arg;
     1198
     1199        if (window->dwindow != NULL)
     1200                (void) display_window_move_req(window->dwindow, pos, pos_id);
    5551201}
    5561202
     
    5611207 * @param rsztype Resize type
    5621208 * @param pos Position where the button was pressed
     1209 * @param pos_id Positioning device ID
    5631210 */
    5641211static void wd_resize(ui_wdecor_t *wdecor, void *arg,
    565     ui_wdecor_rsztype_t rsztype, gfx_coord2_t *pos)
    566 {
    567         ui_window_t *window = (ui_window_t *) arg;
    568 
    569         (void) display_window_resize_req(window->dwindow, rsztype, pos);
    570 }
    571 
    572 /** Window decoration requested changing cursor.
    573  *
    574  * @param wdecor Window decoration
    575  * @param arg Argument (window)
    576  * @param cursor Cursor to set
    577  */
    578 static void wd_set_cursor(ui_wdecor_t *wdecor, void *arg,
    579     ui_stock_cursor_t cursor)
    580 {
    581         ui_window_t *window = (ui_window_t *) arg;
     1212    ui_wdecor_rsztype_t rsztype, gfx_coord2_t *pos, sysarg_t pos_id)
     1213{
     1214        ui_window_t *window = (ui_window_t *) arg;
     1215
     1216        if (window->dwindow != NULL) {
     1217                (void) display_window_resize_req(window->dwindow,
     1218                    (display_wnd_rsztype_t) rsztype, // Same constants in the enums
     1219                    pos, pos_id);
     1220        }
     1221}
     1222
     1223/** Get display stock cursor from UI stock cursor.
     1224 *
     1225 * @param cursor UI stock cursor
     1226 * @return Display stock cursor
     1227 */
     1228display_stock_cursor_t wnd_dcursor_from_cursor(ui_stock_cursor_t cursor)
     1229{
    5821230        display_stock_cursor_t dcursor;
    583 
    584         if (cursor == window->cursor)
    585                 return;
    5861231
    5871232        dcursor = dcurs_arrow;
     
    6031248                dcursor = dcurs_size_urdl;
    6041249                break;
    605         }
    606 
    607         (void) display_window_set_cursor(window->dwindow, dcursor);
     1250        case ui_curs_ibeam:
     1251                dcursor = dcurs_ibeam;
     1252                break;
     1253        }
     1254
     1255        return dcursor;
     1256}
     1257
     1258/** Window decoration requested changing cursor.
     1259 *
     1260 * @param wdecor Window decoration
     1261 * @param arg Argument (window)
     1262 * @param cursor Cursor to set
     1263 */
     1264static void wd_set_cursor(ui_wdecor_t *wdecor, void *arg,
     1265    ui_stock_cursor_t cursor)
     1266{
     1267        ui_window_t *window = (ui_window_t *) arg;
     1268        display_stock_cursor_t dcursor;
     1269
     1270        if (cursor == window->cursor)
     1271                return;
     1272
     1273        dcursor = wnd_dcursor_from_cursor(cursor);
     1274
     1275        if (window->dwindow != NULL)
     1276                (void) display_window_set_cursor(window->dwindow, dcursor);
     1277
    6081278        window->cursor = cursor;
     1279}
     1280
     1281/** Send window sysmenu event.
     1282 *
     1283 * @param window Window
     1284 * @parma idev_id Input device ID
     1285 */
     1286void ui_window_send_sysmenu(ui_window_t *window, sysarg_t idev_id)
     1287{
     1288        if (window->cb != NULL && window->cb->sysmenu != NULL)
     1289                window->cb->sysmenu(window, window->arg, idev_id);
     1290        else
     1291                ui_window_def_sysmenu(window, idev_id);
     1292}
     1293
     1294/** Send window minimize event.
     1295 *
     1296 * @param window Window
     1297 */
     1298void ui_window_send_minimize(ui_window_t *window)
     1299{
     1300        if (window->cb != NULL && window->cb->minimize != NULL)
     1301                window->cb->minimize(window, window->arg);
     1302        else
     1303                ui_window_def_minimize(window);
     1304}
     1305
     1306/** Send window maximize event.
     1307 *
     1308 * @param window Window
     1309 */
     1310void ui_window_send_maximize(ui_window_t *window)
     1311{
     1312        if (window->cb != NULL && window->cb->maximize != NULL)
     1313                window->cb->maximize(window, window->arg);
     1314        else
     1315                ui_window_def_maximize(window);
     1316}
     1317
     1318/** Send window unmaximize event.
     1319 *
     1320 * @param window Window
     1321 */
     1322void ui_window_send_unmaximize(ui_window_t *window)
     1323{
     1324        if (window->cb != NULL && window->cb->unmaximize != NULL)
     1325                window->cb->unmaximize(window, window->arg);
     1326        else
     1327                ui_window_def_unmaximize(window);
    6091328}
    6101329
     
    6221341 *
    6231342 * @param window Window
    624  */
    625 void ui_window_send_focus(ui_window_t *window)
     1343 * @param nfocus New number of foci
     1344 */
     1345void ui_window_send_focus(ui_window_t *window, unsigned nfocus)
    6261346{
    6271347        if (window->cb != NULL && window->cb->focus != NULL)
    628                 window->cb->focus(window, window->arg);
     1348                window->cb->focus(window, window->arg, nfocus);
    6291349}
    6301350
     
    6371357        if (window->cb != NULL && window->cb->kbd != NULL)
    6381358                window->cb->kbd(window, window->arg, kbd);
     1359        else
     1360                ui_window_def_kbd(window, kbd);
    6391361}
    6401362
     
    6661388 *
    6671389 * @param window Window
    668  */
    669 void ui_window_send_unfocus(ui_window_t *window)
     1390 * @param nfocus Number of remaining foci
     1391 */
     1392void ui_window_send_unfocus(ui_window_t *window, unsigned nfocus)
    6701393{
    6711394        if (window->cb != NULL && window->cb->unfocus != NULL)
    672                 window->cb->unfocus(window, window->arg);
     1395                window->cb->unfocus(window, window->arg, nfocus);
     1396        else
     1397                return ui_window_def_unfocus(window, nfocus);
     1398}
     1399
     1400/** Send window resize event.
     1401 *
     1402 * @param window Window
     1403 */
     1404void ui_window_send_resize(ui_window_t *window)
     1405{
     1406        if (window->cb != NULL && window->cb->resize != NULL)
     1407                window->cb->resize(window, window->arg);
     1408        else
     1409                return ui_window_def_resize(window);
     1410}
     1411
     1412/** Default window sysmenu routine.
     1413 *
     1414 * @param window Window
     1415 * @param idev_id Input device ID
     1416 * @return EOK on success or an error code
     1417 */
     1418errno_t ui_window_def_sysmenu(ui_window_t *window, sysarg_t idev_id)
     1419{
     1420        errno_t rc;
     1421        ui_wdecor_geom_t geom;
     1422
     1423        if (ui_menu_is_open(window->sysmenu)) {
     1424                ui_menu_close(window->sysmenu);
     1425        } else {
     1426                ui_wdecor_get_geom(window->wdecor, &geom);
     1427
     1428                rc = ui_menu_open(window->sysmenu, &geom.title_bar_rect,
     1429                    idev_id);
     1430                if (rc != EOK)
     1431                        goto error;
     1432        }
     1433
     1434        return EOK;
     1435error:
     1436        return rc;
     1437}
     1438
     1439/** Default window minimize routine.
     1440 *
     1441 * @param window Window
     1442 * @return EOK on success or an error code
     1443 */
     1444errno_t ui_window_def_minimize(ui_window_t *window)
     1445{
     1446        errno_t rc;
     1447
     1448        if (window->dwindow != NULL) {
     1449                rc = display_window_minimize(window->dwindow);
     1450                if (rc != EOK)
     1451                        goto error;
     1452        }
     1453
     1454        return EOK;
     1455error:
     1456        return rc;
     1457}
     1458
     1459/** Default window maximize routine.
     1460 *
     1461 * @param window Window
     1462 * @return EOK on success or an error code
     1463 */
     1464errno_t ui_window_def_maximize(ui_window_t *window)
     1465{
     1466        errno_t rc;
     1467        gfx_rect_t old_rect;
     1468        gfx_rect_t rect;
     1469
     1470        old_rect = window->rect;
     1471
     1472        if (window->dwindow != NULL) {
     1473                rc = display_window_get_max_rect(window->dwindow, &rect);
     1474                if (rc != EOK)
     1475                        return rc;
     1476        } else {
     1477                rect = window->ui->rect;
     1478        }
     1479
     1480        ui_wdecor_set_maximized(window->wdecor, true);
     1481        ui_menu_entry_set_disabled(window->sysmenu_restore, false);
     1482        ui_menu_entry_set_disabled(window->sysmenu_maximize, true);
     1483
     1484        rc = ui_window_size_change(window, &rect, ui_wsc_maximize);
     1485        if (rc != EOK) {
     1486                ui_wdecor_set_maximized(window->wdecor, false);
     1487                return rc;
     1488        }
     1489
     1490        window->normal_rect = old_rect;
     1491        (void) ui_window_paint(window);
     1492        return EOK;
     1493}
     1494
     1495/** Default window unmaximize routine.
     1496 *
     1497 * @param window Window
     1498 * @return EOK on success or an error code
     1499 */
     1500errno_t ui_window_def_unmaximize(ui_window_t *window)
     1501{
     1502        errno_t rc;
     1503
     1504        ui_wdecor_set_maximized(window->wdecor, false);
     1505        ui_menu_entry_set_disabled(window->sysmenu_restore, true);
     1506        ui_menu_entry_set_disabled(window->sysmenu_maximize, false);
     1507
     1508        rc = ui_window_size_change(window, &window->normal_rect,
     1509            ui_wsc_unmaximize);
     1510        if (rc != EOK) {
     1511                ui_wdecor_set_maximized(window->wdecor, true);
     1512                printf("ui_window_size_change->error\n");
     1513                return rc;
     1514        }
     1515
     1516        (void) ui_window_paint(window);
     1517        return EOK;
     1518}
     1519
     1520/** Default window keyboard event routine.
     1521 *
     1522 * @param window Window
     1523 * @return ui_claimed iff event was claimed
     1524 */
     1525ui_evclaim_t ui_window_def_kbd(ui_window_t *window, kbd_event_t *kbd)
     1526{
     1527        ui_evclaim_t claim;
     1528
     1529        if (window->control != NULL)
     1530                claim = ui_control_kbd_event(window->control, kbd);
     1531        else
     1532                claim = ui_unclaimed;
     1533
     1534        if (claim == ui_unclaimed)
     1535                return ui_wdecor_kbd_event(window->wdecor, kbd);
     1536
     1537        return ui_unclaimed;
    6731538}
    6741539
     
    6961561                return ui_control_paint(window->control);
    6971562
     1563        rc = gfx_update(window->res->gc);
     1564        if (rc != EOK)
     1565                return rc;
     1566
    6981567        return EOK;
    6991568}
     
    7021571 *
    7031572 * @param window Window
    704  * @return EOK on success or an error code
    7051573 */
    7061574void ui_window_def_pos(ui_window_t *window, pos_event_t *pos)
     
    7101578}
    7111579
    712 /** Application area update callback
     1580/** Default window unfocus routine.
     1581 *
     1582 * @param window Window
     1583 * @param nfocus Number of remaining foci
     1584 * @return EOK on success or an error code
     1585 */
     1586void ui_window_def_unfocus(ui_window_t *window, unsigned nfocus)
     1587{
     1588        if (window->control != NULL)
     1589                ui_control_unfocus(window->control, nfocus);
     1590}
     1591
     1592/** Default window resize routine.
     1593 *
     1594 * @param window Window
     1595 * @return EOK on success or an error code
     1596 */
     1597void ui_window_def_resize(ui_window_t *window)
     1598{
     1599        ui_window_paint(window);
     1600}
     1601
     1602/** Handle system menu left event.
     1603 *
     1604 * @param sysmenu System menu
     1605 * @param arg Argument (ui_window_t *)
     1606 * @param idev_id Input device ID
     1607 */
     1608static void wnd_sysmenu_left(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
     1609{
     1610        ui_window_t *window = (ui_window_t *)arg;
     1611
     1612        if (window->mbar != NULL) {
     1613                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1614                ui_menu_close(sysmenu);
     1615                ui_menu_bar_select_last(window->mbar, true, idev_id);
     1616        }
     1617}
     1618
     1619/** Handle system menu right event.
     1620 *
     1621 * @param sysmenu System menu
     1622 * @param arg Argument (ui_window_t *)
     1623 * @param idev_id Input device ID
     1624 */
     1625static void wnd_sysmenu_right(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
     1626{
     1627        ui_window_t *window = (ui_window_t *)arg;
     1628
     1629        if (window->mbar != NULL) {
     1630                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1631                ui_menu_close(sysmenu);
     1632                ui_menu_bar_select_first(window->mbar, true, idev_id);
     1633        }
     1634}
     1635
     1636/** Handle system menu close request event.
     1637 *
     1638 * @param sysmenu System menu
     1639 * @param arg Argument (ui_window_t *)
     1640 * @param idev_id Input device ID
     1641 */
     1642static void wnd_sysmenu_close_req(ui_menu_t *sysmenu, void *arg)
     1643{
     1644        ui_window_t *window = (ui_window_t *)arg;
     1645
     1646        ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1647        ui_menu_close(sysmenu);
     1648}
     1649
     1650/** Handle system menu Restore entry activation.
     1651 *
     1652 * @param mentry Menu entry
     1653 * @param arg Argument (ui_window_t *)
     1654 */
     1655static void wnd_sysmenu_erestore(ui_menu_entry_t *mentry, void *arg)
     1656{
     1657        ui_window_t *window = (ui_window_t *)arg;
     1658
     1659        ui_window_send_unmaximize(window);
     1660}
     1661
     1662/** Handle system menu Minimize entry activation.
     1663 *
     1664 * @param mentry Menu entry
     1665 * @param arg Argument (ui_window_t *)
     1666 */
     1667static void wnd_sysmenu_eminimize(ui_menu_entry_t *mentry, void *arg)
     1668{
     1669        ui_window_t *window = (ui_window_t *)arg;
     1670
     1671        ui_window_send_minimize(window);
     1672}
     1673
     1674/** Handle system menu Maximize entry activation.
     1675 *
     1676 * @param mentry Menu entry
     1677 * @param arg Argument (ui_window_t *)
     1678 */
     1679static void wnd_sysmenu_emaximize(ui_menu_entry_t *mentry, void *arg)
     1680{
     1681        ui_window_t *window = (ui_window_t *)arg;
     1682
     1683        ui_window_send_maximize(window);
     1684}
     1685
     1686/** Handle system menu Close entry activation.
     1687 *
     1688 * @param mentry Menu entry
     1689 * @param arg Argument (ui_window_t *)
     1690 */
     1691static void wnd_sysmenu_eclose(ui_menu_entry_t *mentry, void *arg)
     1692{
     1693        ui_window_t *window = (ui_window_t *)arg;
     1694
     1695        ui_window_send_close(window);
     1696}
     1697
     1698/** Handle system menu press accelerator key event.
     1699 *
     1700 * @param sysmenu System menu
     1701 * @param arg Argument (ui_window_t *)
     1702 * @param idev_id Input device ID
     1703 */
     1704static void wnd_sysmenu_press_accel(ui_menu_t *sysmenu, void *arg,
     1705    char32_t c, sysarg_t idev_id)
     1706{
     1707        (void)sysmenu;
     1708        (void)arg;
     1709        (void)c;
     1710        (void)idev_id;
     1711}
     1712
     1713/** Window invalidate callback
    7131714 *
    7141715 * @param arg Argument (ui_window_t *)
    7151716 * @param rect Rectangle to update
    7161717 */
    717 static void ui_window_app_update(void *arg, gfx_rect_t *rect)
     1718static void ui_window_invalidate(void *arg, gfx_rect_t *rect)
     1719{
     1720        ui_window_t *window = (ui_window_t *) arg;
     1721        gfx_rect_t env;
     1722
     1723        gfx_rect_envelope(&window->dirty_rect, rect, &env);
     1724        window->dirty_rect = env;
     1725}
     1726
     1727/** Window update callback
     1728 *
     1729 * @param arg Argument (ui_window_t *)
     1730 */
     1731static void ui_window_update(void *arg)
     1732{
     1733        ui_window_t *window = (ui_window_t *) arg;
     1734
     1735        if (!gfx_rect_is_empty(&window->dirty_rect)) {
     1736                (void) gfx_bitmap_render(window->bmp, &window->dirty_rect,
     1737                    &window->dpos);
     1738        }
     1739
     1740        window->dirty_rect.p0.x = 0;
     1741        window->dirty_rect.p0.y = 0;
     1742        window->dirty_rect.p1.x = 0;
     1743        window->dirty_rect.p1.y = 0;
     1744}
     1745
     1746/** Window cursor get position callback
     1747 *
     1748 * @param arg Argument (ui_window_t *)
     1749 * @param pos Place to store position
     1750 */
     1751static errno_t ui_window_cursor_get_pos(void *arg, gfx_coord2_t *pos)
     1752{
     1753        ui_window_t *window = (ui_window_t *) arg;
     1754        gfx_coord2_t cpos;
     1755        errno_t rc;
     1756
     1757        rc = gfx_cursor_get_pos(window->realgc, &cpos);
     1758        if (rc != EOK)
     1759                return rc;
     1760
     1761        pos->x = cpos.x - window->dpos.x;
     1762        pos->y = cpos.y - window->dpos.y;
     1763        return EOK;
     1764}
     1765
     1766/** Window cursor set position callback
     1767 *
     1768 * @param arg Argument (ui_window_t *)
     1769 * @param pos New position
     1770 */
     1771static errno_t ui_window_cursor_set_pos(void *arg, gfx_coord2_t *pos)
     1772{
     1773        ui_window_t *window = (ui_window_t *) arg;
     1774        gfx_coord2_t cpos;
     1775
     1776        cpos.x = pos->x + window->dpos.x;
     1777        cpos.y = pos->y + window->dpos.y;
     1778
     1779        return gfx_cursor_set_pos(window->realgc, &cpos);
     1780}
     1781
     1782/** Window cursor set visibility callback
     1783 *
     1784 * @param arg Argument (ui_window_t *)
     1785 * @param visible @c true iff cursor is to be made visible
     1786 */
     1787static errno_t ui_window_cursor_set_visible(void *arg, bool visible)
     1788{
     1789        ui_window_t *window = (ui_window_t *) arg;
     1790
     1791        return gfx_cursor_set_visible(window->realgc, visible);
     1792}
     1793
     1794/** Application area invalidate callback
     1795 *
     1796 * @param arg Argument (ui_window_t *)
     1797 * @param rect Rectangle to update
     1798 */
     1799static void ui_window_app_invalidate(void *arg, gfx_rect_t *rect)
    7181800{
    7191801        ui_window_t *window = (ui_window_t *) arg;
     
    7241806        /* Render bitmap rectangle inside the application area */
    7251807        (void) gfx_bitmap_render(window->app_bmp, rect, &arect.p0);
     1808        /*
     1809         * TODO Update applications to call gfx_update(), then
     1810         * we can defer update to ui_window_app_update().
     1811         */
     1812        (void) gfx_update(window->res->gc);
     1813}
     1814
     1815/** Application area update callback
     1816 *
     1817 * @param arg Argument (ui_window_t *)
     1818 */
     1819static void ui_window_app_update(void *arg)
     1820{
     1821        ui_window_t *window = (ui_window_t *) arg;
     1822
     1823        /*
     1824         * Not used since display is updated immediately
     1825         * in ui_window_app_invalidate
     1826         */
     1827        (void) window;
     1828}
     1829
     1830/** Window expose callback. */
     1831static void ui_window_expose_cb(void *arg)
     1832{
     1833        ui_window_t *window = (ui_window_t *) arg;
     1834
     1835        ui_window_paint(window);
    7261836}
    7271837
Note: See TracChangeset for help on using the changeset viewer.