Ignore:
File:
1 edited

Legend:

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

    r3d10a2f rb979ffb  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4747#include <stdlib.h>
    4848#include <ui/control.h>
     49#include <ui/menubar.h>
     50#include <ui/menu.h>
     51#include <ui/menuentry.h>
    4952#include <ui/resource.h>
    5053#include <ui/ui.h>
     
    5962
    6063static void dwnd_close_event(void *);
    61 static void dwnd_focus_event(void *);
     64static void dwnd_focus_event(void *, unsigned);
    6265static void dwnd_kbd_event(void *, kbd_event_t *);
    6366static void dwnd_pos_event(void *, pos_event_t *);
    6467static void dwnd_resize_event(void *, gfx_rect_t *);
    65 static void dwnd_unfocus_event(void *);
     68static void dwnd_unfocus_event(void *, unsigned);
    6669
    6770static display_wnd_cb_t dwnd_cb = {
     
    7477};
    7578
     79static void wd_sysmenu_open(ui_wdecor_t *, void *, sysarg_t);
     80static void wd_sysmenu_left(ui_wdecor_t *, void *, sysarg_t);
     81static void wd_sysmenu_right(ui_wdecor_t *, void *, sysarg_t);
     82static void wd_sysmenu_accel(ui_wdecor_t *, void *, char32_t, sysarg_t);
     83static void wd_minimize(ui_wdecor_t *, void *);
     84static void wd_maximize(ui_wdecor_t *, void *);
     85static void wd_unmaximize(ui_wdecor_t *, void *);
    7686static void wd_close(ui_wdecor_t *, void *);
    77 static void wd_move(ui_wdecor_t *, void *, gfx_coord2_t *);
     87static void wd_move(ui_wdecor_t *, void *, gfx_coord2_t *, sysarg_t);
    7888static void wd_resize(ui_wdecor_t *, void *, ui_wdecor_rsztype_t,
    79     gfx_coord2_t *);
     89    gfx_coord2_t *, sysarg_t);
    8090static void wd_set_cursor(ui_wdecor_t *, void *, ui_stock_cursor_t);
    8191
    8292static 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,
    83100        .close = wd_close,
    84101        .move = wd_move,
     
    86103        .set_cursor = wd_set_cursor
    87104};
     105
     106static void wnd_sysmenu_left(ui_menu_t *, void *, sysarg_t);
     107static void wnd_sysmenu_right(ui_menu_t *, void *, sysarg_t);
     108static void wnd_sysmenu_close_req(ui_menu_t *, void *);
     109static void wnd_sysmenu_press_accel(ui_menu_t *, void *, char32_t, sysarg_t);
     110
     111static ui_menu_cb_t wnd_sysmenu_cb = {
     112        .left = wnd_sysmenu_left,
     113        .right = wnd_sysmenu_right,
     114        .close_req = wnd_sysmenu_close_req,
     115        .press_accel = wnd_sysmenu_press_accel
     116};
     117
     118static void wnd_sysmenu_erestore(ui_menu_entry_t *, void *);
     119static void wnd_sysmenu_eminimize(ui_menu_entry_t *, void *);
     120static void wnd_sysmenu_emaximize(ui_menu_entry_t *, void *);
     121static void wnd_sysmenu_eclose(ui_menu_entry_t *, void *);
    88122
    89123static void ui_window_invalidate(void *, gfx_rect_t *);
     
    137171 * @param window Window
    138172 * @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
    139176 * @param params Window parameters
    140177 * @param pos Place to store position of top-left corner
    141178 */
    142179static void ui_window_place(ui_window_t *window, gfx_rect_t *drect,
    143     ui_wnd_params_t *params, gfx_coord2_t *pos)
     180    gfx_rect_t *wrect, gfx_rect_t *prect, ui_wnd_placement_t placement,
     181    gfx_coord2_t *pos)
    144182{
    145183        gfx_coord2_t dims;
    146 
    147         assert(params->placement != ui_wnd_place_default ||
     184        gfx_coord2_t below_pos;
     185        gfx_rect_t below_rect;
     186
     187        assert(placement != ui_wnd_place_default ||
    148188            ui_is_fullscreen(window->ui));
    149189
     
    151191        pos->y = 0;
    152192
    153         switch (params->placement) {
     193        switch (placement) {
    154194        case ui_wnd_place_default:
    155                 assert(ui_is_fullscreen(window->ui));
     195        case ui_wnd_place_center:
     196                assert(placement != ui_wnd_place_default ||
     197                    ui_is_fullscreen(window->ui));
    156198                /* Center window */
    157                 gfx_rect_dims(&params->rect, &dims);
     199                gfx_rect_dims(wrect, &dims);
    158200                pos->x = (drect->p0.x + drect->p1.x) / 2 - dims.x / 2;
    159201                pos->y = (drect->p0.y + drect->p1.y) / 2 - dims.y / 2;
     
    161203        case ui_wnd_place_top_left:
    162204        case ui_wnd_place_full_screen:
    163                 pos->x = drect->p0.x - params->rect.p0.x;
    164                 pos->y = drect->p0.y - params->rect.p0.y;
     205                pos->x = drect->p0.x - wrect->p0.x;
     206                pos->y = drect->p0.y - wrect->p0.y;
    165207                break;
    166208        case ui_wnd_place_top_right:
    167                 pos->x = drect->p1.x - params->rect.p1.x;
    168                 pos->y = drect->p0.y - params->rect.p0.y;
     209                pos->x = drect->p1.x - wrect->p1.x;
     210                pos->y = drect->p0.y - wrect->p0.y;
    169211                break;
    170212        case ui_wnd_place_bottom_left:
    171                 pos->x = drect->p0.x - params->rect.p0.x;
    172                 pos->y = drect->p1.y - params->rect.p1.y;
     213                pos->x = drect->p0.x - wrect->p0.x;
     214                pos->y = drect->p1.y - wrect->p1.y;
    173215                break;
    174216        case ui_wnd_place_bottom_right:
    175                 pos->x = drect->p1.x - params->rect.p1.x;
    176                 pos->y = drect->p1.y - params->rect.p1.y;
     217                pos->x = drect->p1.x - wrect->p1.x;
     218                pos->y = drect->p1.y - wrect->p1.y;
    177219                break;
    178220        case ui_wnd_place_popup:
    179                 /* Place popup window below parent rectangle */
    180                 pos->x = params->prect.p0.x;
    181                 pos->y = params->prect.p1.y;
     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                }
    182237                break;
    183238        }
     239}
     240
     241static 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 */
     253static 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;
     318error:
     319        return rc;
    184320}
    185321
     
    195331{
    196332        ui_window_t *window;
     333        ui_window_t *pwindow = NULL;
    197334        display_info_t info;
    198335        gfx_coord2_t scr_dims;
     
    208345        mem_gc_t *memgc = NULL;
    209346        xlate_gc_t *xgc = NULL;
     347        gfx_coord2_t dpos;
    210348        errno_t rc;
    211349
     
    218356        display_wnd_params_init(&dparams);
    219357        dparams.rect = params->rect;
    220         /* Only allow making the window larger */
    221         gfx_rect_dims(&params->rect, &dparams.min_size);
     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;
    222370
    223371        if ((params->flags & ui_wndf_popup) != 0)
    224372                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;
    225381
    226382        if (ui->display != NULL) {
     
    240396                if (params->placement != ui_wnd_place_default) {
    241397                        /* Set initial display window position */
    242                         ui_window_place(window, &info.rect, params,
    243                             &dparams.pos);
     398                        ui_window_place(window, &info.rect, &params->rect,
     399                            &params->prect, params->placement, &dparams.pos);
    244400
    245401                        dparams.flags |= wndf_setpos;
     
    262418                        gfx_coord2_add(&dparams.rect.p0, &scr_dims,
    263419                            &dparams.rect.p1);
     420                        (void) console_set_caption(ui->console,
     421                            params->caption);
    264422                }
    265423        } else {
     
    331489#endif
    332490        if (ui->display == NULL) {
    333                 ui_window_place(window, &ui->rect, params, &window->dpos);
    334 
    335                 if (window->xgc != NULL)
    336                         xlate_gc_set_off(window->xgc, &window->dpos);
     491                ui_window_place(window, &ui->rect, &params->rect, &params->prect,
     492                    params->placement, &dpos);
     493                ui_window_set_dpos(window, &dpos);
    337494        }
    338495
     
    355512        window->wdecor = wdecor;
    356513        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
    357520        *rwindow = window;
    358521
     522        if (ui_is_fullscreen(ui))
     523                pwindow = ui_window_get_active(ui);
     524
    359525        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
    360533        return EOK;
    361534error:
     
    376549}
    377550
     551/** Update window placement after screen resize (only in fullscreen UI).
     552 *
     553 * @param window UI window
     554 */
     555void 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
    378565/** Destroy window.
    379566 *
     
    383570{
    384571        ui_t *ui;
     572        ui_window_t *nwindow;
    385573
    386574        if (window == NULL)
     
    391579        list_remove(&window->lwindows);
    392580        ui_control_destroy(window->control);
     581        ui_menu_destroy(window->sysmenu);
    393582        ui_wdecor_destroy(window->wdecor);
    394583        ui_resource_destroy(window->res);
    395         if (0 && window->app_mgc != NULL)
     584        if (window->app_mgc != NULL)
    396585                mem_gc_delete(window->app_mgc);
    397         if (0 && window->app_bmp != NULL)
     586        if (window->app_bmp != NULL)
    398587                gfx_bitmap_destroy(window->app_bmp);
    399588        if (window->mgc != NULL) {
     
    406595                display_window_destroy(window->dwindow);
    407596
    408         free(window);
    409 
    410597        /* Need to repaint if windows are emulated */
    411598        if (ui_is_fullscreen(ui)) {
    412                 ui_paint(ui);
    413         }
     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
     611        free(window);
    414612}
    415613
     
    421619 * @param window Window
    422620 * @param control Control
    423  * @return EOK on success, ENOMEM if out of memory
    424621 */
    425622void ui_window_add(ui_window_t *window, ui_control_t *control)
     
    443640        window->control = NULL;
    444641        control->elemp = NULL;
     642}
     643
     644/** Get first (lowermost) window (only valid in fullscreen mode).
     645 *
     646 * @param ui User interface
     647 * @return First window
     648 */
     649ui_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 */
     665ui_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);
    445674}
    446675
     
    461690}
    462691
    463 /** Resize/move window.
    464  *
    465  * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
    466  * the top-left corner of the window will move on the screen accordingly.
     692/** Resize or (un)maximize window.
    467693 *
    468694 * @param window Window
    469695 * @param rect Rectangle
     696 * @param scop Size change operation
    470697 *
    471698 * @return EOK on success or an error code
    472699 */
    473 errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
     700errno_t ui_window_size_change(ui_window_t *window, gfx_rect_t *rect,
     701    ui_wnd_sc_op_t scop)
    474702{
    475703        gfx_coord2_t offs;
     
    482710        gfx_bitmap_alloc_t app_alloc;
    483711        gfx_bitmap_alloc_t win_alloc;
     712        gfx_coord2_t dpos;
    484713        errno_t rc;
    485714
     
    537766        }
    538767
    539         /* dwindow can be NULL in case of unit tests */
     768        /* dwindow can be NULL in case of unit tests or fullscreen mode */
    540769        if (window->dwindow != NULL) {
    541                 rc = display_window_resize(window->dwindow, &offs, &nrect);
    542                 if (rc != EOK)
    543                         goto error;
     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                }
    544803        }
    545804
     
    549808                /* Window is resized, now we can map the window bitmap again */
    550809                gfx_bitmap_params_init(&win_params);
    551                 win_params.flags |= bmpf_direct_output;
     810                if (window->ui->display != NULL)
     811                        win_params.flags |= bmpf_direct_output;
    552812                win_params.rect = nrect;
    553813
     
    561821                        goto error;
    562822#endif
    563 
    564823                mem_gc_retarget(window->mgc, &win_params.rect, &win_alloc);
    565824
     
    568827        }
    569828
     829        window->rect = nrect;
    570830        ui_wdecor_set_rect(window->wdecor, &nrect);
    571831        ui_wdecor_paint(window->wdecor);
     
    578838                gfx_bitmap_destroy(window->app_bmp);
    579839                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;
    580851        }
    581852
     
    589860}
    590861
     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 */
     872errno_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
    591887/** Set window callbacks.
    592888 *
     
    599895        window->cb = cb;
    600896        window->arg = arg;
     897}
     898
     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 */
     906errno_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);
    601926}
    602927
     
    7461071{
    7471072        ui_window_t *window = (ui_window_t *) arg;
    748 
     1073        ui_t *ui = window->ui;
     1074
     1075        fibril_mutex_lock(&ui->lock);
    7491076        ui_window_send_close(window);
     1077        fibril_mutex_unlock(&ui->lock);
    7501078}
    7511079
    7521080/** Handle window focus event. */
    753 static void dwnd_focus_event(void *arg)
    754 {
    755         ui_window_t *window = (ui_window_t *) arg;
     1081static 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;
    7561088
    7571089        if (window->wdecor != NULL) {
     
    7601092        }
    7611093
    762         ui_window_send_focus(window);
     1094        ui_window_send_focus(window, nfocus);
     1095        fibril_mutex_unlock(&ui->lock);
    7631096}
    7641097
     
    7671100{
    7681101        ui_window_t *window = (ui_window_t *) arg;
    769 
    770         (void) window;
     1102        ui_t *ui = window->ui;
     1103
     1104        fibril_mutex_lock(&ui->lock);
    7711105        ui_window_send_kbd(window, kbd_event);
     1106        fibril_mutex_unlock(&ui->lock);
    7721107}
    7731108
     
    7761111{
    7771112        ui_window_t *window = (ui_window_t *) arg;
     1113        ui_t *ui = window->ui;
     1114        ui_evclaim_t claim;
    7781115
    7791116        /* Make sure we don't process events until fully initialized */
     
    7811118                return;
    7821119
    783         ui_wdecor_pos_event(window->wdecor, event);
     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
    7841128        ui_window_send_pos(window, event);
     1129        fibril_mutex_unlock(&ui->lock);
    7851130}
    7861131
     
    7891134{
    7901135        ui_window_t *window = (ui_window_t *) arg;
     1136        ui_t *ui = window->ui;
    7911137
    7921138        /* Make sure we don't process events until fully initialized */
     
    7971143                return;
    7981144
     1145        fibril_mutex_lock(&ui->lock);
    7991146        (void) ui_window_resize(window, rect);
    800         (void) ui_window_paint(window);
     1147        ui_window_send_resize(window);
     1148        fibril_mutex_unlock(&ui->lock);
    8011149}
    8021150
    8031151/** Handle window unfocus event. */
    804 static void dwnd_unfocus_event(void *arg)
    805 {
    806         ui_window_t *window = (ui_window_t *) arg;
    807 
    808         if (window->wdecor != NULL) {
     1152static 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) {
    8091160                ui_wdecor_set_active(window->wdecor, false);
    8101161                ui_wdecor_paint(window->wdecor);
    8111162        }
    8121163
    813         ui_window_send_unfocus(window);
     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 */
     1174static 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 */
     1187static 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 */
     1204static 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 */
     1222static 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 */
     1239static 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 */
     1251static 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 */
     1263static 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);
    8141268}
    8151269
     
    8311285 * @param arg Argument (window)
    8321286 * @param pos Position where the title bar was pressed
    833  */
    834 static void wd_move(ui_wdecor_t *wdecor, void *arg, gfx_coord2_t *pos)
     1287 * @param pos_id Positioning device ID
     1288 */
     1289static void wd_move(ui_wdecor_t *wdecor, void *arg, gfx_coord2_t *pos,
     1290    sysarg_t pos_id)
    8351291{
    8361292        ui_window_t *window = (ui_window_t *) arg;
    8371293
    8381294        if (window->dwindow != NULL)
    839                 (void) display_window_move_req(window->dwindow, pos);
     1295                (void) display_window_move_req(window->dwindow, pos, pos_id);
    8401296}
    8411297
     
    8461302 * @param rsztype Resize type
    8471303 * @param pos Position where the button was pressed
     1304 * @param pos_id Positioning device ID
    8481305 */
    8491306static void wd_resize(ui_wdecor_t *wdecor, void *arg,
    850     ui_wdecor_rsztype_t rsztype, gfx_coord2_t *pos)
    851 {
    852         ui_window_t *window = (ui_window_t *) arg;
    853 
    854         if (window->dwindow != NULL)
    855                 (void) display_window_resize_req(window->dwindow, rsztype, pos);
     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        }
    8561316}
    8571317
     
    9141374}
    9151375
     1376/** Send window sysmenu event.
     1377 *
     1378 * @param window Window
     1379 * @parma idev_id Input device ID
     1380 */
     1381void 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 */
     1393void 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 */
     1405void 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 */
     1417void 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);
     1423}
     1424
    9161425/** Send window close event.
    9171426 *
     
    9271436 *
    9281437 * @param window Window
    929  */
    930 void ui_window_send_focus(ui_window_t *window)
     1438 * @param nfocus New number of foci
     1439 */
     1440void ui_window_send_focus(ui_window_t *window, unsigned nfocus)
    9311441{
    9321442        if (window->cb != NULL && window->cb->focus != NULL)
    933                 window->cb->focus(window, window->arg);
     1443                window->cb->focus(window, window->arg, nfocus);
    9341444}
    9351445
     
    9431453                window->cb->kbd(window, window->arg, kbd);
    9441454        else
    945                 return ui_window_def_kbd(window, kbd);
     1455                ui_window_def_kbd(window, kbd);
    9461456}
    9471457
     
    9731483 *
    9741484 * @param window Window
    975  */
    976 void ui_window_send_unfocus(ui_window_t *window)
     1485 * @param nfocus Number of remaining foci
     1486 */
     1487void ui_window_send_unfocus(ui_window_t *window, unsigned nfocus)
    9771488{
    9781489        if (window->cb != NULL && window->cb->unfocus != NULL)
    979                 window->cb->unfocus(window, window->arg);
     1490                window->cb->unfocus(window, window->arg, nfocus);
    9801491        else
    981                 return ui_window_def_unfocus(window);
     1492                return ui_window_def_unfocus(window, nfocus);
     1493}
     1494
     1495/** Send window resize event.
     1496 *
     1497 * @param window Window
     1498 */
     1499void 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 */
     1513errno_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;
     1530error:
     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 */
     1539errno_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;
     1550error:
     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 */
     1559errno_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 */
     1600errno_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;
    9821623}
    9831624
     
    9851626 *
    9861627 * @param window Window
    987  */
    988 void ui_window_def_kbd(ui_window_t *window, kbd_event_t *kbd)
    989 {
     1628 * @return ui_claimed iff event was claimed
     1629 */
     1630ui_evclaim_t ui_window_def_kbd(ui_window_t *window, kbd_event_t *kbd)
     1631{
     1632        ui_evclaim_t claim;
     1633
    9901634        if (window->control != NULL)
    991                 ui_control_kbd_event(window->control, kbd);
     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;
    9921643}
    9931644
     
    10351686 *
    10361687 * @param window Window
     1688 * @param nfocus Number of remaining foci
    10371689 * @return EOK on success or an error code
    10381690 */
    1039 void ui_window_def_unfocus(ui_window_t *window)
     1691void ui_window_def_unfocus(ui_window_t *window, unsigned nfocus)
    10401692{
    10411693        if (window->control != NULL)
    1042                 ui_control_unfocus(window->control);
     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 */
     1702void 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 */
     1713static 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 */
     1730static 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 */
     1747static 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 */
     1760static 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 */
     1772static 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 */
     1784static 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 */
     1796static 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 */
     1809static 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;
    10431816}
    10441817
Note: See TracChangeset for help on using the changeset viewer.