Ignore:
File:
1 edited

Legend:

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

    rb979ffb r25f26600  
    11/*
    2  * Copyright (c) 2026 Jiri Svoboda
     2 * Copyright (c) 2020 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3434 */
    3535
    36 #include <congfx/console.h>
    3736#include <display.h>
    3837#include <errno.h>
    3938#include <gfx/bitmap.h>
    4039#include <gfx/context.h>
    41 #include <gfx/cursor.h>
    4240#include <gfx/render.h>
    4341#include <io/kbd_event.h>
     
    4745#include <stdlib.h>
    4846#include <ui/control.h>
    49 #include <ui/menubar.h>
    50 #include <ui/menu.h>
    51 #include <ui/menuentry.h>
    5247#include <ui/resource.h>
    53 #include <ui/ui.h>
    5448#include <ui/wdecor.h>
    5549#include <ui/window.h>
     
    6256
    6357static void dwnd_close_event(void *);
    64 static void dwnd_focus_event(void *, unsigned);
     58static void dwnd_focus_event(void *);
    6559static void dwnd_kbd_event(void *, kbd_event_t *);
    6660static void dwnd_pos_event(void *, pos_event_t *);
    6761static void dwnd_resize_event(void *, gfx_rect_t *);
    68 static void dwnd_unfocus_event(void *, unsigned);
     62static void dwnd_unfocus_event(void *);
    6963
    7064static display_wnd_cb_t dwnd_cb = {
     
    7771};
    7872
    79 static void wd_sysmenu_open(ui_wdecor_t *, void *, sysarg_t);
    80 static void wd_sysmenu_left(ui_wdecor_t *, void *, sysarg_t);
    81 static void wd_sysmenu_right(ui_wdecor_t *, void *, sysarg_t);
    82 static void wd_sysmenu_accel(ui_wdecor_t *, void *, char32_t, sysarg_t);
    83 static void wd_minimize(ui_wdecor_t *, void *);
    84 static void wd_maximize(ui_wdecor_t *, void *);
    85 static void wd_unmaximize(ui_wdecor_t *, void *);
    8673static void wd_close(ui_wdecor_t *, void *);
    87 static void wd_move(ui_wdecor_t *, void *, gfx_coord2_t *, sysarg_t);
     74static void wd_move(ui_wdecor_t *, void *, gfx_coord2_t *);
    8875static void wd_resize(ui_wdecor_t *, void *, ui_wdecor_rsztype_t,
    89     gfx_coord2_t *, sysarg_t);
     76    gfx_coord2_t *);
    9077static void wd_set_cursor(ui_wdecor_t *, void *, ui_stock_cursor_t);
    9178
    9279static 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,
    10080        .close = wd_close,
    10181        .move = wd_move,
     
    10484};
    10585
    106 static void wnd_sysmenu_left(ui_menu_t *, void *, sysarg_t);
    107 static void wnd_sysmenu_right(ui_menu_t *, void *, sysarg_t);
    108 static void wnd_sysmenu_close_req(ui_menu_t *, void *);
    109 static void wnd_sysmenu_press_accel(ui_menu_t *, void *, char32_t, sysarg_t);
    110 
    111 static ui_menu_cb_t wnd_sysmenu_cb = {
    112         .left = wnd_sysmenu_left,
    113         .right = wnd_sysmenu_right,
    114         .close_req = wnd_sysmenu_close_req,
    115         .press_accel = wnd_sysmenu_press_accel
    116 };
    117 
    118 static void wnd_sysmenu_erestore(ui_menu_entry_t *, void *);
    119 static void wnd_sysmenu_eminimize(ui_menu_entry_t *, void *);
    120 static void wnd_sysmenu_emaximize(ui_menu_entry_t *, void *);
    121 static void wnd_sysmenu_eclose(ui_menu_entry_t *, void *);
    122 
    123 static void ui_window_invalidate(void *, gfx_rect_t *);
    124 static void ui_window_update(void *);
    125 static errno_t ui_window_cursor_get_pos(void *, gfx_coord2_t *);
    126 static errno_t ui_window_cursor_set_pos(void *, gfx_coord2_t *);
    127 static errno_t ui_window_cursor_set_visible(void *, bool);
    128 
    129 /** Window memory GC callbacks */
    130 static mem_gc_cb_t ui_window_mem_gc_cb = {
    131         .invalidate = ui_window_invalidate,
    132         .update = ui_window_update,
    133         .cursor_get_pos = ui_window_cursor_get_pos,
    134         .cursor_set_pos = ui_window_cursor_set_pos,
    135         .cursor_set_visible = ui_window_cursor_set_visible
    136 };
    137 
    138 static void ui_window_app_invalidate(void *, gfx_rect_t *);
    139 static void ui_window_app_update(void *);
    140 
    141 /** Application area memory GC callbacks */
    142 static mem_gc_cb_t ui_window_app_mem_gc_cb = {
    143         .invalidate = ui_window_app_invalidate,
    144         .update = ui_window_app_update
    145 };
    146 
    147 static void ui_window_expose_cb(void *);
     86static void ui_window_app_update(void *, gfx_rect_t *);
    14887
    14988/** Initialize window parameters structure.
     
    164103}
    165104
    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 wrect Window rectangle
    174  * @param prect Parent rectangle for popup placement or @c NULL
    175  * @param placement Window placement
    176  * @param params Window parameters
    177  * @param pos Place to store position of top-left corner
    178  */
    179 static void ui_window_place(ui_window_t *window, gfx_rect_t *drect,
    180     gfx_rect_t *wrect, gfx_rect_t *prect, ui_wnd_placement_t placement,
    181     gfx_coord2_t *pos)
    182 {
    183         gfx_coord2_t dims;
    184         gfx_coord2_t below_pos;
    185         gfx_rect_t below_rect;
    186 
    187         assert(placement != ui_wnd_place_default ||
    188             ui_is_fullscreen(window->ui));
    189 
    190         pos->x = 0;
    191         pos->y = 0;
    192 
    193         switch (placement) {
    194         case ui_wnd_place_default:
    195         case ui_wnd_place_center:
    196                 assert(placement != ui_wnd_place_default ||
    197                     ui_is_fullscreen(window->ui));
    198                 /* Center window */
    199                 gfx_rect_dims(wrect, &dims);
    200                 pos->x = (drect->p0.x + drect->p1.x) / 2 - dims.x / 2;
    201                 pos->y = (drect->p0.y + drect->p1.y) / 2 - dims.y / 2;
    202                 break;
    203         case ui_wnd_place_top_left:
    204         case ui_wnd_place_full_screen:
    205                 pos->x = drect->p0.x - wrect->p0.x;
    206                 pos->y = drect->p0.y - wrect->p0.y;
    207                 break;
    208         case ui_wnd_place_top_right:
    209                 pos->x = drect->p1.x - wrect->p1.x;
    210                 pos->y = drect->p0.y - wrect->p0.y;
    211                 break;
    212         case ui_wnd_place_bottom_left:
    213                 pos->x = drect->p0.x - wrect->p0.x;
    214                 pos->y = drect->p1.y - wrect->p1.y;
    215                 break;
    216         case ui_wnd_place_bottom_right:
    217                 pos->x = drect->p1.x - wrect->p1.x;
    218                 pos->y = drect->p1.y - wrect->p1.y;
    219                 break;
    220         case ui_wnd_place_popup:
    221                 /* Compute rectangle when placed below */
    222                 below_pos.x = prect->p0.x;
    223                 below_pos.y = prect->p1.y;
    224                 gfx_rect_translate(&below_pos, wrect, &below_rect);
    225 
    226                 /* Does below_rect fit within the display? */
    227                 if (gfx_rect_is_inside(&below_rect, drect)) {
    228                         /* Place popup window below parent rectangle */
    229                         pos->x = prect->p0.x - wrect->p0.x;
    230                         pos->y = prect->p1.y - wrect->p0.y;
    231                 } else {
    232                         /* Place popup window above parent rectangle */
    233                         pos->x = prect->p0.x;
    234                         pos->y = prect->p0.y -
    235                             (wrect->p1.y - wrect->p0.y);
    236                 }
    237                 break;
    238         }
    239 }
    240 
    241 static void ui_window_set_dpos(ui_window_t *window, gfx_coord2_t *dpos)
    242 {
    243         window->dpos = *dpos;
    244         if (window->xgc != NULL)
    245                 xlate_gc_set_off(window->xgc, &window->dpos);
    246 }
    247 
    248 /** Create window's system menu.
    249  *
    250  * @param window Window
    251  * @return EOK on success or an error code
    252  */
    253 static errno_t ui_window_sysmenu_create(ui_window_t *window)
    254 {
    255         errno_t rc;
    256         ui_menu_entry_t *mrestore;
    257         ui_menu_entry_t *mmin;
    258         ui_menu_entry_t *mmax;
    259         ui_menu_entry_t *msep;
    260         ui_menu_entry_t *mclose;
    261 
    262         rc = ui_menu_create(window, &window->sysmenu);
    263         if (rc != EOK)
    264                 goto error;
    265 
    266         ui_menu_set_cb(window->sysmenu, &wnd_sysmenu_cb, (void *)window);
    267 
    268         rc = ui_menu_entry_create(window->sysmenu, "~R~estore",
    269             "", &mrestore);
    270         if (rc != EOK)
    271                 goto error;
    272 
    273         if (!window->wdecor->maximized)
    274                 ui_menu_entry_set_disabled(mrestore, true);
    275 
    276         ui_menu_entry_set_cb(mrestore, wnd_sysmenu_erestore, (void *)window);
    277 
    278         rc = ui_menu_entry_create(window->sysmenu, "Mi~n~imize",
    279             "", &mmin);
    280         if (rc != EOK)
    281                 goto error;
    282 
    283         if ((window->wdecor->style & ui_wds_minimize_btn) == 0)
    284                 ui_menu_entry_set_disabled(mmin, true);
    285 
    286         ui_menu_entry_set_cb(mmin, wnd_sysmenu_eminimize, (void *)window);
    287 
    288         rc = ui_menu_entry_create(window->sysmenu, "Ma~x~imize",
    289             "", &mmax);
    290         if (rc != EOK)
    291                 goto error;
    292 
    293         if ((window->wdecor->style & ui_wds_maximize_btn) == 0 ||
    294             window->wdecor->maximized)
    295                 ui_menu_entry_set_disabled(mmax, true);
    296 
    297         ui_menu_entry_set_cb(mmax, wnd_sysmenu_emaximize, (void *)window);
    298 
    299         rc = ui_menu_entry_sep_create(window->sysmenu, &msep);
    300         if (rc != EOK)
    301                 goto error;
    302 
    303         rc = ui_menu_entry_create(window->sysmenu, "~C~lose", "Alt-F4",
    304             &mclose);
    305         if (rc != EOK)
    306                 goto error;
    307 
    308         if ((window->wdecor->style & ui_wds_close_btn) == 0)
    309                 ui_menu_entry_set_disabled(mclose, true);
    310 
    311         ui_menu_entry_set_cb(mclose, wnd_sysmenu_eclose, (void *)window);
    312 
    313         window->sysmenu_restore = mrestore;
    314         window->sysmenu_minimize = mmin;
    315         window->sysmenu_maximize = mmax;
    316 
    317         return EOK;
    318 error:
    319         return rc;
    320 }
    321 
    322105/** Create new window.
    323106 *
     
    331114{
    332115        ui_window_t *window;
    333         ui_window_t *pwindow = NULL;
    334116        display_info_t info;
     117        gfx_coord2_t pos;
    335118        gfx_coord2_t scr_dims;
    336119        display_wnd_params_t dparams;
     120        display_window_t *dwindow = NULL;
    337121        gfx_context_t *gc = NULL;
    338122        ui_resource_t *res = NULL;
    339123        ui_wdecor_t *wdecor = NULL;
    340124        dummy_gc_t *dgc = NULL;
    341         gfx_bitmap_params_t bparams;
    342         gfx_bitmap_alloc_t alloc;
    343         gfx_bitmap_t *bmp = NULL;
    344         gfx_coord2_t off;
    345         mem_gc_t *memgc = NULL;
    346         xlate_gc_t *xgc = NULL;
    347         gfx_coord2_t dpos;
    348125        errno_t rc;
    349126
     
    352129                return ENOMEM;
    353130
    354         window->ui = ui;
    355 
    356131        display_wnd_params_init(&dparams);
    357132        dparams.rect = params->rect;
    358         dparams.caption = params->caption;
    359         dparams.min_size = params->min_size;
    360 
    361         /*
    362          * If idev_id is not specified, use the UI default (probably
    363          * obtained from display specification. This creates the
    364          * main window in the seat specified on the command line.
    365          */
    366         if (params->idev_id != 0)
    367                 dparams.idev_id = params->idev_id;
    368         else
    369                 dparams.idev_id = ui->idev_id;
    370 
    371         if ((params->flags & ui_wndf_popup) != 0)
    372                 dparams.flags |= wndf_popup;
    373         if ((params->flags & ui_wndf_nofocus) != 0)
    374                 dparams.flags |= wndf_nofocus;
    375         if ((params->flags & ui_wndf_topmost) != 0)
    376                 dparams.flags |= wndf_topmost;
    377         if ((params->flags & ui_wndf_system) != 0)
    378                 dparams.flags |= wndf_system;
    379         if ((params->flags & ui_wndf_avoid) != 0)
    380                 dparams.flags |= wndf_avoid;
     133        /* Only allow making the window larger */
     134        gfx_rect_dims(&params->rect, &dparams.min_size);
    381135
    382136        if (ui->display != NULL) {
     
    394148                }
    395149
    396                 if (params->placement != ui_wnd_place_default) {
    397                         /* Set initial display window position */
    398                         ui_window_place(window, &info.rect, &params->rect,
    399                             &params->prect, params->placement, &dparams.pos);
    400 
    401                         dparams.flags |= wndf_setpos;
    402                 }
    403 
    404150                rc = display_window_create(ui->display, &dparams, &dwnd_cb,
    405                     (void *) window, &window->dwindow);
     151                    (void *) window, &dwindow);
    406152                if (rc != EOK)
    407153                        goto error;
    408154
    409                 rc = display_window_get_gc(window->dwindow, &gc);
     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);
    410187                if (rc != EOK)
    411188                        goto error;
    412         } else if (ui->console != NULL) {
    413                 gc = console_gc_get_ctx(ui->cgc);
    414 
    415                 if (params->placement == ui_wnd_place_full_screen) {
    416                         /* Make window the size of the screen */
    417                         gfx_rect_dims(&ui->rect, &scr_dims);
    418                         gfx_coord2_add(&dparams.rect.p0, &scr_dims,
    419                             &dparams.rect.p1);
    420                         (void) console_set_caption(ui->console,
    421                             params->caption);
    422                 }
    423189        } else {
    424190                /* Needed for unit tests */
     
    430196        }
    431197
    432 #ifdef CONFIG_UI_CS_RENDER
    433         /* Create window bitmap */
    434         gfx_bitmap_params_init(&bparams);
    435 #ifndef CONFIG_WIN_DOUBLE_BUF
    436         /* Console does not support direct output */
    437         if (ui->display != NULL)
    438                 bparams.flags |= bmpf_direct_output;
    439 #endif
    440 
    441         /* Move rectangle so that top-left corner is 0,0 */
    442         gfx_rect_rtranslate(&dparams.rect.p0, &dparams.rect, &bparams.rect);
    443 
    444         rc = gfx_bitmap_create(gc, &bparams, NULL, &bmp);
    445         if (rc != EOK)
    446                 goto error;
    447 
    448         /* Create memory GC */
    449         rc = gfx_bitmap_get_alloc(bmp, &alloc);
    450         if (rc != EOK) {
    451                 gfx_bitmap_destroy(window->app_bmp);
    452                 return rc;
    453         }
    454 
    455         rc = mem_gc_create(&bparams.rect, &alloc, &ui_window_mem_gc_cb,
    456             (void *) window, &memgc);
    457         if (rc != EOK) {
    458                 gfx_bitmap_destroy(window->app_bmp);
    459                 return rc;
    460         }
    461 
    462         window->bmp = bmp;
    463         window->mgc = memgc;
    464         window->gc = mem_gc_get_ctx(memgc);
    465         window->realgc = gc;
    466         (void) off;
    467 #else
    468         /* Server-side rendering */
    469 
    470         /* Full-screen mode? */
    471         if (ui->display == NULL) {
    472                 /* Create translating GC to translate window contents */
    473                 off.x = 0;
    474                 off.y = 0;
    475                 rc = xlate_gc_create(&off, gc, &xgc);
    476                 if (rc != EOK)
    477                         goto error;
    478 
    479                 window->xgc = xgc;
    480                 window->gc = xlate_gc_get_ctx(xgc);
    481                 window->realgc = gc;
    482         } else {
    483                 window->gc = gc;
    484         }
    485 
    486         (void) ui_window_mem_gc_cb;
    487         (void) alloc;
    488         (void) bparams;
    489 #endif
    490         if (ui->display == NULL) {
    491                 ui_window_place(window, &ui->rect, &params->rect, &params->prect,
    492                     params->placement, &dpos);
    493                 ui_window_set_dpos(window, &dpos);
    494         }
    495 
    496         rc = ui_resource_create(window->gc, ui_is_textmode(ui), &res);
     198        rc = ui_resource_create(gc, &res);
    497199        if (rc != EOK)
    498200                goto error;
     
    506208        ui_wdecor_paint(wdecor);
    507209
    508         ui_resource_set_expose_cb(res, ui_window_expose_cb, (void *) window);
    509 
     210        window->ui = ui;
     211        window->dwindow = dwindow;
    510212        window->rect = dparams.rect;
     213        window->gc = gc;
    511214        window->res = res;
    512215        window->wdecor = wdecor;
    513216        window->cursor = ui_curs_arrow;
    514         window->placement = params->placement;
    515 
    516         rc = ui_window_sysmenu_create(window);
    517         if (rc != EOK)
    518                 goto error;
    519 
    520217        *rwindow = window;
    521 
    522         if (ui_is_fullscreen(ui))
    523                 pwindow = ui_window_get_active(ui);
    524 
    525         list_append(&window->lwindows, &ui->windows);
    526 
    527         if (ui_is_fullscreen(ui)) {
    528                 /* Send unfocus event to previously active window */
    529                 if (pwindow != NULL)
    530                         ui_window_send_unfocus(pwindow, 0);
    531         }
    532 
    533218        return EOK;
    534219error:
     
    537222        if (res != NULL)
    538223                ui_resource_destroy(res);
    539         if (memgc != NULL)
    540                 mem_gc_delete(memgc);
    541         if (xgc != NULL)
    542                 xlate_gc_delete(xgc);
    543         if (bmp != NULL)
    544                 gfx_bitmap_destroy(bmp);
    545224        if (dgc != NULL)
    546225                dummygc_destroy(dgc);
     226        if (dwindow != NULL)
     227                display_window_destroy(dwindow);
    547228        free(window);
    548229        return rc;
    549230}
    550231
    551 /** Update window placement after screen resize (only in fullscreen UI).
    552  *
    553  * @param window UI window
    554  */
    555 void ui_window_update_placement(ui_window_t *window)
    556 {
    557         if (window->placement == ui_wnd_place_full_screen ||
    558             (window->flags & uiwf_maximized) != 0) {
    559                 /* Update size of fullscreen or maximized window. */
    560                 (void)ui_window_resize(window, &window->ui->rect);
    561                 ui_window_send_resize(window);
    562         }
    563 }
    564 
    565232/** Destroy window.
    566233 *
     
    569236void ui_window_destroy(ui_window_t *window)
    570237{
    571         ui_t *ui;
    572         ui_window_t *nwindow;
    573 
    574238        if (window == NULL)
    575239                return;
    576240
    577         ui = window->ui;
    578 
    579         list_remove(&window->lwindows);
    580241        ui_control_destroy(window->control);
    581         ui_menu_destroy(window->sysmenu);
    582242        ui_wdecor_destroy(window->wdecor);
    583243        ui_resource_destroy(window->res);
    584         if (window->app_mgc != NULL)
    585                 mem_gc_delete(window->app_mgc);
    586         if (window->app_bmp != NULL)
    587                 gfx_bitmap_destroy(window->app_bmp);
    588         if (window->mgc != NULL) {
    589                 mem_gc_delete(window->mgc);
    590                 window->gc = NULL;
    591         }
    592         if (window->bmp != NULL)
    593                 gfx_bitmap_destroy(window->bmp);
    594         if (window->dwindow != NULL)
    595                 display_window_destroy(window->dwindow);
    596 
    597         /* Need to repaint if windows are emulated */
    598         if (ui_is_fullscreen(ui)) {
    599                 (void)ui_paint(ui);
    600                 /* Send focus event to newly active window */
    601                 nwindow = ui_window_get_active(ui);
    602                 if (nwindow != NULL)
    603                         ui_window_send_focus(nwindow, 0);
    604         }
    605 
    606         if (ui->console != NULL &&
    607             window->placement == ui_wnd_place_full_screen) {
    608                 (void) console_set_caption(ui->console, "");
    609         }
    610 
     244        gfx_context_delete(window->gc);
     245        display_window_destroy(window->dwindow);
    611246        free(window);
    612247}
     
    617252 * is added, the results are undefined.
    618253 *
    619  * @param window Window
     254 * @param fixed Fixed layout
    620255 * @param control Control
     256 * @return EOK on success, ENOMEM if out of memory
    621257 */
    622258void ui_window_add(ui_window_t *window, ui_control_t *control)
     
    642278}
    643279
    644 /** Get first (lowermost) window (only valid in fullscreen mode).
    645  *
    646  * @param ui User interface
    647  * @return First window
    648  */
    649 ui_window_t *ui_window_first(ui_t *ui)
    650 {
    651         link_t *link;
    652 
    653         link = list_first(&ui->windows);
    654         if (link == NULL)
    655                 return NULL;
    656 
    657         return list_get_instance(link, ui_window_t, lwindows);
    658 }
    659 
    660 /** Get next window (only valid in fullscreen mode).
    661  *
    662  * @param cur Current window
    663  * @return First window
    664  */
    665 ui_window_t *ui_window_next(ui_window_t *cur)
    666 {
    667         link_t *link;
    668 
    669         link = list_next(&cur->lwindows, &cur->ui->windows);
    670         if (link == NULL)
    671                 return NULL;
    672 
    673         return list_get_instance(link, ui_window_t, lwindows);
    674 }
    675 
    676 /** Get active window (only valid in fullscreen mode).
    677  *
    678  * @param ui User interface
    679  * @return Active window
    680  */
    681 ui_window_t *ui_window_get_active(ui_t *ui)
    682 {
    683         link_t *link;
    684 
    685         link = list_last(&ui->windows);
    686         if (link == NULL)
    687                 return NULL;
    688 
    689         return list_get_instance(link, ui_window_t, lwindows);
    690 }
    691 
    692 /** Resize or (un)maximize window.
     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.
    693284 *
    694285 * @param window Window
    695286 * @param rect Rectangle
    696  * @param scop Size change operation
    697287 *
    698288 * @return EOK on success or an error code
    699289 */
    700 errno_t ui_window_size_change(ui_window_t *window, gfx_rect_t *rect,
    701     ui_wnd_sc_op_t scop)
     290errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
    702291{
    703292        gfx_coord2_t offs;
     
    705294        gfx_rect_t arect;
    706295        gfx_bitmap_t *app_bmp = NULL;
    707         gfx_bitmap_t *win_bmp = NULL;
    708         gfx_bitmap_params_t app_params;
    709         gfx_bitmap_params_t win_params;
    710         gfx_bitmap_alloc_t app_alloc;
    711         gfx_bitmap_alloc_t win_alloc;
    712         gfx_coord2_t dpos;
     296        gfx_bitmap_params_t params;
     297        gfx_bitmap_alloc_t alloc;
    713298        errno_t rc;
    714299
     
    720305        gfx_rect_rtranslate(&offs, rect, &nrect);
    721306
    722         /* mgc != NULL iff client-side rendering */
    723         if (window->mgc != NULL) {
    724 #ifdef CONFIG_WIN_DOUBLE_BUF
    725                 /*
    726                  * Create new window bitmap in advance. If direct mapping,
    727                  * will need do it after resizing the window.
    728                  */
    729                 assert(window->bmp != NULL);
    730                 gfx_bitmap_params_init(&win_params);
    731                 win_params.rect = nrect;
    732 
    733                 rc = gfx_bitmap_create(window->realgc, &win_params, NULL,
    734                     &win_bmp);
    735                 if (rc != EOK)
    736                         goto error;
    737 
    738                 rc = gfx_bitmap_get_alloc(win_bmp, &win_alloc);
    739                 if (rc != EOK)
    740                         goto error;
    741 #endif
    742         }
    743 
    744         /* Application area GC? */
    745307        if (window->app_gc != NULL) {
    746                 /* Resize application bitmap */
    747308                assert(window->app_bmp != NULL);
    748309
    749                 gfx_bitmap_params_init(&app_params);
     310                gfx_bitmap_params_init(&params);
    750311
    751312                /*
     
    754315                 */
    755316                ui_wdecor_app_from_rect(window->wdecor->style, &nrect, &arect);
    756                 gfx_rect_rtranslate(&arect.p0, &arect, &app_params.rect);
    757 
    758                 rc = gfx_bitmap_create(window->gc, &app_params, NULL,
     317                gfx_rect_rtranslate(&arect.p0, &arect, &params.rect);
     318
     319                rc = gfx_bitmap_create(window->gc, &params, NULL,
    759320                    &app_bmp);
    760321                if (rc != EOK)
    761322                        goto error;
    762323
    763                 rc = gfx_bitmap_get_alloc(app_bmp, &app_alloc);
     324                rc = gfx_bitmap_get_alloc(app_bmp, &alloc);
    764325                if (rc != EOK)
    765326                        goto error;
    766327        }
    767328
    768         /* dwindow can be NULL in case of unit tests or fullscreen mode */
     329        /* dwindow can be NULL in case of unit tests */
    769330        if (window->dwindow != NULL) {
    770                 switch (scop) {
    771                 case ui_wsc_resize:
    772                         rc = display_window_resize(window->dwindow, &offs,
    773                             &nrect);
    774                         if (rc != EOK)
    775                                 goto error;
    776                         break;
    777                 case ui_wsc_maximize:
    778                         rc = display_window_maximize(window->dwindow);
    779                         if (rc != EOK)
    780                                 goto error;
    781                         break;
    782                 case ui_wsc_unmaximize:
    783                         rc = display_window_unmaximize(window->dwindow);
    784                         if (rc != EOK)
    785                                 goto error;
    786                         break;
    787                 }
    788         } else {
    789                 /* fullscreen mode or unit tests */
    790                 switch (scop) {
    791                 case ui_wsc_resize:
    792                         break;
    793                 case ui_wsc_maximize:
    794                         window->normal_dpos = window->dpos;
    795                         dpos.x = 0;
    796                         dpos.y = 0;
    797                         ui_window_set_dpos(window, &dpos);
    798                         break;
    799                 case ui_wsc_unmaximize:
    800                         ui_window_set_dpos(window, &window->normal_dpos);
    801                         break;
    802                 }
    803         }
    804 
    805         /* Client side rendering? */
    806         if (window->mgc != NULL) {
    807 #ifndef CONFIG_WIN_DOUBLE_BUF
    808                 /* Window is resized, now we can map the window bitmap again */
    809                 gfx_bitmap_params_init(&win_params);
    810                 if (window->ui->display != NULL)
    811                         win_params.flags |= bmpf_direct_output;
    812                 win_params.rect = nrect;
    813 
    814                 rc = gfx_bitmap_create(window->realgc, &win_params, NULL,
    815                     &win_bmp);
     331                rc = display_window_resize(window->dwindow, &offs, &nrect);
    816332                if (rc != EOK)
    817333                        goto error;
    818 
    819                 rc = gfx_bitmap_get_alloc(win_bmp, &win_alloc);
    820                 if (rc != EOK)
    821                         goto error;
    822 #endif
    823                 mem_gc_retarget(window->mgc, &win_params.rect, &win_alloc);
    824 
    825                 gfx_bitmap_destroy(window->bmp);
    826                 window->bmp = win_bmp;
    827334        }
    828335
    829         window->rect = nrect;
    830336        ui_wdecor_set_rect(window->wdecor, &nrect);
    831337        ui_wdecor_paint(window->wdecor);
    832         gfx_update(window->gc);
    833 
    834         /* Application area GC? */
     338
    835339        if (window->app_gc != NULL) {
    836                 mem_gc_retarget(window->app_mgc, &app_params.rect, &app_alloc);
     340                mem_gc_retarget(window->app_mgc, &params.rect, &alloc);
    837341
    838342                gfx_bitmap_destroy(window->app_bmp);
    839343                window->app_bmp = app_bmp;
    840         }
    841 
    842         switch (scop) {
    843         case ui_wsc_resize:
    844                 break;
    845         case ui_wsc_maximize:
    846                 window->flags |= uiwf_maximized;
    847                 break;
    848         case ui_wsc_unmaximize:
    849                 window->flags &= ~uiwf_maximized;
    850                 break;
    851344        }
    852345
     
    855348        if (app_bmp != NULL)
    856349                gfx_bitmap_destroy(app_bmp);
    857         if (win_bmp != NULL)
    858                 gfx_bitmap_destroy(win_bmp);
    859350        return rc;
    860351}
    861352
    862 /** Resize/move window.
    863  *
    864  * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
    865  * the top-left corner of the window will move on the screen accordingly.
    866  *
    867  * @param window Window
    868  * @param rect Rectangle
    869  *
    870  * @return EOK on success or an error code
    871  */
    872 errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
    873 {
    874         errno_t rc;
    875 
    876         rc = ui_window_size_change(window, rect, ui_wsc_resize);
    877         if (rc != EOK)
    878                 return rc;
    879 
    880         /* Need to repaint UI if windows are emulated */
    881         if (ui_is_fullscreen(window->ui))
    882                 (void)ui_paint(window->ui);
    883 
    884         return EOK;
    885 }
    886 
    887353/** Set window callbacks.
    888354 *
    889355 * @param window Window
    890  * @param cb Window callbacks
     356 * @param cb Window decoration callbacks
    891357 * @param arg Callback argument
    892358 */
     
    897363}
    898364
    899 /** Change window caption.
    900  *
    901  * @param window Window
    902  * @param caption New caption
    903  *
    904  * @return EOK on success or an error code
    905  */
    906 errno_t ui_window_set_caption(ui_window_t *window, const char *caption)
    907 {
    908         errno_t rc;
    909 
    910         /* Set console caption if fullscreen window on console */
    911         if (window->ui->console != NULL && window->placement ==
    912             ui_wnd_place_full_screen) {
    913                 rc = console_set_caption(window->ui->console, caption);
    914                 if (rc != EOK)
    915                         return rc;
    916         }
    917 
    918         /* Set display window caption if running on display service */
    919         if (window->dwindow != NULL) {
    920                 rc = display_window_set_caption(window->dwindow, caption);
    921                 if (rc != EOK)
    922                         return rc;
    923         }
    924 
    925         return ui_wdecor_set_caption(window->wdecor, caption);
    926 }
    927 
    928 /** Get window's containing UI.
    929  *
    930  * @param window Window
    931  * @return Containing UI
    932  */
    933 ui_t *ui_window_get_ui(ui_window_t *window)
    934 {
    935         return window->ui;
    936 }
    937 
    938365/** Get UI resource from window.
    939366 *
     
    954381{
    955382        return window->gc;
    956 }
    957 
    958 /** Get window position.
    959  *
    960  * @param window Window
    961  * @param pos Place to store position
    962  * @return EOK on success or an error code
    963  */
    964 errno_t ui_window_get_pos(ui_window_t *window, gfx_coord2_t *pos)
    965 {
    966         errno_t rc;
    967 
    968         if (window->dwindow != NULL) {
    969                 rc = display_window_get_pos(window->dwindow, pos);
    970                 if (rc != EOK)
    971                         return rc;
    972         } else {
    973                 *pos = window->dpos;
    974         }
    975 
    976         return EOK;
    977383}
    978384
     
    1014420                }
    1015421
    1016                 rc = mem_gc_create(&params.rect, &alloc,
    1017                     &ui_window_app_mem_gc_cb, (void *) window, &memgc);
     422                rc = mem_gc_create(&params.rect, &alloc, ui_window_app_update,
     423                    (void *) window, &memgc);
    1018424                if (rc != EOK) {
    1019425                        gfx_bitmap_destroy(window->app_bmp);
     
    1042448}
    1043449
    1044 /** Set cursor when pointer is hovering over a control.
    1045  *
    1046  * @param window Window
    1047  * @param cursor Cursor
    1048  */
    1049 void ui_window_set_ctl_cursor(ui_window_t *window, ui_stock_cursor_t cursor)
    1050 {
    1051         display_stock_cursor_t dcursor;
    1052 
    1053         dcursor = wnd_dcursor_from_cursor(cursor);
    1054 
    1055         if (window->dwindow != NULL)
    1056                 (void) display_window_set_cursor(window->dwindow, dcursor);
    1057 }
    1058 
    1059450/** Paint window
    1060451 *
     
    1071462{
    1072463        ui_window_t *window = (ui_window_t *) arg;
    1073         ui_t *ui = window->ui;
    1074 
    1075         fibril_mutex_lock(&ui->lock);
     464
    1076465        ui_window_send_close(window);
    1077         fibril_mutex_unlock(&ui->lock);
    1078466}
    1079467
    1080468/** Handle window focus event. */
    1081 static void dwnd_focus_event(void *arg, unsigned nfocus)
    1082 {
    1083         ui_window_t *window = (ui_window_t *) arg;
    1084         ui_t *ui = window->ui;
    1085 
    1086         fibril_mutex_lock(&ui->lock);
    1087         (void)nfocus;
     469static void dwnd_focus_event(void *arg)
     470{
     471        ui_window_t *window = (ui_window_t *) arg;
    1088472
    1089473        if (window->wdecor != NULL) {
     
    1092476        }
    1093477
    1094         ui_window_send_focus(window, nfocus);
    1095         fibril_mutex_unlock(&ui->lock);
     478        ui_window_send_focus(window);
    1096479}
    1097480
     
    1100483{
    1101484        ui_window_t *window = (ui_window_t *) arg;
    1102         ui_t *ui = window->ui;
    1103 
    1104         fibril_mutex_lock(&ui->lock);
     485
     486        (void) window;
    1105487        ui_window_send_kbd(window, kbd_event);
    1106         fibril_mutex_unlock(&ui->lock);
    1107488}
    1108489
     
    1111492{
    1112493        ui_window_t *window = (ui_window_t *) arg;
    1113         ui_t *ui = window->ui;
    1114         ui_evclaim_t claim;
    1115494
    1116495        /* Make sure we don't process events until fully initialized */
     
    1118497                return;
    1119498
    1120         fibril_mutex_lock(&ui->lock);
    1121 
    1122         claim = ui_wdecor_pos_event(window->wdecor, event);
    1123         if (claim == ui_claimed) {
    1124                 fibril_mutex_unlock(&ui->lock);
    1125                 return;
    1126         }
    1127 
     499        ui_wdecor_pos_event(window->wdecor, event);
    1128500        ui_window_send_pos(window, event);
    1129         fibril_mutex_unlock(&ui->lock);
    1130501}
    1131502
     
    1134505{
    1135506        ui_window_t *window = (ui_window_t *) arg;
    1136         ui_t *ui = window->ui;
    1137507
    1138508        /* Make sure we don't process events until fully initialized */
     
    1143513                return;
    1144514
    1145         fibril_mutex_lock(&ui->lock);
    1146515        (void) ui_window_resize(window, rect);
    1147         ui_window_send_resize(window);
    1148         fibril_mutex_unlock(&ui->lock);
     516        (void) ui_window_paint(window);
    1149517}
    1150518
    1151519/** Handle window unfocus event. */
    1152 static void dwnd_unfocus_event(void *arg, unsigned nfocus)
    1153 {
    1154         ui_window_t *window = (ui_window_t *) arg;
    1155         ui_t *ui = window->ui;
    1156 
    1157         fibril_mutex_lock(&ui->lock);
    1158 
    1159         if (window->wdecor != NULL && nfocus == 0) {
     520static void dwnd_unfocus_event(void *arg)
     521{
     522        ui_window_t *window = (ui_window_t *) arg;
     523
     524        if (window->wdecor != NULL) {
    1160525                ui_wdecor_set_active(window->wdecor, false);
    1161526                ui_wdecor_paint(window->wdecor);
    1162527        }
    1163528
    1164         ui_window_send_unfocus(window, nfocus);
    1165         fibril_mutex_unlock(&ui->lock);
    1166 }
    1167 
    1168 /** Window decoration requested opening of system menu.
    1169  *
    1170  * @param wdecor Window decoration
    1171  * @param arg Argument (window)
    1172  * @param idev_id Input device ID
    1173  */
    1174 static void wd_sysmenu_open(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
    1175 {
    1176         ui_window_t *window = (ui_window_t *) arg;
    1177 
    1178         ui_window_send_sysmenu(window, idev_id);
    1179 }
    1180 
    1181 /** Window decoration requested moving left from system menu handle.
    1182  *
    1183  * @param wdecor Window decoration
    1184  * @param arg Argument (window)
    1185  * @param idev_id Input device ID
    1186  */
    1187 static void wd_sysmenu_left(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
    1188 {
    1189         ui_window_t *window = (ui_window_t *) arg;
    1190 
    1191         if (window->mbar != NULL) {
    1192                 ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
    1193                 ui_menu_close(window->sysmenu);
    1194                 ui_menu_bar_select_last(window->mbar, false, idev_id);
    1195         }
    1196 }
    1197 
    1198 /** Window decoration requested moving right from system menu handle.
    1199  *
    1200  * @param wdecor Window decoration
    1201  * @param arg Argument (window)
    1202  * @param idev_id Input device ID
    1203  */
    1204 static void wd_sysmenu_right(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
    1205 {
    1206         ui_window_t *window = (ui_window_t *) arg;
    1207 
    1208         if (window->mbar != NULL) {
    1209                 ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
    1210                 ui_menu_close(window->sysmenu);
    1211                 ui_menu_bar_select_first(window->mbar, false, idev_id);
    1212         }
    1213 }
    1214 
    1215 /** Window decoration detected accelerator press from system menu handle.
    1216  *
    1217  * @param wdecor Window decoration
    1218  * @param arg Argument (window)
    1219  * @param c Accelerator key
    1220  * @param idev_id Input device ID
    1221  */
    1222 static void wd_sysmenu_accel(ui_wdecor_t *wdecor, void *arg, char32_t c,
    1223     sysarg_t idev_id)
    1224 {
    1225         ui_window_t *window = (ui_window_t *) arg;
    1226 
    1227         if (window->mbar != NULL) {
    1228                 ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
    1229                 ui_menu_close(window->sysmenu);
    1230                 ui_menu_bar_press_accel(window->mbar, c, idev_id);
    1231         }
    1232 }
    1233 
    1234 /** Window decoration requested window minimization.
    1235  *
    1236  * @param wdecor Window decoration
    1237  * @param arg Argument (window)
    1238  */
    1239 static void wd_minimize(ui_wdecor_t *wdecor, void *arg)
    1240 {
    1241         ui_window_t *window = (ui_window_t *) arg;
    1242 
    1243         ui_window_send_minimize(window);
    1244 }
    1245 
    1246 /** Window decoration requested window maximization.
    1247  *
    1248  * @param wdecor Window decoration
    1249  * @param arg Argument (window)
    1250  */
    1251 static void wd_maximize(ui_wdecor_t *wdecor, void *arg)
    1252 {
    1253         ui_window_t *window = (ui_window_t *) arg;
    1254 
    1255         ui_window_send_maximize(window);
    1256 }
    1257 
    1258 /** Window decoration requested window unmaximization.
    1259  *
    1260  * @param wdecor Window decoration
    1261  * @param arg Argument (window)
    1262  */
    1263 static void wd_unmaximize(ui_wdecor_t *wdecor, void *arg)
    1264 {
    1265         ui_window_t *window = (ui_window_t *) arg;
    1266 
    1267         ui_window_send_unmaximize(window);
     529        ui_window_send_unfocus(window);
    1268530}
    1269531
     
    1285547 * @param arg Argument (window)
    1286548 * @param pos Position where the title bar was pressed
    1287  * @param pos_id Positioning device ID
    1288  */
    1289 static void wd_move(ui_wdecor_t *wdecor, void *arg, gfx_coord2_t *pos,
    1290     sysarg_t pos_id)
    1291 {
    1292         ui_window_t *window = (ui_window_t *) arg;
    1293 
    1294         if (window->dwindow != NULL)
    1295                 (void) display_window_move_req(window->dwindow, pos, pos_id);
     549 */
     550static 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);
    1296555}
    1297556
     
    1302561 * @param rsztype Resize type
    1303562 * @param pos Position where the button was pressed
    1304  * @param pos_id Positioning device ID
    1305563 */
    1306564static void wd_resize(ui_wdecor_t *wdecor, void *arg,
    1307     ui_wdecor_rsztype_t rsztype, gfx_coord2_t *pos, sysarg_t pos_id)
    1308 {
    1309         ui_window_t *window = (ui_window_t *) arg;
    1310 
    1311         if (window->dwindow != NULL) {
    1312                 (void) display_window_resize_req(window->dwindow,
    1313                     (display_wnd_rsztype_t) rsztype, // Same constants in the enums
    1314                     pos, pos_id);
    1315         }
    1316 }
    1317 
    1318 /** Get display stock cursor from UI stock cursor.
    1319  *
    1320  * @param cursor UI stock cursor
    1321  * @return Display stock cursor
    1322  */
    1323 display_stock_cursor_t wnd_dcursor_from_cursor(ui_stock_cursor_t cursor)
    1324 {
     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 */
     578static 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;
    1325582        display_stock_cursor_t dcursor;
     583
     584        if (cursor == window->cursor)
     585                return;
    1326586
    1327587        dcursor = dcurs_arrow;
     
    1343603                dcursor = dcurs_size_urdl;
    1344604                break;
    1345         case ui_curs_ibeam:
    1346                 dcursor = dcurs_ibeam;
    1347                 break;
    1348605        }
    1349606
    1350         return dcursor;
    1351 }
    1352 
    1353 /** Window decoration requested changing cursor.
    1354  *
    1355  * @param wdecor Window decoration
    1356  * @param arg Argument (window)
    1357  * @param cursor Cursor to set
    1358  */
    1359 static void wd_set_cursor(ui_wdecor_t *wdecor, void *arg,
    1360     ui_stock_cursor_t cursor)
    1361 {
    1362         ui_window_t *window = (ui_window_t *) arg;
    1363         display_stock_cursor_t dcursor;
    1364 
    1365         if (cursor == window->cursor)
    1366                 return;
    1367 
    1368         dcursor = wnd_dcursor_from_cursor(cursor);
    1369 
    1370         if (window->dwindow != NULL)
    1371                 (void) display_window_set_cursor(window->dwindow, dcursor);
    1372 
     607        (void) display_window_set_cursor(window->dwindow, dcursor);
    1373608        window->cursor = cursor;
    1374 }
    1375 
    1376 /** Send window sysmenu event.
    1377  *
    1378  * @param window Window
    1379  * @parma idev_id Input device ID
    1380  */
    1381 void ui_window_send_sysmenu(ui_window_t *window, sysarg_t idev_id)
    1382 {
    1383         if (window->cb != NULL && window->cb->sysmenu != NULL)
    1384                 window->cb->sysmenu(window, window->arg, idev_id);
    1385         else
    1386                 ui_window_def_sysmenu(window, idev_id);
    1387 }
    1388 
    1389 /** Send window minimize event.
    1390  *
    1391  * @param window Window
    1392  */
    1393 void ui_window_send_minimize(ui_window_t *window)
    1394 {
    1395         if (window->cb != NULL && window->cb->minimize != NULL)
    1396                 window->cb->minimize(window, window->arg);
    1397         else
    1398                 ui_window_def_minimize(window);
    1399 }
    1400 
    1401 /** Send window maximize event.
    1402  *
    1403  * @param window Window
    1404  */
    1405 void ui_window_send_maximize(ui_window_t *window)
    1406 {
    1407         if (window->cb != NULL && window->cb->maximize != NULL)
    1408                 window->cb->maximize(window, window->arg);
    1409         else
    1410                 ui_window_def_maximize(window);
    1411 }
    1412 
    1413 /** Send window unmaximize event.
    1414  *
    1415  * @param window Window
    1416  */
    1417 void ui_window_send_unmaximize(ui_window_t *window)
    1418 {
    1419         if (window->cb != NULL && window->cb->unmaximize != NULL)
    1420                 window->cb->unmaximize(window, window->arg);
    1421         else
    1422                 ui_window_def_unmaximize(window);
    1423609}
    1424610
     
    1436622 *
    1437623 * @param window Window
    1438  * @param nfocus New number of foci
    1439  */
    1440 void ui_window_send_focus(ui_window_t *window, unsigned nfocus)
     624 */
     625void ui_window_send_focus(ui_window_t *window)
    1441626{
    1442627        if (window->cb != NULL && window->cb->focus != NULL)
    1443                 window->cb->focus(window, window->arg, nfocus);
     628                window->cb->focus(window, window->arg);
    1444629}
    1445630
     
    1452637        if (window->cb != NULL && window->cb->kbd != NULL)
    1453638                window->cb->kbd(window, window->arg, kbd);
    1454         else
    1455                 ui_window_def_kbd(window, kbd);
    1456639}
    1457640
     
    1483666 *
    1484667 * @param window Window
    1485  * @param nfocus Number of remaining foci
    1486  */
    1487 void ui_window_send_unfocus(ui_window_t *window, unsigned nfocus)
     668 */
     669void ui_window_send_unfocus(ui_window_t *window)
    1488670{
    1489671        if (window->cb != NULL && window->cb->unfocus != NULL)
    1490                 window->cb->unfocus(window, window->arg, nfocus);
    1491         else
    1492                 return ui_window_def_unfocus(window, nfocus);
    1493 }
    1494 
    1495 /** Send window resize event.
    1496  *
    1497  * @param window Window
    1498  */
    1499 void ui_window_send_resize(ui_window_t *window)
    1500 {
    1501         if (window->cb != NULL && window->cb->resize != NULL)
    1502                 window->cb->resize(window, window->arg);
    1503         else
    1504                 return ui_window_def_resize(window);
    1505 }
    1506 
    1507 /** Default window sysmenu routine.
    1508  *
    1509  * @param window Window
    1510  * @param idev_id Input device ID
    1511  * @return EOK on success or an error code
    1512  */
    1513 errno_t ui_window_def_sysmenu(ui_window_t *window, sysarg_t idev_id)
    1514 {
    1515         errno_t rc;
    1516         ui_wdecor_geom_t geom;
    1517 
    1518         if (ui_menu_is_open(window->sysmenu)) {
    1519                 ui_menu_close(window->sysmenu);
    1520         } else {
    1521                 ui_wdecor_get_geom(window->wdecor, &geom);
    1522 
    1523                 rc = ui_menu_open(window->sysmenu, &geom.title_bar_rect,
    1524                     idev_id);
    1525                 if (rc != EOK)
    1526                         goto error;
    1527         }
    1528 
    1529         return EOK;
    1530 error:
    1531         return rc;
    1532 }
    1533 
    1534 /** Default window minimize routine.
    1535  *
    1536  * @param window Window
    1537  * @return EOK on success or an error code
    1538  */
    1539 errno_t ui_window_def_minimize(ui_window_t *window)
    1540 {
    1541         errno_t rc;
    1542 
    1543         if (window->dwindow != NULL) {
    1544                 rc = display_window_minimize(window->dwindow);
    1545                 if (rc != EOK)
    1546                         goto error;
    1547         }
    1548 
    1549         return EOK;
    1550 error:
    1551         return rc;
    1552 }
    1553 
    1554 /** Default window maximize routine.
    1555  *
    1556  * @param window Window
    1557  * @return EOK on success or an error code
    1558  */
    1559 errno_t ui_window_def_maximize(ui_window_t *window)
    1560 {
    1561         errno_t rc;
    1562         gfx_rect_t old_rect;
    1563         gfx_rect_t rect;
    1564 
    1565         old_rect = window->rect;
    1566 
    1567         if (window->dwindow != NULL) {
    1568                 rc = display_window_get_max_rect(window->dwindow, &rect);
    1569                 if (rc != EOK)
    1570                         return rc;
    1571         } else {
    1572                 rect = window->ui->rect;
    1573         }
    1574 
    1575         ui_wdecor_set_maximized(window->wdecor, true);
    1576         ui_menu_entry_set_disabled(window->sysmenu_restore, false);
    1577         ui_menu_entry_set_disabled(window->sysmenu_maximize, true);
    1578 
    1579         rc = ui_window_size_change(window, &rect, ui_wsc_maximize);
    1580         if (rc != EOK) {
    1581                 ui_wdecor_set_maximized(window->wdecor, false);
    1582                 return rc;
    1583         }
    1584 
    1585         window->normal_rect = old_rect;
    1586         ui_window_send_resize(window);
    1587 
    1588         /* Need to repaint UI if windows are emulated */
    1589         if (ui_is_fullscreen(window->ui))
    1590                 (void)ui_paint(window->ui);
    1591 
    1592         return EOK;
    1593 }
    1594 
    1595 /** Default window unmaximize routine.
    1596  *
    1597  * @param window Window
    1598  * @return EOK on success or an error code
    1599  */
    1600 errno_t ui_window_def_unmaximize(ui_window_t *window)
    1601 {
    1602         errno_t rc;
    1603 
    1604         ui_wdecor_set_maximized(window->wdecor, false);
    1605         ui_menu_entry_set_disabled(window->sysmenu_restore, true);
    1606         ui_menu_entry_set_disabled(window->sysmenu_maximize, false);
    1607 
    1608         rc = ui_window_size_change(window, &window->normal_rect,
    1609             ui_wsc_unmaximize);
    1610         if (rc != EOK) {
    1611                 ui_wdecor_set_maximized(window->wdecor, true);
    1612                 printf("ui_window_size_change->error\n");
    1613                 return rc;
    1614         }
    1615 
    1616         ui_window_send_resize(window);
    1617 
    1618         /* Need to repaint UI if windows are emulated */
    1619         if (ui_is_fullscreen(window->ui))
    1620                 (void)ui_paint(window->ui);
    1621 
    1622         return EOK;
    1623 }
    1624 
    1625 /** Default window keyboard event routine.
    1626  *
    1627  * @param window Window
    1628  * @return ui_claimed iff event was claimed
    1629  */
    1630 ui_evclaim_t ui_window_def_kbd(ui_window_t *window, kbd_event_t *kbd)
    1631 {
    1632         ui_evclaim_t claim;
    1633 
    1634         if (window->control != NULL)
    1635                 claim = ui_control_kbd_event(window->control, kbd);
    1636         else
    1637                 claim = ui_unclaimed;
    1638 
    1639         if (claim == ui_unclaimed)
    1640                 return ui_wdecor_kbd_event(window->wdecor, kbd);
    1641 
    1642         return ui_unclaimed;
     672                window->cb->unfocus(window, window->arg);
    1643673}
    1644674
     
    1666696                return ui_control_paint(window->control);
    1667697
    1668         rc = gfx_update(window->res->gc);
    1669         if (rc != EOK)
    1670                 return rc;
    1671 
    1672698        return EOK;
    1673699}
     
    1676702 *
    1677703 * @param window Window
     704 * @return EOK on success or an error code
    1678705 */
    1679706void ui_window_def_pos(ui_window_t *window, pos_event_t *pos)
     
    1683710}
    1684711
    1685 /** Default window unfocus routine.
    1686  *
    1687  * @param window Window
    1688  * @param nfocus Number of remaining foci
    1689  * @return EOK on success or an error code
    1690  */
    1691 void ui_window_def_unfocus(ui_window_t *window, unsigned nfocus)
    1692 {
    1693         if (window->control != NULL)
    1694                 ui_control_unfocus(window->control, nfocus);
    1695 }
    1696 
    1697 /** Default window resize routine.
    1698  *
    1699  * @param window Window
    1700  * @return EOK on success or an error code
    1701  */
    1702 void ui_window_def_resize(ui_window_t *window)
    1703 {
    1704         ui_window_paint(window);
    1705 }
    1706 
    1707 /** Handle system menu left event.
    1708  *
    1709  * @param sysmenu System menu
    1710  * @param arg Argument (ui_window_t *)
    1711  * @param idev_id Input device ID
    1712  */
    1713 static void wnd_sysmenu_left(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
    1714 {
    1715         ui_window_t *window = (ui_window_t *)arg;
    1716 
    1717         if (window->mbar != NULL) {
    1718                 ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
    1719                 ui_menu_close(sysmenu);
    1720                 ui_menu_bar_select_last(window->mbar, true, idev_id);
    1721         }
    1722 }
    1723 
    1724 /** Handle system menu right event.
    1725  *
    1726  * @param sysmenu System menu
    1727  * @param arg Argument (ui_window_t *)
    1728  * @param idev_id Input device ID
    1729  */
    1730 static void wnd_sysmenu_right(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
    1731 {
    1732         ui_window_t *window = (ui_window_t *)arg;
    1733 
    1734         if (window->mbar != NULL) {
    1735                 ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
    1736                 ui_menu_close(sysmenu);
    1737                 ui_menu_bar_select_first(window->mbar, true, idev_id);
    1738         }
    1739 }
    1740 
    1741 /** Handle system menu close request event.
    1742  *
    1743  * @param sysmenu System menu
    1744  * @param arg Argument (ui_window_t *)
    1745  * @param idev_id Input device ID
    1746  */
    1747 static void wnd_sysmenu_close_req(ui_menu_t *sysmenu, void *arg)
    1748 {
    1749         ui_window_t *window = (ui_window_t *)arg;
    1750 
    1751         ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
    1752         ui_menu_close(sysmenu);
    1753 }
    1754 
    1755 /** Handle system menu Restore entry activation.
    1756  *
    1757  * @param mentry Menu entry
    1758  * @param arg Argument (ui_window_t *)
    1759  */
    1760 static void wnd_sysmenu_erestore(ui_menu_entry_t *mentry, void *arg)
    1761 {
    1762         ui_window_t *window = (ui_window_t *)arg;
    1763 
    1764         ui_window_send_unmaximize(window);
    1765 }
    1766 
    1767 /** Handle system menu Minimize entry activation.
    1768  *
    1769  * @param mentry Menu entry
    1770  * @param arg Argument (ui_window_t *)
    1771  */
    1772 static void wnd_sysmenu_eminimize(ui_menu_entry_t *mentry, void *arg)
    1773 {
    1774         ui_window_t *window = (ui_window_t *)arg;
    1775 
    1776         ui_window_send_minimize(window);
    1777 }
    1778 
    1779 /** Handle system menu Maximize entry activation.
    1780  *
    1781  * @param mentry Menu entry
    1782  * @param arg Argument (ui_window_t *)
    1783  */
    1784 static void wnd_sysmenu_emaximize(ui_menu_entry_t *mentry, void *arg)
    1785 {
    1786         ui_window_t *window = (ui_window_t *)arg;
    1787 
    1788         ui_window_send_maximize(window);
    1789 }
    1790 
    1791 /** Handle system menu Close entry activation.
    1792  *
    1793  * @param mentry Menu entry
    1794  * @param arg Argument (ui_window_t *)
    1795  */
    1796 static void wnd_sysmenu_eclose(ui_menu_entry_t *mentry, void *arg)
    1797 {
    1798         ui_window_t *window = (ui_window_t *)arg;
    1799 
    1800         ui_window_send_close(window);
    1801 }
    1802 
    1803 /** Handle system menu press accelerator key event.
    1804  *
    1805  * @param sysmenu System menu
    1806  * @param arg Argument (ui_window_t *)
    1807  * @param idev_id Input device ID
    1808  */
    1809 static void wnd_sysmenu_press_accel(ui_menu_t *sysmenu, void *arg,
    1810     char32_t c, sysarg_t idev_id)
    1811 {
    1812         (void)sysmenu;
    1813         (void)arg;
    1814         (void)c;
    1815         (void)idev_id;
    1816 }
    1817 
    1818 /** Window invalidate callback
     712/** Application area update callback
    1819713 *
    1820714 * @param arg Argument (ui_window_t *)
    1821715 * @param rect Rectangle to update
    1822716 */
    1823 static void ui_window_invalidate(void *arg, gfx_rect_t *rect)
    1824 {
    1825         ui_window_t *window = (ui_window_t *) arg;
    1826         gfx_rect_t env;
    1827 
    1828         gfx_rect_envelope(&window->dirty_rect, rect, &env);
    1829         window->dirty_rect = env;
    1830 }
    1831 
    1832 /** Window update callback
    1833  *
    1834  * @param arg Argument (ui_window_t *)
    1835  */
    1836 static void ui_window_update(void *arg)
    1837 {
    1838         ui_window_t *window = (ui_window_t *) arg;
    1839 
    1840         if (!gfx_rect_is_empty(&window->dirty_rect)) {
    1841                 (void) gfx_bitmap_render(window->bmp, &window->dirty_rect,
    1842                     &window->dpos);
    1843         }
    1844 
    1845         window->dirty_rect.p0.x = 0;
    1846         window->dirty_rect.p0.y = 0;
    1847         window->dirty_rect.p1.x = 0;
    1848         window->dirty_rect.p1.y = 0;
    1849 }
    1850 
    1851 /** Window cursor get position callback
    1852  *
    1853  * @param arg Argument (ui_window_t *)
    1854  * @param pos Place to store position
    1855  */
    1856 static errno_t ui_window_cursor_get_pos(void *arg, gfx_coord2_t *pos)
    1857 {
    1858         ui_window_t *window = (ui_window_t *) arg;
    1859         gfx_coord2_t cpos;
    1860         errno_t rc;
    1861 
    1862         rc = gfx_cursor_get_pos(window->realgc, &cpos);
    1863         if (rc != EOK)
    1864                 return rc;
    1865 
    1866         pos->x = cpos.x - window->dpos.x;
    1867         pos->y = cpos.y - window->dpos.y;
    1868         return EOK;
    1869 }
    1870 
    1871 /** Window cursor set position callback
    1872  *
    1873  * @param arg Argument (ui_window_t *)
    1874  * @param pos New position
    1875  */
    1876 static errno_t ui_window_cursor_set_pos(void *arg, gfx_coord2_t *pos)
    1877 {
    1878         ui_window_t *window = (ui_window_t *) arg;
    1879         gfx_coord2_t cpos;
    1880 
    1881         cpos.x = pos->x + window->dpos.x;
    1882         cpos.y = pos->y + window->dpos.y;
    1883 
    1884         return gfx_cursor_set_pos(window->realgc, &cpos);
    1885 }
    1886 
    1887 /** Window cursor set visibility callback
    1888  *
    1889  * @param arg Argument (ui_window_t *)
    1890  * @param visible @c true iff cursor is to be made visible
    1891  */
    1892 static errno_t ui_window_cursor_set_visible(void *arg, bool visible)
    1893 {
    1894         ui_window_t *window = (ui_window_t *) arg;
    1895 
    1896         return gfx_cursor_set_visible(window->realgc, visible);
    1897 }
    1898 
    1899 /** Application area invalidate callback
    1900  *
    1901  * @param arg Argument (ui_window_t *)
    1902  * @param rect Rectangle to update
    1903  */
    1904 static void ui_window_app_invalidate(void *arg, gfx_rect_t *rect)
     717static void ui_window_app_update(void *arg, gfx_rect_t *rect)
    1905718{
    1906719        ui_window_t *window = (ui_window_t *) arg;
     
    1911724        /* Render bitmap rectangle inside the application area */
    1912725        (void) gfx_bitmap_render(window->app_bmp, rect, &arect.p0);
    1913         /*
    1914          * TODO Update applications to call gfx_update(), then
    1915          * we can defer update to ui_window_app_update().
    1916          */
    1917         (void) gfx_update(window->res->gc);
    1918 }
    1919 
    1920 /** Application area update callback
    1921  *
    1922  * @param arg Argument (ui_window_t *)
    1923  */
    1924 static void ui_window_app_update(void *arg)
    1925 {
    1926         ui_window_t *window = (ui_window_t *) arg;
    1927 
    1928         /*
    1929          * Not used since display is updated immediately
    1930          * in ui_window_app_invalidate
    1931          */
    1932         (void) window;
    1933 }
    1934 
    1935 /** Window expose callback. */
    1936 static void ui_window_expose_cb(void *arg)
    1937 {
    1938         ui_window_t *window = (ui_window_t *) arg;
    1939 
    1940         ui_window_paint(window);
    1941726}
    1942727
Note: See TracChangeset for help on using the changeset viewer.