Ignore:
File:
1 edited

Legend:

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

    r0d00e53 rdb3895d  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3939#include <gfx/bitmap.h>
    4040#include <gfx/context.h>
    41 #include <gfx/cursor.h>
    4241#include <gfx/render.h>
    4342#include <io/kbd_event.h>
     
    4746#include <stdlib.h>
    4847#include <ui/control.h>
    49 #include <ui/menubar.h>
    50 #include <ui/menu.h>
    51 #include <ui/menuentry.h>
    5248#include <ui/resource.h>
    5349#include <ui/ui.h>
     
    6258
    6359static void dwnd_close_event(void *);
    64 static void dwnd_focus_event(void *, unsigned);
     60static void dwnd_focus_event(void *);
    6561static void dwnd_kbd_event(void *, kbd_event_t *);
    6662static void dwnd_pos_event(void *, pos_event_t *);
    6763static void dwnd_resize_event(void *, gfx_rect_t *);
    68 static void dwnd_unfocus_event(void *, unsigned);
     64static void dwnd_unfocus_event(void *);
    6965
    7066static display_wnd_cb_t dwnd_cb = {
     
    7773};
    7874
    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 *);
    8675static void wd_close(ui_wdecor_t *, void *);
    87 static void wd_move(ui_wdecor_t *, void *, gfx_coord2_t *, sysarg_t);
     76static void wd_move(ui_wdecor_t *, void *, gfx_coord2_t *);
    8877static void wd_resize(ui_wdecor_t *, void *, ui_wdecor_rsztype_t,
    89     gfx_coord2_t *, sysarg_t);
     78    gfx_coord2_t *);
    9079static void wd_set_cursor(ui_wdecor_t *, void *, ui_stock_cursor_t);
    9180
    9281static 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,
    10082        .close = wd_close,
    10183        .move = wd_move,
     
    10486};
    10587
    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 
    12388static void ui_window_invalidate(void *, gfx_rect_t *);
    12489static 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 
    13890static void ui_window_app_invalidate(void *, gfx_rect_t *);
    13991static 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 
    14792static void ui_window_expose_cb(void *);
    14893
     
    166111/** Compute where window should be placed on the screen.
    167112 *
    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
     113 * This only applies to windows that do not use default placement.
     114 *
     115 * @param window Window
     116 * @param display Display
     117 * @param info Display info
    173118 * @param params Window parameters
    174119 * @param pos Place to store position of top-left corner
    175120 */
    176 static 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));
     121static void ui_window_place(ui_window_t *window, display_t *display,
     122    display_info_t *info, ui_wnd_params_t *params, gfx_coord2_t *pos)
     123{
     124        assert(params->placement != ui_wnd_place_default);
    185125
    186126        pos->x = 0;
     
    189129        switch (params->placement) {
    190130        case ui_wnd_place_default:
    191         case ui_wnd_place_center:
    192                 assert(params->placement != ui_wnd_place_default ||
    193                     ui_is_fullscreen(window->ui));
    194                 /* Center window */
    195                 gfx_rect_dims(&params->rect, &dims);
    196                 pos->x = (drect->p0.x + drect->p1.x) / 2 - dims.x / 2;
    197                 pos->y = (drect->p0.y + drect->p1.y) / 2 - dims.y / 2;
    198                 break;
     131                assert(false);
    199132        case ui_wnd_place_top_left:
    200133        case ui_wnd_place_full_screen:
    201                 pos->x = drect->p0.x - params->rect.p0.x;
    202                 pos->y = drect->p0.y - params->rect.p0.y;
     134                pos->x = info->rect.p0.x - params->rect.p0.x;
     135                pos->y = info->rect.p0.y - params->rect.p0.y;
    203136                break;
    204137        case ui_wnd_place_top_right:
    205                 pos->x = drect->p1.x - params->rect.p1.x;
    206                 pos->y = drect->p0.y - params->rect.p0.y;
     138                pos->x = info->rect.p1.x - params->rect.p1.x;
     139                pos->y = info->rect.p0.y - params->rect.p0.y;
    207140                break;
    208141        case ui_wnd_place_bottom_left:
    209                 pos->x = drect->p0.x - params->rect.p0.x;
    210                 pos->y = drect->p1.y - params->rect.p1.y;
     142                pos->x = info->rect.p0.x - params->rect.p0.x;
     143                pos->y = info->rect.p1.y - params->rect.p1.y;
    211144                break;
    212145        case ui_wnd_place_bottom_right:
    213                 pos->x = drect->p1.x - params->rect.p1.x;
    214                 pos->y = drect->p1.y - params->rect.p1.y;
     146                pos->x = info->rect.p1.x - params->rect.p1.x;
     147                pos->y = info->rect.p1.y - params->rect.p1.y;
    215148                break;
    216149        case ui_wnd_place_popup:
    217                 /* Compute rectangle when placed below */
    218                 below_pos.x = params->prect.p0.x;
    219                 below_pos.y = params->prect.p1.y;
    220                 gfx_rect_translate(&below_pos, &params->rect, &below_rect);
    221 
    222                 /* Does below_rect fit within the display? */
    223                 if (gfx_rect_is_inside(&below_rect, drect)) {
    224                         /* Place popup window below parent rectangle */
    225                         pos->x = params->prect.p0.x - params->rect.p0.x;
    226                         pos->y = params->prect.p1.y - params->rect.p0.y;
    227                 } else {
    228                         /* Place popup window above parent rectangle */
    229                         pos->x = params->prect.p0.x;
    230                         pos->y = params->prect.p0.y -
    231                             (params->rect.p1.y - params->rect.p0.y);
    232                 }
     150                /* Place popup window below parent rectangle */
     151                pos->x = params->prect.p0.x;
     152                pos->y = params->prect.p1.y;
    233153                break;
    234154        }
    235 }
    236 
    237 /** Create window's system menu.
    238  *
    239  * @param window Window
    240  * @return EOK on success or an error code
    241  */
    242 static errno_t ui_window_sysmenu_create(ui_window_t *window)
    243 {
    244         errno_t rc;
    245         ui_menu_entry_t *mrestore;
    246         ui_menu_entry_t *mmin;
    247         ui_menu_entry_t *mmax;
    248         ui_menu_entry_t *msep;
    249         ui_menu_entry_t *mclose;
    250 
    251         rc = ui_menu_create(window, &window->sysmenu);
    252         if (rc != EOK)
    253                 goto error;
    254 
    255         ui_menu_set_cb(window->sysmenu, &wnd_sysmenu_cb, (void *)window);
    256 
    257         rc = ui_menu_entry_create(window->sysmenu, "~R~estore",
    258             "", &mrestore);
    259         if (rc != EOK)
    260                 goto error;
    261 
    262         if (!window->wdecor->maximized)
    263                 ui_menu_entry_set_disabled(mrestore, true);
    264 
    265         ui_menu_entry_set_cb(mrestore, wnd_sysmenu_erestore, (void *)window);
    266 
    267         rc = ui_menu_entry_create(window->sysmenu, "Mi~n~imize",
    268             "", &mmin);
    269         if (rc != EOK)
    270                 goto error;
    271 
    272         if ((window->wdecor->style & ui_wds_minimize_btn) == 0)
    273                 ui_menu_entry_set_disabled(mmin, true);
    274 
    275         ui_menu_entry_set_cb(mmin, wnd_sysmenu_eminimize, (void *)window);
    276 
    277         rc = ui_menu_entry_create(window->sysmenu, "Ma~x~imize",
    278             "", &mmax);
    279         if (rc != EOK)
    280                 goto error;
    281 
    282         if ((window->wdecor->style & ui_wds_maximize_btn) == 0 ||
    283             window->wdecor->maximized)
    284                 ui_menu_entry_set_disabled(mmax, true);
    285 
    286         ui_menu_entry_set_cb(mmax, wnd_sysmenu_emaximize, (void *)window);
    287 
    288         rc = ui_menu_entry_sep_create(window->sysmenu, &msep);
    289         if (rc != EOK)
    290                 goto error;
    291 
    292         rc = ui_menu_entry_create(window->sysmenu, "~C~lose", "Alt-F4",
    293             &mclose);
    294         if (rc != EOK)
    295                 goto error;
    296 
    297         if ((window->wdecor->style & ui_wds_close_btn) == 0)
    298                 ui_menu_entry_set_disabled(mclose, true);
    299 
    300         ui_menu_entry_set_cb(mclose, wnd_sysmenu_eclose, (void *)window);
    301 
    302         window->sysmenu_restore = mrestore;
    303         window->sysmenu_minimize = mmin;
    304         window->sysmenu_maximize = mmax;
    305 
    306         return EOK;
    307 error:
    308         return rc;
    309155}
    310156
     
    320166{
    321167        ui_window_t *window;
    322         ui_window_t *pwindow = NULL;
    323168        display_info_t info;
    324169        gfx_coord2_t scr_dims;
     
    331176        gfx_bitmap_alloc_t alloc;
    332177        gfx_bitmap_t *bmp = NULL;
    333         gfx_coord2_t off;
    334178        mem_gc_t *memgc = NULL;
    335         xlate_gc_t *xgc = NULL;
    336179        errno_t rc;
    337180
     
    340183                return ENOMEM;
    341184
    342         window->ui = ui;
    343 
    344185        display_wnd_params_init(&dparams);
    345186        dparams.rect = params->rect;
    346         dparams.caption = params->caption;
    347         dparams.min_size = params->min_size;
    348 
    349         /*
    350          * If idev_id is not specified, use the UI default (probably
    351          * obtained from display specification. This creates the
    352          * main window in the seat specified on the command line.
    353          */
    354         if (params->idev_id != 0)
    355                 dparams.idev_id = params->idev_id;
    356         else
    357                 dparams.idev_id = ui->idev_id;
     187        /* Only allow making the window larger */
     188        gfx_rect_dims(&params->rect, &dparams.min_size);
    358189
    359190        if ((params->flags & ui_wndf_popup) != 0)
    360191                dparams.flags |= wndf_popup;
    361         if ((params->flags & ui_wndf_nofocus) != 0)
    362                 dparams.flags |= wndf_nofocus;
    363         if ((params->flags & ui_wndf_topmost) != 0)
    364                 dparams.flags |= wndf_topmost;
    365         if ((params->flags & ui_wndf_system) != 0)
    366                 dparams.flags |= wndf_system;
    367         if ((params->flags & ui_wndf_avoid) != 0)
    368                 dparams.flags |= wndf_avoid;
    369192
    370193        if (ui->display != NULL) {
     
    384207                if (params->placement != ui_wnd_place_default) {
    385208                        /* Set initial display window position */
    386                         ui_window_place(window, &info.rect, params,
    387                             &dparams.pos);
     209                        ui_window_place(window, ui->display, &info,
     210                            params, &dparams.pos);
    388211
    389212                        dparams.flags |= wndf_setpos;
     
    400223        } else if (ui->console != NULL) {
    401224                gc = console_gc_get_ctx(ui->cgc);
    402 
    403                 if (params->placement == ui_wnd_place_full_screen) {
    404                         /* Make window the size of the screen */
    405                         gfx_rect_dims(&ui->rect, &scr_dims);
    406                         gfx_coord2_add(&dparams.rect.p0, &scr_dims,
    407                             &dparams.rect.p1);
    408                         (void) console_set_caption(ui->console,
    409                             params->caption);
    410                 }
    411225        } else {
    412226                /* Needed for unit tests */
     
    428242
    429243        /* Move rectangle so that top-left corner is 0,0 */
    430         gfx_rect_rtranslate(&dparams.rect.p0, &dparams.rect, &bparams.rect);
     244        gfx_rect_rtranslate(&params->rect.p0, &params->rect, &bparams.rect);
    431245
    432246        rc = gfx_bitmap_create(gc, &bparams, NULL, &bmp);
     
    441255        }
    442256
    443         rc = mem_gc_create(&bparams.rect, &alloc, &ui_window_mem_gc_cb,
    444             (void *) window, &memgc);
     257        rc = mem_gc_create(&bparams.rect, &alloc, ui_window_invalidate,
     258            ui_window_update, (void *) window, &memgc);
    445259        if (rc != EOK) {
    446260                gfx_bitmap_destroy(window->app_bmp);
     
    452266        window->gc = mem_gc_get_ctx(memgc);
    453267        window->realgc = gc;
    454         (void) off;
    455268#else
    456         /* Server-side rendering */
    457 
    458         /* Full-screen mode? */
    459         if (ui->display == NULL) {
    460                 /* Create translating GC to translate window contents */
    461                 off.x = 0;
    462                 off.y = 0;
    463                 rc = xlate_gc_create(&off, gc, &xgc);
    464                 if (rc != EOK)
    465                         goto error;
    466 
    467                 window->xgc = xgc;
    468                 window->gc = xlate_gc_get_ctx(xgc);
    469                 window->realgc = gc;
    470         } else {
    471                 window->gc = gc;
    472         }
    473 
    474         (void) ui_window_mem_gc_cb;
     269        (void) ui_window_update;
     270        (void) ui_window_invalidate;
    475271        (void) alloc;
    476272        (void) bparams;
     273        window->gc = gc;
    477274#endif
    478         if (ui->display == NULL) {
    479                 ui_window_place(window, &ui->rect, params, &window->dpos);
    480 
    481                 if (window->xgc != NULL)
    482                         xlate_gc_set_off(window->xgc, &window->dpos);
    483         }
    484275
    485276        rc = ui_resource_create(window->gc, ui_is_textmode(ui), &res);
     
    497288        ui_resource_set_expose_cb(res, ui_window_expose_cb, (void *) window);
    498289
     290        window->ui = ui;
    499291        window->rect = dparams.rect;
     292
    500293        window->res = res;
    501294        window->wdecor = wdecor;
    502295        window->cursor = ui_curs_arrow;
    503         window->placement = params->placement;
    504 
    505         rc = ui_window_sysmenu_create(window);
    506         if (rc != EOK)
    507                 goto error;
    508 
    509296        *rwindow = window;
    510297
    511         if (ui_is_fullscreen(ui))
    512                 pwindow = ui_window_get_active(ui);
    513 
    514298        list_append(&window->lwindows, &ui->windows);
    515 
    516         if (ui_is_fullscreen(ui)) {
    517                 /* Send unfocus event to previously active window */
    518                 if (pwindow != NULL)
    519                         ui_window_send_unfocus(pwindow, 0);
    520         }
    521 
    522299        return EOK;
    523300error:
     
    528305        if (memgc != NULL)
    529306                mem_gc_delete(memgc);
    530         if (xgc != NULL)
    531                 xlate_gc_delete(xgc);
    532307        if (bmp != NULL)
    533308                gfx_bitmap_destroy(bmp);
     
    545320{
    546321        ui_t *ui;
    547         ui_window_t *nwindow;
    548322
    549323        if (window == NULL)
     
    554328        list_remove(&window->lwindows);
    555329        ui_control_destroy(window->control);
    556         ui_menu_destroy(window->sysmenu);
    557330        ui_wdecor_destroy(window->wdecor);
    558331        ui_resource_destroy(window->res);
    559         if (window->app_mgc != NULL)
     332        if (0 && window->app_mgc != NULL)
    560333                mem_gc_delete(window->app_mgc);
    561         if (window->app_bmp != NULL)
     334        if (0 && window->app_bmp != NULL)
    562335                gfx_bitmap_destroy(window->app_bmp);
    563336        if (window->mgc != NULL) {
     
    567340        if (window->bmp != NULL)
    568341                gfx_bitmap_destroy(window->bmp);
     342        gfx_context_delete(window->gc);
    569343        if (window->dwindow != NULL)
    570344                display_window_destroy(window->dwindow);
     345
     346        free(window);
    571347
    572348        /* Need to repaint if windows are emulated */
    573349        if (ui_is_fullscreen(ui)) {
    574350                ui_paint(ui);
    575                 /* Send focus event to newly active window */
    576                 nwindow = ui_window_get_active(ui);
    577                 if (nwindow != NULL)
    578                         ui_window_send_focus(nwindow, 0);
    579         }
    580 
    581         if (ui->console != NULL &&
    582             window->placement == ui_wnd_place_full_screen) {
    583                 (void) console_set_caption(ui->console, "");
    584         }
    585 
    586         free(window);
     351        }
    587352}
    588353
     
    594359 * @param window Window
    595360 * @param control Control
     361 * @return EOK on success, ENOMEM if out of memory
    596362 */
    597363void ui_window_add(ui_window_t *window, ui_control_t *control)
     
    633399}
    634400
    635 /** Resize or (un)maximize window.
     401/** Resize/move window.
     402 *
     403 * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
     404 * the top-left corner of the window will move on the screen accordingly.
    636405 *
    637406 * @param window Window
    638407 * @param rect Rectangle
    639  * @param scop Size change operation
    640408 *
    641409 * @return EOK on success or an error code
    642410 */
    643 errno_t ui_window_size_change(ui_window_t *window, gfx_rect_t *rect,
    644     ui_wnd_sc_op_t scop)
     411errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
    645412{
    646413        gfx_coord2_t offs;
     
    708475        }
    709476
    710         /* dwindow can be NULL in case of unit tests or fullscreen mode */
     477        /* dwindow can be NULL in case of unit tests */
    711478        if (window->dwindow != NULL) {
    712                 switch (scop) {
    713                 case ui_wsc_resize:
    714                         rc = display_window_resize(window->dwindow, &offs,
    715                             &nrect);
    716                         if (rc != EOK)
    717                                 goto error;
    718                         break;
    719                 case ui_wsc_maximize:
    720                         rc = display_window_maximize(window->dwindow);
    721                         if (rc != EOK)
    722                                 goto error;
    723                         break;
    724                 case ui_wsc_unmaximize:
    725                         rc = display_window_unmaximize(window->dwindow);
    726                         if (rc != EOK)
    727                                 goto error;
    728                         break;
    729                 }
     479                rc = display_window_resize(window->dwindow, &offs, &nrect);
     480                if (rc != EOK)
     481                        goto error;
    730482        }
    731483
     
    747499                        goto error;
    748500#endif
     501
    749502                mem_gc_retarget(window->mgc, &win_params.rect, &win_alloc);
    750503
     
    753506        }
    754507
    755         window->rect = nrect;
    756508        ui_wdecor_set_rect(window->wdecor, &nrect);
    757509        ui_wdecor_paint(window->wdecor);
     
    775527}
    776528
    777 /** Resize/move window.
    778  *
    779  * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
    780  * the top-left corner of the window will move on the screen accordingly.
    781  *
    782  * @param window Window
    783  * @param rect Rectangle
    784  *
    785  * @return EOK on success or an error code
    786  */
    787 errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
    788 {
    789         return ui_window_size_change(window, rect, ui_wsc_resize);
    790 }
    791 
    792529/** Set window callbacks.
    793530 *
     
    802539}
    803540
    804 /** Change window caption.
    805  *
    806  * @param window Window
    807  * @param caption New caption
    808  *
    809  * @return EOK on success or an error code
    810  */
    811 errno_t ui_window_set_caption(ui_window_t *window, const char *caption)
    812 {
    813         errno_t rc;
    814 
    815         /* Set console caption if fullscreen window on console */
    816         if (window->ui->console != NULL && window->placement ==
    817             ui_wnd_place_full_screen) {
    818                 rc = console_set_caption(window->ui->console, caption);
    819                 if (rc != EOK)
    820                         return rc;
    821         }
    822 
    823         /* Set display window caption if running on display service */
    824         if (window->dwindow != NULL) {
    825                 rc = display_window_set_caption(window->dwindow, caption);
    826                 if (rc != EOK)
    827                         return rc;
    828         }
    829 
    830         return ui_wdecor_set_caption(window->wdecor, caption);
    831 }
    832 
    833 /** Get window's containing UI.
    834  *
    835  * @param window Window
    836  * @return Containing UI
    837  */
    838 ui_t *ui_window_get_ui(ui_window_t *window)
    839 {
    840         return window->ui;
    841 }
    842 
    843541/** Get UI resource from window.
    844542 *
     
    876574                        return rc;
    877575        } else {
    878                 *pos = window->dpos;
     576                pos->x = 0;
     577                pos->y = 0;
    879578        }
    880579
     
    919618                }
    920619
    921                 rc = mem_gc_create(&params.rect, &alloc,
    922                     &ui_window_app_mem_gc_cb, (void *) window, &memgc);
     620                rc = mem_gc_create(&params.rect, &alloc, ui_window_app_invalidate,
     621                    ui_window_app_update, (void *) window, &memgc);
    923622                if (rc != EOK) {
    924623                        gfx_bitmap_destroy(window->app_bmp);
     
    976675{
    977676        ui_window_t *window = (ui_window_t *) arg;
    978         ui_t *ui = window->ui;
    979 
    980         ui_lock(ui);
     677
    981678        ui_window_send_close(window);
    982         ui_unlock(ui);
    983679}
    984680
    985681/** Handle window focus event. */
    986 static void dwnd_focus_event(void *arg, unsigned nfocus)
    987 {
    988         ui_window_t *window = (ui_window_t *) arg;
    989         ui_t *ui = window->ui;
    990 
    991         ui_lock(ui);
    992         (void)nfocus;
     682static void dwnd_focus_event(void *arg)
     683{
     684        ui_window_t *window = (ui_window_t *) arg;
    993685
    994686        if (window->wdecor != NULL) {
     
    997689        }
    998690
    999         ui_window_send_focus(window, nfocus);
    1000         ui_unlock(ui);
     691        ui_window_send_focus(window);
    1001692}
    1002693
     
    1005696{
    1006697        ui_window_t *window = (ui_window_t *) arg;
    1007         ui_t *ui = window->ui;
    1008 
    1009         ui_lock(ui);
     698
     699        (void) window;
    1010700        ui_window_send_kbd(window, kbd_event);
    1011         ui_unlock(ui);
    1012701}
    1013702
     
    1016705{
    1017706        ui_window_t *window = (ui_window_t *) arg;
    1018         ui_t *ui = window->ui;
    1019         ui_evclaim_t claim;
    1020707
    1021708        /* Make sure we don't process events until fully initialized */
     
    1023710                return;
    1024711
    1025         ui_lock(ui);
    1026 
    1027         claim = ui_wdecor_pos_event(window->wdecor, event);
    1028         if (claim == ui_claimed) {
    1029                 ui_unlock(ui);
    1030                 return;
    1031         }
    1032 
     712        ui_wdecor_pos_event(window->wdecor, event);
    1033713        ui_window_send_pos(window, event);
    1034         ui_unlock(ui);
    1035714}
    1036715
     
    1039718{
    1040719        ui_window_t *window = (ui_window_t *) arg;
    1041         ui_t *ui = window->ui;
    1042720
    1043721        /* Make sure we don't process events until fully initialized */
     
    1048726                return;
    1049727
    1050         ui_lock(ui);
    1051728        (void) ui_window_resize(window, rect);
    1052         ui_window_send_resize(window);
    1053         ui_unlock(ui);
     729        (void) ui_window_paint(window);
    1054730}
    1055731
    1056732/** Handle window unfocus event. */
    1057 static void dwnd_unfocus_event(void *arg, unsigned nfocus)
    1058 {
    1059         ui_window_t *window = (ui_window_t *) arg;
    1060         ui_t *ui = window->ui;
    1061 
    1062         ui_lock(ui);
    1063 
    1064         if (window->wdecor != NULL && nfocus == 0) {
     733static void dwnd_unfocus_event(void *arg)
     734{
     735        ui_window_t *window = (ui_window_t *) arg;
     736
     737        if (window->wdecor != NULL) {
    1065738                ui_wdecor_set_active(window->wdecor, false);
    1066739                ui_wdecor_paint(window->wdecor);
    1067740        }
    1068741
    1069         ui_window_send_unfocus(window, nfocus);
    1070         ui_unlock(ui);
    1071 }
    1072 
    1073 /** Window decoration requested opening of system menu.
    1074  *
    1075  * @param wdecor Window decoration
    1076  * @param arg Argument (window)
    1077  * @param idev_id Input device ID
    1078  */
    1079 static void wd_sysmenu_open(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
    1080 {
    1081         ui_window_t *window = (ui_window_t *) arg;
    1082 
    1083         ui_window_send_sysmenu(window, idev_id);
    1084 }
    1085 
    1086 /** Window decoration requested moving left from system menu handle.
    1087  *
    1088  * @param wdecor Window decoration
    1089  * @param arg Argument (window)
    1090  * @param idev_id Input device ID
    1091  */
    1092 static void wd_sysmenu_left(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
    1093 {
    1094         ui_window_t *window = (ui_window_t *) arg;
    1095 
    1096         if (window->mbar != NULL) {
    1097                 ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
    1098                 ui_menu_close(window->sysmenu);
    1099                 ui_menu_bar_select_last(window->mbar, false, idev_id);
    1100         }
    1101 }
    1102 
    1103 /** Window decoration requested moving right from system menu handle.
    1104  *
    1105  * @param wdecor Window decoration
    1106  * @param arg Argument (window)
    1107  * @param idev_id Input device ID
    1108  */
    1109 static void wd_sysmenu_right(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
    1110 {
    1111         ui_window_t *window = (ui_window_t *) arg;
    1112 
    1113         if (window->mbar != NULL) {
    1114                 ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
    1115                 ui_menu_close(window->sysmenu);
    1116                 ui_menu_bar_select_first(window->mbar, false, idev_id);
    1117         }
    1118 }
    1119 
    1120 /** Window decoration detected accelerator press from system menu handle.
    1121  *
    1122  * @param wdecor Window decoration
    1123  * @param arg Argument (window)
    1124  * @param c Accelerator key
    1125  * @param idev_id Input device ID
    1126  */
    1127 static void wd_sysmenu_accel(ui_wdecor_t *wdecor, void *arg, char32_t c,
    1128     sysarg_t idev_id)
    1129 {
    1130         ui_window_t *window = (ui_window_t *) arg;
    1131 
    1132         if (window->mbar != NULL) {
    1133                 ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
    1134                 ui_menu_close(window->sysmenu);
    1135                 ui_menu_bar_press_accel(window->mbar, c, idev_id);
    1136         }
    1137 }
    1138 
    1139 /** Window decoration requested window minimization.
    1140  *
    1141  * @param wdecor Window decoration
    1142  * @param arg Argument (window)
    1143  */
    1144 static void wd_minimize(ui_wdecor_t *wdecor, void *arg)
    1145 {
    1146         ui_window_t *window = (ui_window_t *) arg;
    1147 
    1148         ui_window_send_minimize(window);
    1149 }
    1150 
    1151 /** Window decoration requested window maximization.
    1152  *
    1153  * @param wdecor Window decoration
    1154  * @param arg Argument (window)
    1155  */
    1156 static void wd_maximize(ui_wdecor_t *wdecor, void *arg)
    1157 {
    1158         ui_window_t *window = (ui_window_t *) arg;
    1159 
    1160         ui_window_send_maximize(window);
    1161 }
    1162 
    1163 /** Window decoration requested window unmaximization.
    1164  *
    1165  * @param wdecor Window decoration
    1166  * @param arg Argument (window)
    1167  */
    1168 static void wd_unmaximize(ui_wdecor_t *wdecor, void *arg)
    1169 {
    1170         ui_window_t *window = (ui_window_t *) arg;
    1171 
    1172         ui_window_send_unmaximize(window);
     742        ui_window_send_unfocus(window);
    1173743}
    1174744
     
    1190760 * @param arg Argument (window)
    1191761 * @param pos Position where the title bar was pressed
    1192  * @param pos_id Positioning device ID
    1193  */
    1194 static void wd_move(ui_wdecor_t *wdecor, void *arg, gfx_coord2_t *pos,
    1195     sysarg_t pos_id)
     762 */
     763static void wd_move(ui_wdecor_t *wdecor, void *arg, gfx_coord2_t *pos)
    1196764{
    1197765        ui_window_t *window = (ui_window_t *) arg;
    1198766
    1199767        if (window->dwindow != NULL)
    1200                 (void) display_window_move_req(window->dwindow, pos, pos_id);
     768                (void) display_window_move_req(window->dwindow, pos);
    1201769}
    1202770
     
    1207775 * @param rsztype Resize type
    1208776 * @param pos Position where the button was pressed
    1209  * @param pos_id Positioning device ID
    1210777 */
    1211778static void wd_resize(ui_wdecor_t *wdecor, void *arg,
    1212     ui_wdecor_rsztype_t rsztype, gfx_coord2_t *pos, sysarg_t pos_id)
    1213 {
    1214         ui_window_t *window = (ui_window_t *) arg;
    1215 
    1216         if (window->dwindow != NULL) {
    1217                 (void) display_window_resize_req(window->dwindow,
    1218                     (display_wnd_rsztype_t) rsztype, // Same constants in the enums
    1219                     pos, pos_id);
    1220         }
     779    ui_wdecor_rsztype_t rsztype, gfx_coord2_t *pos)
     780{
     781        ui_window_t *window = (ui_window_t *) arg;
     782
     783        if (window->dwindow != NULL)
     784                (void) display_window_resize_req(window->dwindow, rsztype, pos);
    1221785}
    1222786
     
    1279843}
    1280844
    1281 /** Send window sysmenu event.
    1282  *
    1283  * @param window Window
    1284  * @parma idev_id Input device ID
    1285  */
    1286 void ui_window_send_sysmenu(ui_window_t *window, sysarg_t idev_id)
    1287 {
    1288         if (window->cb != NULL && window->cb->sysmenu != NULL)
    1289                 window->cb->sysmenu(window, window->arg, idev_id);
    1290         else
    1291                 ui_window_def_sysmenu(window, idev_id);
    1292 }
    1293 
    1294 /** Send window minimize event.
    1295  *
    1296  * @param window Window
    1297  */
    1298 void ui_window_send_minimize(ui_window_t *window)
    1299 {
    1300         if (window->cb != NULL && window->cb->minimize != NULL)
    1301                 window->cb->minimize(window, window->arg);
    1302         else
    1303                 ui_window_def_minimize(window);
    1304 }
    1305 
    1306 /** Send window maximize event.
    1307  *
    1308  * @param window Window
    1309  */
    1310 void ui_window_send_maximize(ui_window_t *window)
    1311 {
    1312         if (window->cb != NULL && window->cb->maximize != NULL)
    1313                 window->cb->maximize(window, window->arg);
    1314         else
    1315                 ui_window_def_maximize(window);
    1316 }
    1317 
    1318 /** Send window unmaximize event.
    1319  *
    1320  * @param window Window
    1321  */
    1322 void ui_window_send_unmaximize(ui_window_t *window)
    1323 {
    1324         if (window->cb != NULL && window->cb->unmaximize != NULL)
    1325                 window->cb->unmaximize(window, window->arg);
    1326         else
    1327                 ui_window_def_unmaximize(window);
    1328 }
    1329 
    1330845/** Send window close event.
    1331846 *
     
    1341856 *
    1342857 * @param window Window
    1343  * @param nfocus New number of foci
    1344  */
    1345 void ui_window_send_focus(ui_window_t *window, unsigned nfocus)
     858 */
     859void ui_window_send_focus(ui_window_t *window)
    1346860{
    1347861        if (window->cb != NULL && window->cb->focus != NULL)
    1348                 window->cb->focus(window, window->arg, nfocus);
     862                window->cb->focus(window, window->arg);
    1349863}
    1350864
     
    1357871        if (window->cb != NULL && window->cb->kbd != NULL)
    1358872                window->cb->kbd(window, window->arg, kbd);
    1359         else
    1360                 ui_window_def_kbd(window, kbd);
    1361873}
    1362874
     
    1388900 *
    1389901 * @param window Window
    1390  * @param nfocus Number of remaining foci
    1391  */
    1392 void ui_window_send_unfocus(ui_window_t *window, unsigned nfocus)
     902 */
     903void ui_window_send_unfocus(ui_window_t *window)
    1393904{
    1394905        if (window->cb != NULL && window->cb->unfocus != NULL)
    1395                 window->cb->unfocus(window, window->arg, nfocus);
     906                window->cb->unfocus(window, window->arg);
    1396907        else
    1397                 return ui_window_def_unfocus(window, nfocus);
    1398 }
    1399 
    1400 /** Send window resize event.
    1401  *
    1402  * @param window Window
    1403  */
    1404 void ui_window_send_resize(ui_window_t *window)
    1405 {
    1406         if (window->cb != NULL && window->cb->resize != NULL)
    1407                 window->cb->resize(window, window->arg);
    1408         else
    1409                 return ui_window_def_resize(window);
    1410 }
    1411 
    1412 /** Default window sysmenu routine.
    1413  *
    1414  * @param window Window
    1415  * @param idev_id Input device ID
    1416  * @return EOK on success or an error code
    1417  */
    1418 errno_t ui_window_def_sysmenu(ui_window_t *window, sysarg_t idev_id)
    1419 {
    1420         errno_t rc;
    1421         ui_wdecor_geom_t geom;
    1422 
    1423         if (ui_menu_is_open(window->sysmenu)) {
    1424                 ui_menu_close(window->sysmenu);
    1425         } else {
    1426                 ui_wdecor_get_geom(window->wdecor, &geom);
    1427 
    1428                 rc = ui_menu_open(window->sysmenu, &geom.title_bar_rect,
    1429                     idev_id);
    1430                 if (rc != EOK)
    1431                         goto error;
    1432         }
    1433 
    1434         return EOK;
    1435 error:
    1436         return rc;
    1437 }
    1438 
    1439 /** Default window minimize routine.
    1440  *
    1441  * @param window Window
    1442  * @return EOK on success or an error code
    1443  */
    1444 errno_t ui_window_def_minimize(ui_window_t *window)
    1445 {
    1446         errno_t rc;
    1447 
    1448         if (window->dwindow != NULL) {
    1449                 rc = display_window_minimize(window->dwindow);
    1450                 if (rc != EOK)
    1451                         goto error;
    1452         }
    1453 
    1454         return EOK;
    1455 error:
    1456         return rc;
    1457 }
    1458 
    1459 /** Default window maximize routine.
    1460  *
    1461  * @param window Window
    1462  * @return EOK on success or an error code
    1463  */
    1464 errno_t ui_window_def_maximize(ui_window_t *window)
    1465 {
    1466         errno_t rc;
    1467         gfx_rect_t old_rect;
    1468         gfx_rect_t rect;
    1469 
    1470         old_rect = window->rect;
    1471 
    1472         if (window->dwindow != NULL) {
    1473                 rc = display_window_get_max_rect(window->dwindow, &rect);
    1474                 if (rc != EOK)
    1475                         return rc;
    1476         } else {
    1477                 rect = window->ui->rect;
    1478         }
    1479 
    1480         ui_wdecor_set_maximized(window->wdecor, true);
    1481         ui_menu_entry_set_disabled(window->sysmenu_restore, false);
    1482         ui_menu_entry_set_disabled(window->sysmenu_maximize, true);
    1483 
    1484         rc = ui_window_size_change(window, &rect, ui_wsc_maximize);
    1485         if (rc != EOK) {
    1486                 ui_wdecor_set_maximized(window->wdecor, false);
    1487                 return rc;
    1488         }
    1489 
    1490         window->normal_rect = old_rect;
    1491         (void) ui_window_paint(window);
    1492         return EOK;
    1493 }
    1494 
    1495 /** Default window unmaximize routine.
    1496  *
    1497  * @param window Window
    1498  * @return EOK on success or an error code
    1499  */
    1500 errno_t ui_window_def_unmaximize(ui_window_t *window)
    1501 {
    1502         errno_t rc;
    1503 
    1504         ui_wdecor_set_maximized(window->wdecor, false);
    1505         ui_menu_entry_set_disabled(window->sysmenu_restore, true);
    1506         ui_menu_entry_set_disabled(window->sysmenu_maximize, false);
    1507 
    1508         rc = ui_window_size_change(window, &window->normal_rect,
    1509             ui_wsc_unmaximize);
    1510         if (rc != EOK) {
    1511                 ui_wdecor_set_maximized(window->wdecor, true);
    1512                 printf("ui_window_size_change->error\n");
    1513                 return rc;
    1514         }
    1515 
    1516         (void) ui_window_paint(window);
    1517         return EOK;
    1518 }
    1519 
    1520 /** Default window keyboard event routine.
    1521  *
    1522  * @param window Window
    1523  * @return ui_claimed iff event was claimed
    1524  */
    1525 ui_evclaim_t ui_window_def_kbd(ui_window_t *window, kbd_event_t *kbd)
    1526 {
    1527         ui_evclaim_t claim;
    1528 
    1529         if (window->control != NULL)
    1530                 claim = ui_control_kbd_event(window->control, kbd);
    1531         else
    1532                 claim = ui_unclaimed;
    1533 
    1534         if (claim == ui_unclaimed)
    1535                 return ui_wdecor_kbd_event(window->wdecor, kbd);
    1536 
    1537         return ui_unclaimed;
     908                return ui_window_def_unfocus(window);
    1538909}
    1539910
     
    1581952 *
    1582953 * @param window Window
    1583  * @param nfocus Number of remaining foci
    1584954 * @return EOK on success or an error code
    1585955 */
    1586 void ui_window_def_unfocus(ui_window_t *window, unsigned nfocus)
     956void ui_window_def_unfocus(ui_window_t *window)
    1587957{
    1588958        if (window->control != NULL)
    1589                 ui_control_unfocus(window->control, nfocus);
    1590 }
    1591 
    1592 /** Default window resize routine.
    1593  *
    1594  * @param window Window
    1595  * @return EOK on success or an error code
    1596  */
    1597 void ui_window_def_resize(ui_window_t *window)
    1598 {
    1599         ui_window_paint(window);
    1600 }
    1601 
    1602 /** Handle system menu left event.
    1603  *
    1604  * @param sysmenu System menu
    1605  * @param arg Argument (ui_window_t *)
    1606  * @param idev_id Input device ID
    1607  */
    1608 static void wnd_sysmenu_left(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
    1609 {
    1610         ui_window_t *window = (ui_window_t *)arg;
    1611 
    1612         if (window->mbar != NULL) {
    1613                 ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
    1614                 ui_menu_close(sysmenu);
    1615                 ui_menu_bar_select_last(window->mbar, true, idev_id);
    1616         }
    1617 }
    1618 
    1619 /** Handle system menu right event.
    1620  *
    1621  * @param sysmenu System menu
    1622  * @param arg Argument (ui_window_t *)
    1623  * @param idev_id Input device ID
    1624  */
    1625 static void wnd_sysmenu_right(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
    1626 {
    1627         ui_window_t *window = (ui_window_t *)arg;
    1628 
    1629         if (window->mbar != NULL) {
    1630                 ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
    1631                 ui_menu_close(sysmenu);
    1632                 ui_menu_bar_select_first(window->mbar, true, idev_id);
    1633         }
    1634 }
    1635 
    1636 /** Handle system menu close request event.
    1637  *
    1638  * @param sysmenu System menu
    1639  * @param arg Argument (ui_window_t *)
    1640  * @param idev_id Input device ID
    1641  */
    1642 static void wnd_sysmenu_close_req(ui_menu_t *sysmenu, void *arg)
    1643 {
    1644         ui_window_t *window = (ui_window_t *)arg;
    1645 
    1646         ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
    1647         ui_menu_close(sysmenu);
    1648 }
    1649 
    1650 /** Handle system menu Restore entry activation.
    1651  *
    1652  * @param mentry Menu entry
    1653  * @param arg Argument (ui_window_t *)
    1654  */
    1655 static void wnd_sysmenu_erestore(ui_menu_entry_t *mentry, void *arg)
    1656 {
    1657         ui_window_t *window = (ui_window_t *)arg;
    1658 
    1659         ui_window_send_unmaximize(window);
    1660 }
    1661 
    1662 /** Handle system menu Minimize entry activation.
    1663  *
    1664  * @param mentry Menu entry
    1665  * @param arg Argument (ui_window_t *)
    1666  */
    1667 static void wnd_sysmenu_eminimize(ui_menu_entry_t *mentry, void *arg)
    1668 {
    1669         ui_window_t *window = (ui_window_t *)arg;
    1670 
    1671         ui_window_send_minimize(window);
    1672 }
    1673 
    1674 /** Handle system menu Maximize entry activation.
    1675  *
    1676  * @param mentry Menu entry
    1677  * @param arg Argument (ui_window_t *)
    1678  */
    1679 static void wnd_sysmenu_emaximize(ui_menu_entry_t *mentry, void *arg)
    1680 {
    1681         ui_window_t *window = (ui_window_t *)arg;
    1682 
    1683         ui_window_send_maximize(window);
    1684 }
    1685 
    1686 /** Handle system menu Close entry activation.
    1687  *
    1688  * @param mentry Menu entry
    1689  * @param arg Argument (ui_window_t *)
    1690  */
    1691 static void wnd_sysmenu_eclose(ui_menu_entry_t *mentry, void *arg)
    1692 {
    1693         ui_window_t *window = (ui_window_t *)arg;
    1694 
    1695         ui_window_send_close(window);
    1696 }
    1697 
    1698 /** Handle system menu press accelerator key event.
    1699  *
    1700  * @param sysmenu System menu
    1701  * @param arg Argument (ui_window_t *)
    1702  * @param idev_id Input device ID
    1703  */
    1704 static void wnd_sysmenu_press_accel(ui_menu_t *sysmenu, void *arg,
    1705     char32_t c, sysarg_t idev_id)
    1706 {
    1707         (void)sysmenu;
    1708         (void)arg;
    1709         (void)c;
    1710         (void)idev_id;
     959                ui_control_unfocus(window->control);
    1711960}
    1712961
     
    1733982        ui_window_t *window = (ui_window_t *) arg;
    1734983
    1735         if (!gfx_rect_is_empty(&window->dirty_rect)) {
    1736                 (void) gfx_bitmap_render(window->bmp, &window->dirty_rect,
    1737                     &window->dpos);
    1738         }
     984        if (!gfx_rect_is_empty(&window->dirty_rect))
     985                (void) gfx_bitmap_render(window->bmp, &window->dirty_rect, NULL);
    1739986
    1740987        window->dirty_rect.p0.x = 0;
     
    1742989        window->dirty_rect.p1.x = 0;
    1743990        window->dirty_rect.p1.y = 0;
    1744 }
    1745 
    1746 /** Window cursor get position callback
    1747  *
    1748  * @param arg Argument (ui_window_t *)
    1749  * @param pos Place to store position
    1750  */
    1751 static errno_t ui_window_cursor_get_pos(void *arg, gfx_coord2_t *pos)
    1752 {
    1753         ui_window_t *window = (ui_window_t *) arg;
    1754         gfx_coord2_t cpos;
    1755         errno_t rc;
    1756 
    1757         rc = gfx_cursor_get_pos(window->realgc, &cpos);
    1758         if (rc != EOK)
    1759                 return rc;
    1760 
    1761         pos->x = cpos.x - window->dpos.x;
    1762         pos->y = cpos.y - window->dpos.y;
    1763         return EOK;
    1764 }
    1765 
    1766 /** Window cursor set position callback
    1767  *
    1768  * @param arg Argument (ui_window_t *)
    1769  * @param pos New position
    1770  */
    1771 static errno_t ui_window_cursor_set_pos(void *arg, gfx_coord2_t *pos)
    1772 {
    1773         ui_window_t *window = (ui_window_t *) arg;
    1774         gfx_coord2_t cpos;
    1775 
    1776         cpos.x = pos->x + window->dpos.x;
    1777         cpos.y = pos->y + window->dpos.y;
    1778 
    1779         return gfx_cursor_set_pos(window->realgc, &cpos);
    1780 }
    1781 
    1782 /** Window cursor set visibility callback
    1783  *
    1784  * @param arg Argument (ui_window_t *)
    1785  * @param visible @c true iff cursor is to be made visible
    1786  */
    1787 static errno_t ui_window_cursor_set_visible(void *arg, bool visible)
    1788 {
    1789         ui_window_t *window = (ui_window_t *) arg;
    1790 
    1791         return gfx_cursor_set_visible(window->realgc, visible);
    1792991}
    1793992
Note: See TracChangeset for help on using the changeset viewer.