Ignore:
File:
1 edited

Legend:

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

    r3d10a2f r39f67f1  
    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        gfx_coord2_t dpos;
     558
     559        if (window->placement != ui_wnd_place_popup) {
     560                ui_window_place(window, &window->ui->rect, &window->rect,
     561                    NULL, window->placement, &window->dpos);
     562                ui_window_set_dpos(window, &dpos);
     563        }
     564
     565        if (window->placement == ui_wnd_place_full_screen) {
     566                (void)ui_window_resize(window, &window->ui->rect);
     567                ui_window_send_resize(window);
     568        }
     569}
     570
    378571/** Destroy window.
    379572 *
     
    383576{
    384577        ui_t *ui;
     578        ui_window_t *nwindow;
    385579
    386580        if (window == NULL)
     
    391585        list_remove(&window->lwindows);
    392586        ui_control_destroy(window->control);
     587        ui_menu_destroy(window->sysmenu);
    393588        ui_wdecor_destroy(window->wdecor);
    394589        ui_resource_destroy(window->res);
    395         if (0 && window->app_mgc != NULL)
     590        if (window->app_mgc != NULL)
    396591                mem_gc_delete(window->app_mgc);
    397         if (0 && window->app_bmp != NULL)
     592        if (window->app_bmp != NULL)
    398593                gfx_bitmap_destroy(window->app_bmp);
    399594        if (window->mgc != NULL) {
     
    406601                display_window_destroy(window->dwindow);
    407602
    408         free(window);
    409 
    410603        /* Need to repaint if windows are emulated */
    411604        if (ui_is_fullscreen(ui)) {
    412                 ui_paint(ui);
    413         }
     605                (void)ui_paint(ui);
     606                /* Send focus event to newly active window */
     607                nwindow = ui_window_get_active(ui);
     608                if (nwindow != NULL)
     609                        ui_window_send_focus(nwindow, 0);
     610        }
     611
     612        if (ui->console != NULL &&
     613            window->placement == ui_wnd_place_full_screen) {
     614                (void) console_set_caption(ui->console, "");
     615        }
     616
     617        free(window);
    414618}
    415619
     
    421625 * @param window Window
    422626 * @param control Control
    423  * @return EOK on success, ENOMEM if out of memory
    424627 */
    425628void ui_window_add(ui_window_t *window, ui_control_t *control)
     
    443646        window->control = NULL;
    444647        control->elemp = NULL;
     648}
     649
     650/** Get first (lowermost) window (only valid in fullscreen mode).
     651 *
     652 * @param ui User interface
     653 * @return First window
     654 */
     655ui_window_t *ui_window_first(ui_t *ui)
     656{
     657        link_t *link;
     658
     659        link = list_first(&ui->windows);
     660        if (link == NULL)
     661                return NULL;
     662
     663        return list_get_instance(link, ui_window_t, lwindows);
     664}
     665
     666/** Get next window (only valid in fullscreen mode).
     667 *
     668 * @param cur Current window
     669 * @return First window
     670 */
     671ui_window_t *ui_window_next(ui_window_t *cur)
     672{
     673        link_t *link;
     674
     675        link = list_next(&cur->lwindows, &cur->ui->windows);
     676        if (link == NULL)
     677                return NULL;
     678
     679        return list_get_instance(link, ui_window_t, lwindows);
    445680}
    446681
     
    461696}
    462697
    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.
     698/** Resize or (un)maximize window.
    467699 *
    468700 * @param window Window
    469701 * @param rect Rectangle
     702 * @param scop Size change operation
    470703 *
    471704 * @return EOK on success or an error code
    472705 */
    473 errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
     706errno_t ui_window_size_change(ui_window_t *window, gfx_rect_t *rect,
     707    ui_wnd_sc_op_t scop)
    474708{
    475709        gfx_coord2_t offs;
     
    482716        gfx_bitmap_alloc_t app_alloc;
    483717        gfx_bitmap_alloc_t win_alloc;
     718        gfx_coord2_t dpos;
    484719        errno_t rc;
    485720
     
    537772        }
    538773
    539         /* dwindow can be NULL in case of unit tests */
     774        /* dwindow can be NULL in case of unit tests or fullscreen mode */
    540775        if (window->dwindow != NULL) {
    541                 rc = display_window_resize(window->dwindow, &offs, &nrect);
    542                 if (rc != EOK)
    543                         goto error;
     776                switch (scop) {
     777                case ui_wsc_resize:
     778                        rc = display_window_resize(window->dwindow, &offs,
     779                            &nrect);
     780                        if (rc != EOK)
     781                                goto error;
     782                        break;
     783                case ui_wsc_maximize:
     784                        rc = display_window_maximize(window->dwindow);
     785                        if (rc != EOK)
     786                                goto error;
     787                        break;
     788                case ui_wsc_unmaximize:
     789                        rc = display_window_unmaximize(window->dwindow);
     790                        if (rc != EOK)
     791                                goto error;
     792                        break;
     793                }
     794        } else {
     795                /* fullscreen mode or unit tests */
     796                switch (scop) {
     797                case ui_wsc_resize:
     798                        break;
     799                case ui_wsc_maximize:
     800                        window->normal_dpos = window->dpos;
     801                        dpos.x = 0;
     802                        dpos.y = 0;
     803                        ui_window_set_dpos(window, &dpos);
     804                        break;
     805                case ui_wsc_unmaximize:
     806                        ui_window_set_dpos(window, &window->normal_dpos);
     807                        break;
     808                }
    544809        }
    545810
     
    549814                /* Window is resized, now we can map the window bitmap again */
    550815                gfx_bitmap_params_init(&win_params);
    551                 win_params.flags |= bmpf_direct_output;
     816                if (window->ui->display != NULL)
     817                        win_params.flags |= bmpf_direct_output;
    552818                win_params.rect = nrect;
    553819
     
    561827                        goto error;
    562828#endif
    563 
    564829                mem_gc_retarget(window->mgc, &win_params.rect, &win_alloc);
    565830
     
    568833        }
    569834
     835        window->rect = nrect;
    570836        ui_wdecor_set_rect(window->wdecor, &nrect);
    571837        ui_wdecor_paint(window->wdecor);
     
    579845                window->app_bmp = app_bmp;
    580846        }
     847
     848        /* Need to repaint UI if windows are emulated */
     849        if (ui_is_fullscreen(window->ui))
     850                (void)ui_paint(window->ui);
    581851
    582852        return EOK;
     
    589859}
    590860
     861/** Resize/move window.
     862 *
     863 * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
     864 * the top-left corner of the window will move on the screen accordingly.
     865 *
     866 * @param window Window
     867 * @param rect Rectangle
     868 *
     869 * @return EOK on success or an error code
     870 */
     871errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
     872{
     873        return ui_window_size_change(window, rect, ui_wsc_resize);
     874}
     875
    591876/** Set window callbacks.
    592877 *
     
    599884        window->cb = cb;
    600885        window->arg = arg;
     886}
     887
     888/** Change window caption.
     889 *
     890 * @param window Window
     891 * @param caption New caption
     892 *
     893 * @return EOK on success or an error code
     894 */
     895errno_t ui_window_set_caption(ui_window_t *window, const char *caption)
     896{
     897        errno_t rc;
     898
     899        /* Set console caption if fullscreen window on console */
     900        if (window->ui->console != NULL && window->placement ==
     901            ui_wnd_place_full_screen) {
     902                rc = console_set_caption(window->ui->console, caption);
     903                if (rc != EOK)
     904                        return rc;
     905        }
     906
     907        /* Set display window caption if running on display service */
     908        if (window->dwindow != NULL) {
     909                rc = display_window_set_caption(window->dwindow, caption);
     910                if (rc != EOK)
     911                        return rc;
     912        }
     913
     914        return ui_wdecor_set_caption(window->wdecor, caption);
    601915}
    602916
     
    7461060{
    7471061        ui_window_t *window = (ui_window_t *) arg;
    748 
     1062        ui_t *ui = window->ui;
     1063
     1064        fibril_mutex_lock(&ui->lock);
    7491065        ui_window_send_close(window);
     1066        fibril_mutex_unlock(&ui->lock);
    7501067}
    7511068
    7521069/** Handle window focus event. */
    753 static void dwnd_focus_event(void *arg)
    754 {
    755         ui_window_t *window = (ui_window_t *) arg;
     1070static void dwnd_focus_event(void *arg, unsigned nfocus)
     1071{
     1072        ui_window_t *window = (ui_window_t *) arg;
     1073        ui_t *ui = window->ui;
     1074
     1075        fibril_mutex_lock(&ui->lock);
     1076        (void)nfocus;
    7561077
    7571078        if (window->wdecor != NULL) {
     
    7601081        }
    7611082
    762         ui_window_send_focus(window);
     1083        ui_window_send_focus(window, nfocus);
     1084        fibril_mutex_unlock(&ui->lock);
    7631085}
    7641086
     
    7671089{
    7681090        ui_window_t *window = (ui_window_t *) arg;
    769 
    770         (void) window;
     1091        ui_t *ui = window->ui;
     1092
     1093        fibril_mutex_lock(&ui->lock);
    7711094        ui_window_send_kbd(window, kbd_event);
     1095        fibril_mutex_unlock(&ui->lock);
    7721096}
    7731097
     
    7761100{
    7771101        ui_window_t *window = (ui_window_t *) arg;
     1102        ui_t *ui = window->ui;
     1103        ui_evclaim_t claim;
    7781104
    7791105        /* Make sure we don't process events until fully initialized */
     
    7811107                return;
    7821108
    783         ui_wdecor_pos_event(window->wdecor, event);
     1109        fibril_mutex_lock(&ui->lock);
     1110
     1111        claim = ui_wdecor_pos_event(window->wdecor, event);
     1112        if (claim == ui_claimed) {
     1113                fibril_mutex_unlock(&ui->lock);
     1114                return;
     1115        }
     1116
    7841117        ui_window_send_pos(window, event);
     1118        fibril_mutex_unlock(&ui->lock);
    7851119}
    7861120
     
    7891123{
    7901124        ui_window_t *window = (ui_window_t *) arg;
     1125        ui_t *ui = window->ui;
    7911126
    7921127        /* Make sure we don't process events until fully initialized */
     
    7971132                return;
    7981133
     1134        fibril_mutex_lock(&ui->lock);
    7991135        (void) ui_window_resize(window, rect);
    800         (void) ui_window_paint(window);
     1136        ui_window_send_resize(window);
     1137        fibril_mutex_unlock(&ui->lock);
    8011138}
    8021139
    8031140/** 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) {
     1141static void dwnd_unfocus_event(void *arg, unsigned nfocus)
     1142{
     1143        ui_window_t *window = (ui_window_t *) arg;
     1144        ui_t *ui = window->ui;
     1145
     1146        fibril_mutex_lock(&ui->lock);
     1147
     1148        if (window->wdecor != NULL && nfocus == 0) {
    8091149                ui_wdecor_set_active(window->wdecor, false);
    8101150                ui_wdecor_paint(window->wdecor);
    8111151        }
    8121152
    813         ui_window_send_unfocus(window);
     1153        ui_window_send_unfocus(window, nfocus);
     1154        fibril_mutex_unlock(&ui->lock);
     1155}
     1156
     1157/** Window decoration requested opening of system menu.
     1158 *
     1159 * @param wdecor Window decoration
     1160 * @param arg Argument (window)
     1161 * @param idev_id Input device ID
     1162 */
     1163static void wd_sysmenu_open(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1164{
     1165        ui_window_t *window = (ui_window_t *) arg;
     1166
     1167        ui_window_send_sysmenu(window, idev_id);
     1168}
     1169
     1170/** Window decoration requested moving left from system menu handle.
     1171 *
     1172 * @param wdecor Window decoration
     1173 * @param arg Argument (window)
     1174 * @param idev_id Input device ID
     1175 */
     1176static void wd_sysmenu_left(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1177{
     1178        ui_window_t *window = (ui_window_t *) arg;
     1179
     1180        if (window->mbar != NULL) {
     1181                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1182                ui_menu_close(window->sysmenu);
     1183                ui_menu_bar_select_last(window->mbar, false, idev_id);
     1184        }
     1185}
     1186
     1187/** Window decoration requested moving right from system menu handle.
     1188 *
     1189 * @param wdecor Window decoration
     1190 * @param arg Argument (window)
     1191 * @param idev_id Input device ID
     1192 */
     1193static void wd_sysmenu_right(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1194{
     1195        ui_window_t *window = (ui_window_t *) arg;
     1196
     1197        if (window->mbar != NULL) {
     1198                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1199                ui_menu_close(window->sysmenu);
     1200                ui_menu_bar_select_first(window->mbar, false, idev_id);
     1201        }
     1202}
     1203
     1204/** Window decoration detected accelerator press from system menu handle.
     1205 *
     1206 * @param wdecor Window decoration
     1207 * @param arg Argument (window)
     1208 * @param c Accelerator key
     1209 * @param idev_id Input device ID
     1210 */
     1211static void wd_sysmenu_accel(ui_wdecor_t *wdecor, void *arg, char32_t c,
     1212    sysarg_t idev_id)
     1213{
     1214        ui_window_t *window = (ui_window_t *) arg;
     1215
     1216        if (window->mbar != NULL) {
     1217                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1218                ui_menu_close(window->sysmenu);
     1219                ui_menu_bar_press_accel(window->mbar, c, idev_id);
     1220        }
     1221}
     1222
     1223/** Window decoration requested window minimization.
     1224 *
     1225 * @param wdecor Window decoration
     1226 * @param arg Argument (window)
     1227 */
     1228static void wd_minimize(ui_wdecor_t *wdecor, void *arg)
     1229{
     1230        ui_window_t *window = (ui_window_t *) arg;
     1231
     1232        ui_window_send_minimize(window);
     1233}
     1234
     1235/** Window decoration requested window maximization.
     1236 *
     1237 * @param wdecor Window decoration
     1238 * @param arg Argument (window)
     1239 */
     1240static void wd_maximize(ui_wdecor_t *wdecor, void *arg)
     1241{
     1242        ui_window_t *window = (ui_window_t *) arg;
     1243
     1244        ui_window_send_maximize(window);
     1245}
     1246
     1247/** Window decoration requested window unmaximization.
     1248 *
     1249 * @param wdecor Window decoration
     1250 * @param arg Argument (window)
     1251 */
     1252static void wd_unmaximize(ui_wdecor_t *wdecor, void *arg)
     1253{
     1254        ui_window_t *window = (ui_window_t *) arg;
     1255
     1256        ui_window_send_unmaximize(window);
    8141257}
    8151258
     
    8311274 * @param arg Argument (window)
    8321275 * @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)
     1276 * @param pos_id Positioning device ID
     1277 */
     1278static void wd_move(ui_wdecor_t *wdecor, void *arg, gfx_coord2_t *pos,
     1279    sysarg_t pos_id)
    8351280{
    8361281        ui_window_t *window = (ui_window_t *) arg;
    8371282
    8381283        if (window->dwindow != NULL)
    839                 (void) display_window_move_req(window->dwindow, pos);
     1284                (void) display_window_move_req(window->dwindow, pos, pos_id);
    8401285}
    8411286
     
    8461291 * @param rsztype Resize type
    8471292 * @param pos Position where the button was pressed
     1293 * @param pos_id Positioning device ID
    8481294 */
    8491295static 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);
     1296    ui_wdecor_rsztype_t rsztype, gfx_coord2_t *pos, sysarg_t pos_id)
     1297{
     1298        ui_window_t *window = (ui_window_t *) arg;
     1299
     1300        if (window->dwindow != NULL) {
     1301                (void) display_window_resize_req(window->dwindow,
     1302                    (display_wnd_rsztype_t) rsztype, // Same constants in the enums
     1303                    pos, pos_id);
     1304        }
    8561305}
    8571306
     
    9141363}
    9151364
     1365/** Send window sysmenu event.
     1366 *
     1367 * @param window Window
     1368 * @parma idev_id Input device ID
     1369 */
     1370void ui_window_send_sysmenu(ui_window_t *window, sysarg_t idev_id)
     1371{
     1372        if (window->cb != NULL && window->cb->sysmenu != NULL)
     1373                window->cb->sysmenu(window, window->arg, idev_id);
     1374        else
     1375                ui_window_def_sysmenu(window, idev_id);
     1376}
     1377
     1378/** Send window minimize event.
     1379 *
     1380 * @param window Window
     1381 */
     1382void ui_window_send_minimize(ui_window_t *window)
     1383{
     1384        if (window->cb != NULL && window->cb->minimize != NULL)
     1385                window->cb->minimize(window, window->arg);
     1386        else
     1387                ui_window_def_minimize(window);
     1388}
     1389
     1390/** Send window maximize event.
     1391 *
     1392 * @param window Window
     1393 */
     1394void ui_window_send_maximize(ui_window_t *window)
     1395{
     1396        if (window->cb != NULL && window->cb->maximize != NULL)
     1397                window->cb->maximize(window, window->arg);
     1398        else
     1399                ui_window_def_maximize(window);
     1400}
     1401
     1402/** Send window unmaximize event.
     1403 *
     1404 * @param window Window
     1405 */
     1406void ui_window_send_unmaximize(ui_window_t *window)
     1407{
     1408        if (window->cb != NULL && window->cb->unmaximize != NULL)
     1409                window->cb->unmaximize(window, window->arg);
     1410        else
     1411                ui_window_def_unmaximize(window);
     1412}
     1413
    9161414/** Send window close event.
    9171415 *
     
    9271425 *
    9281426 * @param window Window
    929  */
    930 void ui_window_send_focus(ui_window_t *window)
     1427 * @param nfocus New number of foci
     1428 */
     1429void ui_window_send_focus(ui_window_t *window, unsigned nfocus)
    9311430{
    9321431        if (window->cb != NULL && window->cb->focus != NULL)
    933                 window->cb->focus(window, window->arg);
     1432                window->cb->focus(window, window->arg, nfocus);
    9341433}
    9351434
     
    9431442                window->cb->kbd(window, window->arg, kbd);
    9441443        else
    945                 return ui_window_def_kbd(window, kbd);
     1444                ui_window_def_kbd(window, kbd);
    9461445}
    9471446
     
    9731472 *
    9741473 * @param window Window
    975  */
    976 void ui_window_send_unfocus(ui_window_t *window)
     1474 * @param nfocus Number of remaining foci
     1475 */
     1476void ui_window_send_unfocus(ui_window_t *window, unsigned nfocus)
    9771477{
    9781478        if (window->cb != NULL && window->cb->unfocus != NULL)
    979                 window->cb->unfocus(window, window->arg);
     1479                window->cb->unfocus(window, window->arg, nfocus);
    9801480        else
    981                 return ui_window_def_unfocus(window);
     1481                return ui_window_def_unfocus(window, nfocus);
     1482}
     1483
     1484/** Send window resize event.
     1485 *
     1486 * @param window Window
     1487 */
     1488void ui_window_send_resize(ui_window_t *window)
     1489{
     1490        if (window->cb != NULL && window->cb->resize != NULL)
     1491                window->cb->resize(window, window->arg);
     1492        else
     1493                return ui_window_def_resize(window);
     1494}
     1495
     1496/** Default window sysmenu routine.
     1497 *
     1498 * @param window Window
     1499 * @param idev_id Input device ID
     1500 * @return EOK on success or an error code
     1501 */
     1502errno_t ui_window_def_sysmenu(ui_window_t *window, sysarg_t idev_id)
     1503{
     1504        errno_t rc;
     1505        ui_wdecor_geom_t geom;
     1506
     1507        if (ui_menu_is_open(window->sysmenu)) {
     1508                ui_menu_close(window->sysmenu);
     1509        } else {
     1510                ui_wdecor_get_geom(window->wdecor, &geom);
     1511
     1512                rc = ui_menu_open(window->sysmenu, &geom.title_bar_rect,
     1513                    idev_id);
     1514                if (rc != EOK)
     1515                        goto error;
     1516        }
     1517
     1518        return EOK;
     1519error:
     1520        return rc;
     1521}
     1522
     1523/** Default window minimize routine.
     1524 *
     1525 * @param window Window
     1526 * @return EOK on success or an error code
     1527 */
     1528errno_t ui_window_def_minimize(ui_window_t *window)
     1529{
     1530        errno_t rc;
     1531
     1532        if (window->dwindow != NULL) {
     1533                rc = display_window_minimize(window->dwindow);
     1534                if (rc != EOK)
     1535                        goto error;
     1536        }
     1537
     1538        return EOK;
     1539error:
     1540        return rc;
     1541}
     1542
     1543/** Default window maximize routine.
     1544 *
     1545 * @param window Window
     1546 * @return EOK on success or an error code
     1547 */
     1548errno_t ui_window_def_maximize(ui_window_t *window)
     1549{
     1550        errno_t rc;
     1551        gfx_rect_t old_rect;
     1552        gfx_rect_t rect;
     1553
     1554        old_rect = window->rect;
     1555
     1556        if (window->dwindow != NULL) {
     1557                rc = display_window_get_max_rect(window->dwindow, &rect);
     1558                if (rc != EOK)
     1559                        return rc;
     1560        } else {
     1561                rect = window->ui->rect;
     1562        }
     1563
     1564        ui_wdecor_set_maximized(window->wdecor, true);
     1565        ui_menu_entry_set_disabled(window->sysmenu_restore, false);
     1566        ui_menu_entry_set_disabled(window->sysmenu_maximize, true);
     1567
     1568        rc = ui_window_size_change(window, &rect, ui_wsc_maximize);
     1569        if (rc != EOK) {
     1570                ui_wdecor_set_maximized(window->wdecor, false);
     1571                return rc;
     1572        }
     1573
     1574        window->normal_rect = old_rect;
     1575        (void) ui_window_paint(window);
     1576        return EOK;
     1577}
     1578
     1579/** Default window unmaximize routine.
     1580 *
     1581 * @param window Window
     1582 * @return EOK on success or an error code
     1583 */
     1584errno_t ui_window_def_unmaximize(ui_window_t *window)
     1585{
     1586        errno_t rc;
     1587
     1588        ui_wdecor_set_maximized(window->wdecor, false);
     1589        ui_menu_entry_set_disabled(window->sysmenu_restore, true);
     1590        ui_menu_entry_set_disabled(window->sysmenu_maximize, false);
     1591
     1592        rc = ui_window_size_change(window, &window->normal_rect,
     1593            ui_wsc_unmaximize);
     1594        if (rc != EOK) {
     1595                ui_wdecor_set_maximized(window->wdecor, true);
     1596                printf("ui_window_size_change->error\n");
     1597                return rc;
     1598        }
     1599
     1600        (void) ui_window_paint(window);
     1601        return EOK;
    9821602}
    9831603
     
    9851605 *
    9861606 * @param window Window
    987  */
    988 void ui_window_def_kbd(ui_window_t *window, kbd_event_t *kbd)
    989 {
     1607 * @return ui_claimed iff event was claimed
     1608 */
     1609ui_evclaim_t ui_window_def_kbd(ui_window_t *window, kbd_event_t *kbd)
     1610{
     1611        ui_evclaim_t claim;
     1612
    9901613        if (window->control != NULL)
    991                 ui_control_kbd_event(window->control, kbd);
     1614                claim = ui_control_kbd_event(window->control, kbd);
     1615        else
     1616                claim = ui_unclaimed;
     1617
     1618        if (claim == ui_unclaimed)
     1619                return ui_wdecor_kbd_event(window->wdecor, kbd);
     1620
     1621        return ui_unclaimed;
    9921622}
    9931623
     
    10351665 *
    10361666 * @param window Window
     1667 * @param nfocus Number of remaining foci
    10371668 * @return EOK on success or an error code
    10381669 */
    1039 void ui_window_def_unfocus(ui_window_t *window)
     1670void ui_window_def_unfocus(ui_window_t *window, unsigned nfocus)
    10401671{
    10411672        if (window->control != NULL)
    1042                 ui_control_unfocus(window->control);
     1673                ui_control_unfocus(window->control, nfocus);
     1674}
     1675
     1676/** Default window resize routine.
     1677 *
     1678 * @param window Window
     1679 * @return EOK on success or an error code
     1680 */
     1681void ui_window_def_resize(ui_window_t *window)
     1682{
     1683        ui_window_paint(window);
     1684}
     1685
     1686/** Handle system menu left event.
     1687 *
     1688 * @param sysmenu System menu
     1689 * @param arg Argument (ui_window_t *)
     1690 * @param idev_id Input device ID
     1691 */
     1692static void wnd_sysmenu_left(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
     1693{
     1694        ui_window_t *window = (ui_window_t *)arg;
     1695
     1696        if (window->mbar != NULL) {
     1697                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1698                ui_menu_close(sysmenu);
     1699                ui_menu_bar_select_last(window->mbar, true, idev_id);
     1700        }
     1701}
     1702
     1703/** Handle system menu right event.
     1704 *
     1705 * @param sysmenu System menu
     1706 * @param arg Argument (ui_window_t *)
     1707 * @param idev_id Input device ID
     1708 */
     1709static void wnd_sysmenu_right(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
     1710{
     1711        ui_window_t *window = (ui_window_t *)arg;
     1712
     1713        if (window->mbar != NULL) {
     1714                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1715                ui_menu_close(sysmenu);
     1716                ui_menu_bar_select_first(window->mbar, true, idev_id);
     1717        }
     1718}
     1719
     1720/** Handle system menu close request event.
     1721 *
     1722 * @param sysmenu System menu
     1723 * @param arg Argument (ui_window_t *)
     1724 * @param idev_id Input device ID
     1725 */
     1726static void wnd_sysmenu_close_req(ui_menu_t *sysmenu, void *arg)
     1727{
     1728        ui_window_t *window = (ui_window_t *)arg;
     1729
     1730        ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1731        ui_menu_close(sysmenu);
     1732}
     1733
     1734/** Handle system menu Restore entry activation.
     1735 *
     1736 * @param mentry Menu entry
     1737 * @param arg Argument (ui_window_t *)
     1738 */
     1739static void wnd_sysmenu_erestore(ui_menu_entry_t *mentry, void *arg)
     1740{
     1741        ui_window_t *window = (ui_window_t *)arg;
     1742
     1743        ui_window_send_unmaximize(window);
     1744}
     1745
     1746/** Handle system menu Minimize entry activation.
     1747 *
     1748 * @param mentry Menu entry
     1749 * @param arg Argument (ui_window_t *)
     1750 */
     1751static void wnd_sysmenu_eminimize(ui_menu_entry_t *mentry, void *arg)
     1752{
     1753        ui_window_t *window = (ui_window_t *)arg;
     1754
     1755        ui_window_send_minimize(window);
     1756}
     1757
     1758/** Handle system menu Maximize entry activation.
     1759 *
     1760 * @param mentry Menu entry
     1761 * @param arg Argument (ui_window_t *)
     1762 */
     1763static void wnd_sysmenu_emaximize(ui_menu_entry_t *mentry, void *arg)
     1764{
     1765        ui_window_t *window = (ui_window_t *)arg;
     1766
     1767        ui_window_send_maximize(window);
     1768}
     1769
     1770/** Handle system menu Close entry activation.
     1771 *
     1772 * @param mentry Menu entry
     1773 * @param arg Argument (ui_window_t *)
     1774 */
     1775static void wnd_sysmenu_eclose(ui_menu_entry_t *mentry, void *arg)
     1776{
     1777        ui_window_t *window = (ui_window_t *)arg;
     1778
     1779        ui_window_send_close(window);
     1780}
     1781
     1782/** Handle system menu press accelerator key event.
     1783 *
     1784 * @param sysmenu System menu
     1785 * @param arg Argument (ui_window_t *)
     1786 * @param idev_id Input device ID
     1787 */
     1788static void wnd_sysmenu_press_accel(ui_menu_t *sysmenu, void *arg,
     1789    char32_t c, sysarg_t idev_id)
     1790{
     1791        (void)sysmenu;
     1792        (void)arg;
     1793        (void)c;
     1794        (void)idev_id;
    10431795}
    10441796
Note: See TracChangeset for help on using the changeset viewer.