Ignore:
File:
1 edited

Legend:

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

    r25f26600 r9aa51406  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2024 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                assert(ui_is_fullscreen(window->ui));
     192                /* Center window */
     193                gfx_rect_dims(&params->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;
     196                break;
     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;
     201                break;
     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;
     205                break;
     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;
     209                break;
     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;
     213                break;
     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, &params->rect, &below_rect);
     219
     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;
     225                } else {
     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);
     230                }
     231                break;
     232        }
     233}
     234
     235/** Create window's system menu.
     236 *
     237 * @param window Window
     238 * @return EOK on success or an error code
     239 */
     240static errno_t ui_window_sysmenu_create(ui_window_t *window)
     241{
     242        errno_t rc;
     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;
     248
     249        rc = ui_menu_create(window, &window->sysmenu);
     250        if (rc != EOK)
     251                goto error;
     252
     253        ui_menu_set_cb(window->sysmenu, &wnd_sysmenu_cb, (void *)window);
     254
     255        rc = ui_menu_entry_create(window->sysmenu, "~R~estore",
     256            "", &mrestore);
     257        if (rc != EOK)
     258                goto error;
     259
     260        if (!window->wdecor->maximized)
     261                ui_menu_entry_set_disabled(mrestore, true);
     262
     263        ui_menu_entry_set_cb(mrestore, wnd_sysmenu_erestore, (void *)window);
     264
     265        rc = ui_menu_entry_create(window->sysmenu, "Mi~n~imize",
     266            "", &mmin);
     267        if (rc != EOK)
     268                goto error;
     269
     270        if ((window->wdecor->style & ui_wds_minimize_btn) == 0)
     271                ui_menu_entry_set_disabled(mmin, true);
     272
     273        ui_menu_entry_set_cb(mmin, wnd_sysmenu_eminimize, (void *)window);
     274
     275        rc = ui_menu_entry_create(window->sysmenu, "Ma~x~imize",
     276            "", &mmax);
     277        if (rc != EOK)
     278                goto error;
     279
     280        if ((window->wdecor->style & ui_wds_maximize_btn) == 0 ||
     281            window->wdecor->maximized)
     282                ui_menu_entry_set_disabled(mmax, true);
     283
     284        ui_menu_entry_set_cb(mmax, wnd_sysmenu_emaximize, (void *)window);
     285
     286        rc = ui_menu_entry_sep_create(window->sysmenu, &msep);
     287        if (rc != EOK)
     288                goto error;
     289
     290        rc = ui_menu_entry_create(window->sysmenu, "~C~lose", "Alt-F4",
     291            &mclose);
     292        if (rc != EOK)
     293                goto error;
     294
     295        if ((window->wdecor->style & ui_wds_close_btn) == 0)
     296                ui_menu_entry_set_disabled(mclose, true);
     297
     298        ui_menu_entry_set_cb(mclose, wnd_sysmenu_eclose, (void *)window);
     299
     300        window->sysmenu_restore = mrestore;
     301        window->sysmenu_minimize = mmin;
     302        window->sysmenu_maximize = mmax;
     303
     304        return EOK;
     305error:
     306        return rc;
     307}
     308
    105309/** Create new window.
    106310 *
     
    114318{
    115319        ui_window_t *window;
     320        ui_window_t *pwindow = NULL;
    116321        display_info_t info;
    117         gfx_coord2_t pos;
    118322        gfx_coord2_t scr_dims;
    119323        display_wnd_params_t dparams;
    120         display_window_t *dwindow = NULL;
    121324        gfx_context_t *gc = NULL;
    122325        ui_resource_t *res = NULL;
    123326        ui_wdecor_t *wdecor = NULL;
    124327        dummy_gc_t *dgc = NULL;
     328        gfx_bitmap_params_t bparams;
     329        gfx_bitmap_alloc_t alloc;
     330        gfx_bitmap_t *bmp = NULL;
     331        gfx_coord2_t off;
     332        mem_gc_t *memgc = NULL;
     333        xlate_gc_t *xgc = NULL;
    125334        errno_t rc;
    126335
     
    129338                return ENOMEM;
    130339
     340        window->ui = ui;
     341
    131342        display_wnd_params_init(&dparams);
    132343        dparams.rect = params->rect;
    133         /* Only allow making the window larger */
    134         gfx_rect_dims(&params->rect, &dparams.min_size);
     344        dparams.caption = params->caption;
     345        dparams.min_size = params->min_size;
     346
     347        /*
     348         * If idev_id is not specified, use the UI default (probably
     349         * obtained from display specification. This creates the
     350         * main window in the seat specified on the command line.
     351         */
     352        if (params->idev_id != 0)
     353                dparams.idev_id = params->idev_id;
     354        else
     355                dparams.idev_id = ui->idev_id;
     356
     357        if ((params->flags & ui_wndf_popup) != 0)
     358                dparams.flags |= wndf_popup;
     359        if ((params->flags & ui_wndf_topmost) != 0)
     360                dparams.flags |= wndf_topmost;
     361        if ((params->flags & ui_wndf_system) != 0)
     362                dparams.flags |= wndf_system;
     363        if ((params->flags & ui_wndf_avoid) != 0)
     364                dparams.flags |= wndf_avoid;
    135365
    136366        if (ui->display != NULL) {
     
    148378                }
    149379
     380                if (params->placement != ui_wnd_place_default) {
     381                        /* Set initial display window position */
     382                        ui_window_place(window, &info.rect, params,
     383                            &dparams.pos);
     384
     385                        dparams.flags |= wndf_setpos;
     386                }
     387
    150388                rc = display_window_create(ui->display, &dparams, &dwnd_cb,
    151                     (void *) window, &dwindow);
     389                    (void *) window, &window->dwindow);
    152390                if (rc != EOK)
    153391                        goto error;
    154392
    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);
     393                rc = display_window_get_gc(window->dwindow, &gc);
    187394                if (rc != EOK)
    188395                        goto error;
     396        } else if (ui->console != NULL) {
     397                gc = console_gc_get_ctx(ui->cgc);
     398
     399                if (params->placement == ui_wnd_place_full_screen) {
     400                        /* Make window the size of the screen */
     401                        gfx_rect_dims(&ui->rect, &scr_dims);
     402                        gfx_coord2_add(&dparams.rect.p0, &scr_dims,
     403                            &dparams.rect.p1);
     404                        (void) console_set_caption(ui->console,
     405                            params->caption);
     406                }
    189407        } else {
    190408                /* Needed for unit tests */
     
    196414        }
    197415
    198         rc = ui_resource_create(gc, &res);
     416#ifdef CONFIG_UI_CS_RENDER
     417        /* Create window bitmap */
     418        gfx_bitmap_params_init(&bparams);
     419#ifndef CONFIG_WIN_DOUBLE_BUF
     420        /* Console does not support direct output */
     421        if (ui->display != NULL)
     422                bparams.flags |= bmpf_direct_output;
     423#endif
     424
     425        /* Move rectangle so that top-left corner is 0,0 */
     426        gfx_rect_rtranslate(&dparams.rect.p0, &dparams.rect, &bparams.rect);
     427
     428        rc = gfx_bitmap_create(gc, &bparams, NULL, &bmp);
     429        if (rc != EOK)
     430                goto error;
     431
     432        /* Create memory GC */
     433        rc = gfx_bitmap_get_alloc(bmp, &alloc);
     434        if (rc != EOK) {
     435                gfx_bitmap_destroy(window->app_bmp);
     436                return rc;
     437        }
     438
     439        rc = mem_gc_create(&bparams.rect, &alloc, &ui_window_mem_gc_cb,
     440            (void *) window, &memgc);
     441        if (rc != EOK) {
     442                gfx_bitmap_destroy(window->app_bmp);
     443                return rc;
     444        }
     445
     446        window->bmp = bmp;
     447        window->mgc = memgc;
     448        window->gc = mem_gc_get_ctx(memgc);
     449        window->realgc = gc;
     450        (void) off;
     451#else
     452        /* Server-side rendering */
     453
     454        /* Full-screen mode? */
     455        if (ui->display == NULL) {
     456                /* Create translating GC to translate window contents */
     457                off.x = 0;
     458                off.y = 0;
     459                rc = xlate_gc_create(&off, gc, &xgc);
     460                if (rc != EOK)
     461                        goto error;
     462
     463                window->xgc = xgc;
     464                window->gc = xlate_gc_get_ctx(xgc);
     465                window->realgc = gc;
     466        } else {
     467                window->gc = gc;
     468        }
     469
     470        (void) ui_window_mem_gc_cb;
     471        (void) alloc;
     472        (void) bparams;
     473#endif
     474        if (ui->display == NULL) {
     475                ui_window_place(window, &ui->rect, params, &window->dpos);
     476
     477                if (window->xgc != NULL)
     478                        xlate_gc_set_off(window->xgc, &window->dpos);
     479        }
     480
     481        rc = ui_resource_create(window->gc, ui_is_textmode(ui), &res);
    199482        if (rc != EOK)
    200483                goto error;
     
    208491        ui_wdecor_paint(wdecor);
    209492
    210         window->ui = ui;
    211         window->dwindow = dwindow;
     493        ui_resource_set_expose_cb(res, ui_window_expose_cb, (void *) window);
     494
    212495        window->rect = dparams.rect;
    213         window->gc = gc;
    214496        window->res = res;
    215497        window->wdecor = wdecor;
    216498        window->cursor = ui_curs_arrow;
     499        window->placement = params->placement;
     500
     501        rc = ui_window_sysmenu_create(window);
     502        if (rc != EOK)
     503                goto error;
     504
    217505        *rwindow = window;
     506
     507        if (ui_is_fullscreen(ui))
     508                pwindow = ui_window_get_active(ui);
     509
     510        list_append(&window->lwindows, &ui->windows);
     511
     512        if (ui_is_fullscreen(ui)) {
     513                /* Send unfocus event to previously active window */
     514                if (pwindow != NULL)
     515                        ui_window_send_unfocus(pwindow, 0);
     516        }
     517
    218518        return EOK;
    219519error:
     
    222522        if (res != NULL)
    223523                ui_resource_destroy(res);
     524        if (memgc != NULL)
     525                mem_gc_delete(memgc);
     526        if (xgc != NULL)
     527                xlate_gc_delete(xgc);
     528        if (bmp != NULL)
     529                gfx_bitmap_destroy(bmp);
    224530        if (dgc != NULL)
    225531                dummygc_destroy(dgc);
    226         if (dwindow != NULL)
    227                 display_window_destroy(dwindow);
    228532        free(window);
    229533        return rc;
     
    236540void ui_window_destroy(ui_window_t *window)
    237541{
     542        ui_t *ui;
     543        ui_window_t *nwindow;
     544
    238545        if (window == NULL)
    239546                return;
    240547
     548        ui = window->ui;
     549
     550        list_remove(&window->lwindows);
    241551        ui_control_destroy(window->control);
     552        ui_menu_destroy(window->sysmenu);
    242553        ui_wdecor_destroy(window->wdecor);
    243554        ui_resource_destroy(window->res);
    244         gfx_context_delete(window->gc);
    245         display_window_destroy(window->dwindow);
     555        if (window->app_mgc != NULL)
     556                mem_gc_delete(window->app_mgc);
     557        if (window->app_bmp != NULL)
     558                gfx_bitmap_destroy(window->app_bmp);
     559        if (window->mgc != NULL) {
     560                mem_gc_delete(window->mgc);
     561                window->gc = NULL;
     562        }
     563        if (window->bmp != NULL)
     564                gfx_bitmap_destroy(window->bmp);
     565        if (window->dwindow != NULL)
     566                display_window_destroy(window->dwindow);
     567
     568        /* Need to repaint if windows are emulated */
     569        if (ui_is_fullscreen(ui)) {
     570                ui_paint(ui);
     571                /* Send focus event to newly active window */
     572                nwindow = ui_window_get_active(ui);
     573                if (nwindow != NULL)
     574                        ui_window_send_focus(nwindow, 0);
     575        }
     576
     577        if (ui->console != NULL &&
     578            window->placement == ui_wnd_place_full_screen) {
     579                (void) console_set_caption(ui->console, "");
     580        }
     581
    246582        free(window);
    247583}
     
    252588 * is added, the results are undefined.
    253589 *
    254  * @param fixed Fixed layout
     590 * @param window Window
    255591 * @param control Control
    256  * @return EOK on success, ENOMEM if out of memory
    257592 */
    258593void ui_window_add(ui_window_t *window, ui_control_t *control)
     
    278613}
    279614
    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.
     615/** Get active window (only valid in fullscreen mode).
     616 *
     617 * @param ui User interface
     618 * @return Active window
     619 */
     620ui_window_t *ui_window_get_active(ui_t *ui)
     621{
     622        link_t *link;
     623
     624        link = list_last(&ui->windows);
     625        if (link == NULL)
     626                return NULL;
     627
     628        return list_get_instance(link, ui_window_t, lwindows);
     629}
     630
     631/** Resize or (un)maximize window.
    284632 *
    285633 * @param window Window
    286634 * @param rect Rectangle
     635 * @param scop Size change operation
    287636 *
    288637 * @return EOK on success or an error code
    289638 */
    290 errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
     639errno_t ui_window_size_change(ui_window_t *window, gfx_rect_t *rect,
     640    ui_wnd_sc_op_t scop)
    291641{
    292642        gfx_coord2_t offs;
     
    294644        gfx_rect_t arect;
    295645        gfx_bitmap_t *app_bmp = NULL;
    296         gfx_bitmap_params_t params;
    297         gfx_bitmap_alloc_t alloc;
     646        gfx_bitmap_t *win_bmp = NULL;
     647        gfx_bitmap_params_t app_params;
     648        gfx_bitmap_params_t win_params;
     649        gfx_bitmap_alloc_t app_alloc;
     650        gfx_bitmap_alloc_t win_alloc;
    298651        errno_t rc;
    299652
     
    305658        gfx_rect_rtranslate(&offs, rect, &nrect);
    306659
     660        /* mgc != NULL iff client-side rendering */
     661        if (window->mgc != NULL) {
     662#ifdef CONFIG_WIN_DOUBLE_BUF
     663                /*
     664                 * Create new window bitmap in advance. If direct mapping,
     665                 * will need do it after resizing the window.
     666                 */
     667                assert(window->bmp != NULL);
     668                gfx_bitmap_params_init(&win_params);
     669                win_params.rect = nrect;
     670
     671                rc = gfx_bitmap_create(window->realgc, &win_params, NULL,
     672                    &win_bmp);
     673                if (rc != EOK)
     674                        goto error;
     675
     676                rc = gfx_bitmap_get_alloc(win_bmp, &win_alloc);
     677                if (rc != EOK)
     678                        goto error;
     679#endif
     680        }
     681
     682        /* Application area GC? */
    307683        if (window->app_gc != NULL) {
     684                /* Resize application bitmap */
    308685                assert(window->app_bmp != NULL);
    309686
    310                 gfx_bitmap_params_init(&params);
     687                gfx_bitmap_params_init(&app_params);
    311688
    312689                /*
     
    315692                 */
    316693                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,
     694                gfx_rect_rtranslate(&arect.p0, &arect, &app_params.rect);
     695
     696                rc = gfx_bitmap_create(window->gc, &app_params, NULL,
    320697                    &app_bmp);
    321698                if (rc != EOK)
    322699                        goto error;
    323700
    324                 rc = gfx_bitmap_get_alloc(app_bmp, &alloc);
     701                rc = gfx_bitmap_get_alloc(app_bmp, &app_alloc);
    325702                if (rc != EOK)
    326703                        goto error;
    327704        }
    328705
    329         /* dwindow can be NULL in case of unit tests */
     706        /* dwindow can be NULL in case of unit tests or fullscreen mode */
    330707        if (window->dwindow != NULL) {
    331                 rc = display_window_resize(window->dwindow, &offs, &nrect);
     708                switch (scop) {
     709                case ui_wsc_resize:
     710                        rc = display_window_resize(window->dwindow, &offs,
     711                            &nrect);
     712                        if (rc != EOK)
     713                                goto error;
     714                        break;
     715                case ui_wsc_maximize:
     716                        rc = display_window_maximize(window->dwindow);
     717                        if (rc != EOK)
     718                                goto error;
     719                        break;
     720                case ui_wsc_unmaximize:
     721                        rc = display_window_unmaximize(window->dwindow);
     722                        if (rc != EOK)
     723                                goto error;
     724                        break;
     725                }
     726        }
     727
     728        /* Client side rendering? */
     729        if (window->mgc != NULL) {
     730#ifndef CONFIG_WIN_DOUBLE_BUF
     731                /* Window is resized, now we can map the window bitmap again */
     732                gfx_bitmap_params_init(&win_params);
     733                win_params.flags |= bmpf_direct_output;
     734                win_params.rect = nrect;
     735
     736                rc = gfx_bitmap_create(window->realgc, &win_params, NULL,
     737                    &win_bmp);
    332738                if (rc != EOK)
    333739                        goto error;
    334         }
    335 
     740
     741                rc = gfx_bitmap_get_alloc(win_bmp, &win_alloc);
     742                if (rc != EOK)
     743                        goto error;
     744#endif
     745                mem_gc_retarget(window->mgc, &win_params.rect, &win_alloc);
     746
     747                gfx_bitmap_destroy(window->bmp);
     748                window->bmp = win_bmp;
     749        }
     750
     751        window->rect = nrect;
    336752        ui_wdecor_set_rect(window->wdecor, &nrect);
    337753        ui_wdecor_paint(window->wdecor);
    338 
     754        gfx_update(window->gc);
     755
     756        /* Application area GC? */
    339757        if (window->app_gc != NULL) {
    340                 mem_gc_retarget(window->app_mgc, &params.rect, &alloc);
     758                mem_gc_retarget(window->app_mgc, &app_params.rect, &app_alloc);
    341759
    342760                gfx_bitmap_destroy(window->app_bmp);
     
    348766        if (app_bmp != NULL)
    349767                gfx_bitmap_destroy(app_bmp);
     768        if (win_bmp != NULL)
     769                gfx_bitmap_destroy(win_bmp);
    350770        return rc;
    351771}
    352772
     773/** Resize/move window.
     774 *
     775 * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
     776 * the top-left corner of the window will move on the screen accordingly.
     777 *
     778 * @param window Window
     779 * @param rect Rectangle
     780 *
     781 * @return EOK on success or an error code
     782 */
     783errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
     784{
     785        return ui_window_size_change(window, rect, ui_wsc_resize);
     786}
     787
    353788/** Set window callbacks.
    354789 *
    355790 * @param window Window
    356  * @param cb Window decoration callbacks
     791 * @param cb Window callbacks
    357792 * @param arg Callback argument
    358793 */
     
    363798}
    364799
     800/** Change window caption.
     801 *
     802 * @param window Window
     803 * @param caption New caption
     804 *
     805 * @return EOK on success or an error code
     806 */
     807errno_t ui_window_set_caption(ui_window_t *window, const char *caption)
     808{
     809        errno_t rc;
     810
     811        /* Set console caption if fullscreen window on console */
     812        if (window->ui->console != NULL && window->placement ==
     813            ui_wnd_place_full_screen) {
     814                rc = console_set_caption(window->ui->console, caption);
     815                if (rc != EOK)
     816                        return rc;
     817        }
     818
     819        /* Set display window caption if running on display service */
     820        if (window->dwindow != NULL) {
     821                rc = display_window_set_caption(window->dwindow, caption);
     822                if (rc != EOK)
     823                        return rc;
     824        }
     825
     826        return ui_wdecor_set_caption(window->wdecor, caption);
     827}
     828
     829/** Get window's containing UI.
     830 *
     831 * @param window Window
     832 * @return Containing UI
     833 */
     834ui_t *ui_window_get_ui(ui_window_t *window)
     835{
     836        return window->ui;
     837}
     838
    365839/** Get UI resource from window.
    366840 *
     
    381855{
    382856        return window->gc;
     857}
     858
     859/** Get window position.
     860 *
     861 * @param window Window
     862 * @param pos Place to store position
     863 * @return EOK on success or an error code
     864 */
     865errno_t ui_window_get_pos(ui_window_t *window, gfx_coord2_t *pos)
     866{
     867        errno_t rc;
     868
     869        if (window->dwindow != NULL) {
     870                rc = display_window_get_pos(window->dwindow, pos);
     871                if (rc != EOK)
     872                        return rc;
     873        } else {
     874                *pos = window->dpos;
     875        }
     876
     877        return EOK;
    383878}
    384879
     
    420915                }
    421916
    422                 rc = mem_gc_create(&params.rect, &alloc, ui_window_app_update,
    423                     (void *) window, &memgc);
     917                rc = mem_gc_create(&params.rect, &alloc,
     918                    &ui_window_app_mem_gc_cb, (void *) window, &memgc);
    424919                if (rc != EOK) {
    425920                        gfx_bitmap_destroy(window->app_bmp);
     
    448943}
    449944
     945/** Set cursor when pointer is hovering over a control.
     946 *
     947 * @param window Window
     948 * @param cursor Cursor
     949 */
     950void ui_window_set_ctl_cursor(ui_window_t *window, ui_stock_cursor_t cursor)
     951{
     952        display_stock_cursor_t dcursor;
     953
     954        dcursor = wnd_dcursor_from_cursor(cursor);
     955
     956        if (window->dwindow != NULL)
     957                (void) display_window_set_cursor(window->dwindow, dcursor);
     958}
     959
    450960/** Paint window
    451961 *
     
    462972{
    463973        ui_window_t *window = (ui_window_t *) arg;
    464 
     974        ui_t *ui = window->ui;
     975
     976        ui_lock(ui);
    465977        ui_window_send_close(window);
     978        ui_unlock(ui);
    466979}
    467980
    468981/** Handle window focus event. */
    469 static void dwnd_focus_event(void *arg)
    470 {
    471         ui_window_t *window = (ui_window_t *) arg;
     982static void dwnd_focus_event(void *arg, unsigned nfocus)
     983{
     984        ui_window_t *window = (ui_window_t *) arg;
     985        ui_t *ui = window->ui;
     986
     987        ui_lock(ui);
     988        (void)nfocus;
    472989
    473990        if (window->wdecor != NULL) {
     
    476993        }
    477994
    478         ui_window_send_focus(window);
     995        ui_window_send_focus(window, nfocus);
     996        ui_unlock(ui);
    479997}
    480998
     
    4831001{
    4841002        ui_window_t *window = (ui_window_t *) arg;
    485 
    486         (void) window;
     1003        ui_t *ui = window->ui;
     1004
     1005        ui_lock(ui);
    4871006        ui_window_send_kbd(window, kbd_event);
     1007        ui_unlock(ui);
    4881008}
    4891009
     
    4921012{
    4931013        ui_window_t *window = (ui_window_t *) arg;
     1014        ui_t *ui = window->ui;
     1015        ui_evclaim_t claim;
    4941016
    4951017        /* Make sure we don't process events until fully initialized */
     
    4971019                return;
    4981020
    499         ui_wdecor_pos_event(window->wdecor, event);
     1021        ui_lock(ui);
     1022
     1023        claim = ui_wdecor_pos_event(window->wdecor, event);
     1024        if (claim == ui_claimed) {
     1025                ui_unlock(ui);
     1026                return;
     1027        }
     1028
    5001029        ui_window_send_pos(window, event);
     1030        ui_unlock(ui);
    5011031}
    5021032
     
    5051035{
    5061036        ui_window_t *window = (ui_window_t *) arg;
     1037        ui_t *ui = window->ui;
    5071038
    5081039        /* Make sure we don't process events until fully initialized */
     
    5131044                return;
    5141045
     1046        ui_lock(ui);
    5151047        (void) ui_window_resize(window, rect);
    516         (void) ui_window_paint(window);
     1048        ui_window_send_resize(window);
     1049        ui_unlock(ui);
    5171050}
    5181051
    5191052/** 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) {
     1053static void dwnd_unfocus_event(void *arg, unsigned nfocus)
     1054{
     1055        ui_window_t *window = (ui_window_t *) arg;
     1056        ui_t *ui = window->ui;
     1057
     1058        ui_lock(ui);
     1059
     1060        if (window->wdecor != NULL && nfocus == 0) {
    5251061                ui_wdecor_set_active(window->wdecor, false);
    5261062                ui_wdecor_paint(window->wdecor);
    5271063        }
    5281064
    529         ui_window_send_unfocus(window);
     1065        ui_window_send_unfocus(window, nfocus);
     1066        ui_unlock(ui);
     1067}
     1068
     1069/** Window decoration requested opening of system menu.
     1070 *
     1071 * @param wdecor Window decoration
     1072 * @param arg Argument (window)
     1073 * @param idev_id Input device ID
     1074 */
     1075static void wd_sysmenu_open(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1076{
     1077        ui_window_t *window = (ui_window_t *) arg;
     1078
     1079        ui_window_send_sysmenu(window, idev_id);
     1080}
     1081
     1082/** Window decoration requested moving left from system menu handle.
     1083 *
     1084 * @param wdecor Window decoration
     1085 * @param arg Argument (window)
     1086 * @param idev_id Input device ID
     1087 */
     1088static void wd_sysmenu_left(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1089{
     1090        ui_window_t *window = (ui_window_t *) arg;
     1091
     1092        if (window->mbar != NULL) {
     1093                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1094                ui_menu_close(window->sysmenu);
     1095                ui_menu_bar_select_last(window->mbar, false, idev_id);
     1096        }
     1097}
     1098
     1099/** Window decoration requested moving right from system menu handle.
     1100 *
     1101 * @param wdecor Window decoration
     1102 * @param arg Argument (window)
     1103 * @param idev_id Input device ID
     1104 */
     1105static void wd_sysmenu_right(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1106{
     1107        ui_window_t *window = (ui_window_t *) arg;
     1108
     1109        if (window->mbar != NULL) {
     1110                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1111                ui_menu_close(window->sysmenu);
     1112                ui_menu_bar_select_first(window->mbar, false, idev_id);
     1113        }
     1114}
     1115
     1116/** Window decoration detected accelerator press from system menu handle.
     1117 *
     1118 * @param wdecor Window decoration
     1119 * @param arg Argument (window)
     1120 * @param c Accelerator key
     1121 * @param idev_id Input device ID
     1122 */
     1123static void wd_sysmenu_accel(ui_wdecor_t *wdecor, void *arg, char32_t c,
     1124    sysarg_t idev_id)
     1125{
     1126        ui_window_t *window = (ui_window_t *) arg;
     1127
     1128        if (window->mbar != NULL) {
     1129                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1130                ui_menu_close(window->sysmenu);
     1131                ui_menu_bar_press_accel(window->mbar, c, idev_id);
     1132        }
     1133}
     1134
     1135/** Window decoration requested window minimization.
     1136 *
     1137 * @param wdecor Window decoration
     1138 * @param arg Argument (window)
     1139 */
     1140static void wd_minimize(ui_wdecor_t *wdecor, void *arg)
     1141{
     1142        ui_window_t *window = (ui_window_t *) arg;
     1143
     1144        ui_window_send_minimize(window);
     1145}
     1146
     1147/** Window decoration requested window maximization.
     1148 *
     1149 * @param wdecor Window decoration
     1150 * @param arg Argument (window)
     1151 */
     1152static void wd_maximize(ui_wdecor_t *wdecor, void *arg)
     1153{
     1154        ui_window_t *window = (ui_window_t *) arg;
     1155
     1156        ui_window_send_maximize(window);
     1157}
     1158
     1159/** Window decoration requested window unmaximization.
     1160 *
     1161 * @param wdecor Window decoration
     1162 * @param arg Argument (window)
     1163 */
     1164static void wd_unmaximize(ui_wdecor_t *wdecor, void *arg)
     1165{
     1166        ui_window_t *window = (ui_window_t *) arg;
     1167
     1168        ui_window_send_unmaximize(window);
    5301169}
    5311170
     
    5471186 * @param arg Argument (window)
    5481187 * @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);
     1188 * @param pos_id Positioning device ID
     1189 */
     1190static void wd_move(ui_wdecor_t *wdecor, void *arg, gfx_coord2_t *pos,
     1191    sysarg_t pos_id)
     1192{
     1193        ui_window_t *window = (ui_window_t *) arg;
     1194
     1195        if (window->dwindow != NULL)
     1196                (void) display_window_move_req(window->dwindow, pos, pos_id);
    5551197}
    5561198
     
    5611203 * @param rsztype Resize type
    5621204 * @param pos Position where the button was pressed
     1205 * @param pos_id Positioning device ID
    5631206 */
    5641207static 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;
     1208    ui_wdecor_rsztype_t rsztype, gfx_coord2_t *pos, sysarg_t pos_id)
     1209{
     1210        ui_window_t *window = (ui_window_t *) arg;
     1211
     1212        if (window->dwindow != NULL) {
     1213                (void) display_window_resize_req(window->dwindow,
     1214                    (display_wnd_rsztype_t) rsztype, // Same constants in the enums
     1215                    pos, pos_id);
     1216        }
     1217}
     1218
     1219/** Get display stock cursor from UI stock cursor.
     1220 *
     1221 * @param cursor UI stock cursor
     1222 * @return Display stock cursor
     1223 */
     1224display_stock_cursor_t wnd_dcursor_from_cursor(ui_stock_cursor_t cursor)
     1225{
    5821226        display_stock_cursor_t dcursor;
    583 
    584         if (cursor == window->cursor)
    585                 return;
    5861227
    5871228        dcursor = dcurs_arrow;
     
    6031244                dcursor = dcurs_size_urdl;
    6041245                break;
    605         }
    606 
    607         (void) display_window_set_cursor(window->dwindow, dcursor);
     1246        case ui_curs_ibeam:
     1247                dcursor = dcurs_ibeam;
     1248                break;
     1249        }
     1250
     1251        return dcursor;
     1252}
     1253
     1254/** Window decoration requested changing cursor.
     1255 *
     1256 * @param wdecor Window decoration
     1257 * @param arg Argument (window)
     1258 * @param cursor Cursor to set
     1259 */
     1260static void wd_set_cursor(ui_wdecor_t *wdecor, void *arg,
     1261    ui_stock_cursor_t cursor)
     1262{
     1263        ui_window_t *window = (ui_window_t *) arg;
     1264        display_stock_cursor_t dcursor;
     1265
     1266        if (cursor == window->cursor)
     1267                return;
     1268
     1269        dcursor = wnd_dcursor_from_cursor(cursor);
     1270
     1271        if (window->dwindow != NULL)
     1272                (void) display_window_set_cursor(window->dwindow, dcursor);
     1273
    6081274        window->cursor = cursor;
     1275}
     1276
     1277/** Send window sysmenu event.
     1278 *
     1279 * @param window Window
     1280 * @parma idev_id Input device ID
     1281 */
     1282void ui_window_send_sysmenu(ui_window_t *window, sysarg_t idev_id)
     1283{
     1284        if (window->cb != NULL && window->cb->sysmenu != NULL)
     1285                window->cb->sysmenu(window, window->arg, idev_id);
     1286        else
     1287                ui_window_def_sysmenu(window, idev_id);
     1288}
     1289
     1290/** Send window minimize event.
     1291 *
     1292 * @param window Window
     1293 */
     1294void ui_window_send_minimize(ui_window_t *window)
     1295{
     1296        if (window->cb != NULL && window->cb->minimize != NULL)
     1297                window->cb->minimize(window, window->arg);
     1298        else
     1299                ui_window_def_minimize(window);
     1300}
     1301
     1302/** Send window maximize event.
     1303 *
     1304 * @param window Window
     1305 */
     1306void ui_window_send_maximize(ui_window_t *window)
     1307{
     1308        if (window->cb != NULL && window->cb->maximize != NULL)
     1309                window->cb->maximize(window, window->arg);
     1310        else
     1311                ui_window_def_maximize(window);
     1312}
     1313
     1314/** Send window unmaximize event.
     1315 *
     1316 * @param window Window
     1317 */
     1318void ui_window_send_unmaximize(ui_window_t *window)
     1319{
     1320        if (window->cb != NULL && window->cb->unmaximize != NULL)
     1321                window->cb->unmaximize(window, window->arg);
     1322        else
     1323                ui_window_def_unmaximize(window);
    6091324}
    6101325
     
    6221337 *
    6231338 * @param window Window
    624  */
    625 void ui_window_send_focus(ui_window_t *window)
     1339 * @param nfocus New number of foci
     1340 */
     1341void ui_window_send_focus(ui_window_t *window, unsigned nfocus)
    6261342{
    6271343        if (window->cb != NULL && window->cb->focus != NULL)
    628                 window->cb->focus(window, window->arg);
     1344                window->cb->focus(window, window->arg, nfocus);
    6291345}
    6301346
     
    6371353        if (window->cb != NULL && window->cb->kbd != NULL)
    6381354                window->cb->kbd(window, window->arg, kbd);
     1355        else
     1356                ui_window_def_kbd(window, kbd);
    6391357}
    6401358
     
    6661384 *
    6671385 * @param window Window
    668  */
    669 void ui_window_send_unfocus(ui_window_t *window)
     1386 * @param nfocus Number of remaining foci
     1387 */
     1388void ui_window_send_unfocus(ui_window_t *window, unsigned nfocus)
    6701389{
    6711390        if (window->cb != NULL && window->cb->unfocus != NULL)
    672                 window->cb->unfocus(window, window->arg);
     1391                window->cb->unfocus(window, window->arg, nfocus);
     1392        else
     1393                return ui_window_def_unfocus(window, nfocus);
     1394}
     1395
     1396/** Send window resize event.
     1397 *
     1398 * @param window Window
     1399 */
     1400void ui_window_send_resize(ui_window_t *window)
     1401{
     1402        if (window->cb != NULL && window->cb->resize != NULL)
     1403                window->cb->resize(window, window->arg);
     1404        else
     1405                return ui_window_def_resize(window);
     1406}
     1407
     1408/** Default window sysmenu routine.
     1409 *
     1410 * @param window Window
     1411 * @param idev_id Input device ID
     1412 * @return EOK on success or an error code
     1413 */
     1414errno_t ui_window_def_sysmenu(ui_window_t *window, sysarg_t idev_id)
     1415{
     1416        errno_t rc;
     1417        ui_wdecor_geom_t geom;
     1418
     1419        if (ui_menu_is_open(window->sysmenu)) {
     1420                ui_menu_close(window->sysmenu);
     1421        } else {
     1422                ui_wdecor_get_geom(window->wdecor, &geom);
     1423
     1424                rc = ui_menu_open(window->sysmenu, &geom.title_bar_rect,
     1425                    idev_id);
     1426                if (rc != EOK)
     1427                        goto error;
     1428        }
     1429
     1430        return EOK;
     1431error:
     1432        return rc;
     1433}
     1434
     1435/** Default window minimize routine.
     1436 *
     1437 * @param window Window
     1438 * @return EOK on success or an error code
     1439 */
     1440errno_t ui_window_def_minimize(ui_window_t *window)
     1441{
     1442        errno_t rc;
     1443
     1444        if (window->dwindow != NULL) {
     1445                rc = display_window_minimize(window->dwindow);
     1446                if (rc != EOK)
     1447                        goto error;
     1448        }
     1449
     1450        return EOK;
     1451error:
     1452        return rc;
     1453}
     1454
     1455/** Default window maximize routine.
     1456 *
     1457 * @param window Window
     1458 * @return EOK on success or an error code
     1459 */
     1460errno_t ui_window_def_maximize(ui_window_t *window)
     1461{
     1462        errno_t rc;
     1463        gfx_rect_t old_rect;
     1464        gfx_rect_t rect;
     1465
     1466        old_rect = window->rect;
     1467
     1468        if (window->dwindow != NULL) {
     1469                rc = display_window_get_max_rect(window->dwindow, &rect);
     1470                if (rc != EOK)
     1471                        return rc;
     1472        } else {
     1473                rect = window->ui->rect;
     1474        }
     1475
     1476        ui_wdecor_set_maximized(window->wdecor, true);
     1477        ui_menu_entry_set_disabled(window->sysmenu_restore, false);
     1478        ui_menu_entry_set_disabled(window->sysmenu_maximize, true);
     1479
     1480        rc = ui_window_size_change(window, &rect, ui_wsc_maximize);
     1481        if (rc != EOK) {
     1482                ui_wdecor_set_maximized(window->wdecor, false);
     1483                return rc;
     1484        }
     1485
     1486        window->normal_rect = old_rect;
     1487        (void) ui_window_paint(window);
     1488        return EOK;
     1489}
     1490
     1491/** Default window unmaximize routine.
     1492 *
     1493 * @param window Window
     1494 * @return EOK on success or an error code
     1495 */
     1496errno_t ui_window_def_unmaximize(ui_window_t *window)
     1497{
     1498        errno_t rc;
     1499
     1500        ui_wdecor_set_maximized(window->wdecor, false);
     1501        ui_menu_entry_set_disabled(window->sysmenu_restore, true);
     1502        ui_menu_entry_set_disabled(window->sysmenu_maximize, false);
     1503
     1504        rc = ui_window_size_change(window, &window->normal_rect,
     1505            ui_wsc_unmaximize);
     1506        if (rc != EOK) {
     1507                ui_wdecor_set_maximized(window->wdecor, true);
     1508                printf("ui_window_size_change->error\n");
     1509                return rc;
     1510        }
     1511
     1512        (void) ui_window_paint(window);
     1513        return EOK;
     1514}
     1515
     1516/** Default window keyboard event routine.
     1517 *
     1518 * @param window Window
     1519 * @return ui_claimed iff event was claimed
     1520 */
     1521ui_evclaim_t ui_window_def_kbd(ui_window_t *window, kbd_event_t *kbd)
     1522{
     1523        ui_evclaim_t claim;
     1524
     1525        if (window->control != NULL)
     1526                claim = ui_control_kbd_event(window->control, kbd);
     1527        else
     1528                claim = ui_unclaimed;
     1529
     1530        if (claim == ui_unclaimed)
     1531                return ui_wdecor_kbd_event(window->wdecor, kbd);
     1532
     1533        return ui_unclaimed;
    6731534}
    6741535
     
    6961557                return ui_control_paint(window->control);
    6971558
     1559        rc = gfx_update(window->res->gc);
     1560        if (rc != EOK)
     1561                return rc;
     1562
    6981563        return EOK;
    6991564}
     
    7021567 *
    7031568 * @param window Window
    704  * @return EOK on success or an error code
    7051569 */
    7061570void ui_window_def_pos(ui_window_t *window, pos_event_t *pos)
     
    7101574}
    7111575
    712 /** Application area update callback
     1576/** Default window unfocus routine.
     1577 *
     1578 * @param window Window
     1579 * @param nfocus Number of remaining foci
     1580 * @return EOK on success or an error code
     1581 */
     1582void ui_window_def_unfocus(ui_window_t *window, unsigned nfocus)
     1583{
     1584        if (window->control != NULL)
     1585                ui_control_unfocus(window->control, nfocus);
     1586}
     1587
     1588/** Default window resize routine.
     1589 *
     1590 * @param window Window
     1591 * @return EOK on success or an error code
     1592 */
     1593void ui_window_def_resize(ui_window_t *window)
     1594{
     1595        ui_window_paint(window);
     1596}
     1597
     1598/** Handle system menu left event.
     1599 *
     1600 * @param sysmenu System menu
     1601 * @param arg Argument (ui_window_t *)
     1602 * @param idev_id Input device ID
     1603 */
     1604static void wnd_sysmenu_left(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
     1605{
     1606        ui_window_t *window = (ui_window_t *)arg;
     1607
     1608        if (window->mbar != NULL) {
     1609                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1610                ui_menu_close(sysmenu);
     1611                ui_menu_bar_select_last(window->mbar, true, idev_id);
     1612        }
     1613}
     1614
     1615/** Handle system menu right event.
     1616 *
     1617 * @param sysmenu System menu
     1618 * @param arg Argument (ui_window_t *)
     1619 * @param idev_id Input device ID
     1620 */
     1621static void wnd_sysmenu_right(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
     1622{
     1623        ui_window_t *window = (ui_window_t *)arg;
     1624
     1625        if (window->mbar != NULL) {
     1626                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1627                ui_menu_close(sysmenu);
     1628                ui_menu_bar_select_first(window->mbar, true, idev_id);
     1629        }
     1630}
     1631
     1632/** Handle system menu close request event.
     1633 *
     1634 * @param sysmenu System menu
     1635 * @param arg Argument (ui_window_t *)
     1636 * @param idev_id Input device ID
     1637 */
     1638static void wnd_sysmenu_close_req(ui_menu_t *sysmenu, void *arg)
     1639{
     1640        ui_window_t *window = (ui_window_t *)arg;
     1641
     1642        ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1643        ui_menu_close(sysmenu);
     1644}
     1645
     1646/** Handle system menu Restore entry activation.
     1647 *
     1648 * @param mentry Menu entry
     1649 * @param arg Argument (ui_window_t *)
     1650 */
     1651static void wnd_sysmenu_erestore(ui_menu_entry_t *mentry, void *arg)
     1652{
     1653        ui_window_t *window = (ui_window_t *)arg;
     1654
     1655        ui_window_send_unmaximize(window);
     1656}
     1657
     1658/** Handle system menu Minimize entry activation.
     1659 *
     1660 * @param mentry Menu entry
     1661 * @param arg Argument (ui_window_t *)
     1662 */
     1663static void wnd_sysmenu_eminimize(ui_menu_entry_t *mentry, void *arg)
     1664{
     1665        ui_window_t *window = (ui_window_t *)arg;
     1666
     1667        ui_window_send_minimize(window);
     1668}
     1669
     1670/** Handle system menu Maximize entry activation.
     1671 *
     1672 * @param mentry Menu entry
     1673 * @param arg Argument (ui_window_t *)
     1674 */
     1675static void wnd_sysmenu_emaximize(ui_menu_entry_t *mentry, void *arg)
     1676{
     1677        ui_window_t *window = (ui_window_t *)arg;
     1678
     1679        ui_window_send_maximize(window);
     1680}
     1681
     1682/** Handle system menu Close entry activation.
     1683 *
     1684 * @param mentry Menu entry
     1685 * @param arg Argument (ui_window_t *)
     1686 */
     1687static void wnd_sysmenu_eclose(ui_menu_entry_t *mentry, void *arg)
     1688{
     1689        ui_window_t *window = (ui_window_t *)arg;
     1690
     1691        ui_window_send_close(window);
     1692}
     1693
     1694/** Handle system menu press accelerator key event.
     1695 *
     1696 * @param sysmenu System menu
     1697 * @param arg Argument (ui_window_t *)
     1698 * @param idev_id Input device ID
     1699 */
     1700static void wnd_sysmenu_press_accel(ui_menu_t *sysmenu, void *arg,
     1701    char32_t c, sysarg_t idev_id)
     1702{
     1703        (void)sysmenu;
     1704        (void)arg;
     1705        (void)c;
     1706        (void)idev_id;
     1707}
     1708
     1709/** Window invalidate callback
    7131710 *
    7141711 * @param arg Argument (ui_window_t *)
    7151712 * @param rect Rectangle to update
    7161713 */
    717 static void ui_window_app_update(void *arg, gfx_rect_t *rect)
     1714static void ui_window_invalidate(void *arg, gfx_rect_t *rect)
     1715{
     1716        ui_window_t *window = (ui_window_t *) arg;
     1717        gfx_rect_t env;
     1718
     1719        gfx_rect_envelope(&window->dirty_rect, rect, &env);
     1720        window->dirty_rect = env;
     1721}
     1722
     1723/** Window update callback
     1724 *
     1725 * @param arg Argument (ui_window_t *)
     1726 */
     1727static void ui_window_update(void *arg)
     1728{
     1729        ui_window_t *window = (ui_window_t *) arg;
     1730
     1731        if (!gfx_rect_is_empty(&window->dirty_rect)) {
     1732                (void) gfx_bitmap_render(window->bmp, &window->dirty_rect,
     1733                    &window->dpos);
     1734        }
     1735
     1736        window->dirty_rect.p0.x = 0;
     1737        window->dirty_rect.p0.y = 0;
     1738        window->dirty_rect.p1.x = 0;
     1739        window->dirty_rect.p1.y = 0;
     1740}
     1741
     1742/** Window cursor get position callback
     1743 *
     1744 * @param arg Argument (ui_window_t *)
     1745 * @param pos Place to store position
     1746 */
     1747static errno_t ui_window_cursor_get_pos(void *arg, gfx_coord2_t *pos)
     1748{
     1749        ui_window_t *window = (ui_window_t *) arg;
     1750        gfx_coord2_t cpos;
     1751        errno_t rc;
     1752
     1753        rc = gfx_cursor_get_pos(window->realgc, &cpos);
     1754        if (rc != EOK)
     1755                return rc;
     1756
     1757        pos->x = cpos.x - window->dpos.x;
     1758        pos->y = cpos.y - window->dpos.y;
     1759        return EOK;
     1760}
     1761
     1762/** Window cursor set position callback
     1763 *
     1764 * @param arg Argument (ui_window_t *)
     1765 * @param pos New position
     1766 */
     1767static errno_t ui_window_cursor_set_pos(void *arg, gfx_coord2_t *pos)
     1768{
     1769        ui_window_t *window = (ui_window_t *) arg;
     1770        gfx_coord2_t cpos;
     1771
     1772        cpos.x = pos->x + window->dpos.x;
     1773        cpos.y = pos->y + window->dpos.y;
     1774
     1775        return gfx_cursor_set_pos(window->realgc, &cpos);
     1776}
     1777
     1778/** Window cursor set visibility callback
     1779 *
     1780 * @param arg Argument (ui_window_t *)
     1781 * @param visible @c true iff cursor is to be made visible
     1782 */
     1783static errno_t ui_window_cursor_set_visible(void *arg, bool visible)
     1784{
     1785        ui_window_t *window = (ui_window_t *) arg;
     1786
     1787        return gfx_cursor_set_visible(window->realgc, visible);
     1788}
     1789
     1790/** Application area invalidate callback
     1791 *
     1792 * @param arg Argument (ui_window_t *)
     1793 * @param rect Rectangle to update
     1794 */
     1795static void ui_window_app_invalidate(void *arg, gfx_rect_t *rect)
    7181796{
    7191797        ui_window_t *window = (ui_window_t *) arg;
     
    7241802        /* Render bitmap rectangle inside the application area */
    7251803        (void) gfx_bitmap_render(window->app_bmp, rect, &arect.p0);
     1804        /*
     1805         * TODO Update applications to call gfx_update(), then
     1806         * we can defer update to ui_window_app_update().
     1807         */
     1808        (void) gfx_update(window->res->gc);
     1809}
     1810
     1811/** Application area update callback
     1812 *
     1813 * @param arg Argument (ui_window_t *)
     1814 */
     1815static void ui_window_app_update(void *arg)
     1816{
     1817        ui_window_t *window = (ui_window_t *) arg;
     1818
     1819        /*
     1820         * Not used since display is updated immediately
     1821         * in ui_window_app_invalidate
     1822         */
     1823        (void) window;
     1824}
     1825
     1826/** Window expose callback. */
     1827static void ui_window_expose_cb(void *arg)
     1828{
     1829        ui_window_t *window = (ui_window_t *) arg;
     1830
     1831        ui_window_paint(window);
    7261832}
    7271833
Note: See TracChangeset for help on using the changeset viewer.