Ignore:
File:
1 edited

Legend:

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

    rb979ffb rec50d65e  
    11/*
    2  * Copyright (c) 2026 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    171171 * @param window Window
    172172 * @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
    176173 * @param params Window parameters
    177174 * @param pos Place to store position of top-left corner
    178175 */
    179176static void ui_window_place(ui_window_t *window, gfx_rect_t *drect,
    180     gfx_rect_t *wrect, gfx_rect_t *prect, ui_wnd_placement_t placement,
    181     gfx_coord2_t *pos)
     177    ui_wnd_params_t *params, gfx_coord2_t *pos)
    182178{
    183179        gfx_coord2_t dims;
     
    185181        gfx_rect_t below_rect;
    186182
    187         assert(placement != ui_wnd_place_default ||
     183        assert(params->placement != ui_wnd_place_default ||
    188184            ui_is_fullscreen(window->ui));
    189185
     
    191187        pos->y = 0;
    192188
    193         switch (placement) {
     189        switch (params->placement) {
    194190        case ui_wnd_place_default:
    195         case ui_wnd_place_center:
    196                 assert(placement != ui_wnd_place_default ||
    197                     ui_is_fullscreen(window->ui));
     191                assert(ui_is_fullscreen(window->ui));
    198192                /* Center window */
    199                 gfx_rect_dims(wrect, &dims);
     193                gfx_rect_dims(&params->rect, &dims);
    200194                pos->x = (drect->p0.x + drect->p1.x) / 2 - dims.x / 2;
    201195                pos->y = (drect->p0.y + drect->p1.y) / 2 - dims.y / 2;
     
    203197        case ui_wnd_place_top_left:
    204198        case ui_wnd_place_full_screen:
    205                 pos->x = drect->p0.x - wrect->p0.x;
    206                 pos->y = drect->p0.y - wrect->p0.y;
     199                pos->x = drect->p0.x - params->rect.p0.x;
     200                pos->y = drect->p0.y - params->rect.p0.y;
    207201                break;
    208202        case ui_wnd_place_top_right:
    209                 pos->x = drect->p1.x - wrect->p1.x;
    210                 pos->y = drect->p0.y - wrect->p0.y;
     203                pos->x = drect->p1.x - params->rect.p1.x;
     204                pos->y = drect->p0.y - params->rect.p0.y;
    211205                break;
    212206        case ui_wnd_place_bottom_left:
    213                 pos->x = drect->p0.x - wrect->p0.x;
    214                 pos->y = drect->p1.y - wrect->p1.y;
     207                pos->x = drect->p0.x - params->rect.p0.x;
     208                pos->y = drect->p1.y - params->rect.p1.y;
    215209                break;
    216210        case ui_wnd_place_bottom_right:
    217                 pos->x = drect->p1.x - wrect->p1.x;
    218                 pos->y = drect->p1.y - wrect->p1.y;
     211                pos->x = drect->p1.x - params->rect.p1.x;
     212                pos->y = drect->p1.y - params->rect.p1.y;
    219213                break;
    220214        case ui_wnd_place_popup:
    221215                /* 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);
     216                below_pos.x = params->prect.p0.x;
     217                below_pos.y = params->prect.p1.y;
     218                gfx_rect_translate(&below_pos, &params->rect, &below_rect);
    225219
    226220                /* Does below_rect fit within the display? */
    227221                if (gfx_rect_is_inside(&below_rect, drect)) {
    228222                        /* Place popup window below parent rectangle */
    229                         pos->x = prect->p0.x - wrect->p0.x;
    230                         pos->y = prect->p1.y - wrect->p0.y;
     223                        pos->x = params->prect.p0.x - params->rect.p0.x;
     224                        pos->y = params->prect.p1.y - params->rect.p0.y;
    231225                } else {
    232226                        /* 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);
     227                        pos->x = params->prect.p0.x;
     228                        pos->y = params->prect.p0.y -
     229                            (params->rect.p1.y - params->rect.p0.y);
    236230                }
    237231                break;
    238232        }
    239 }
    240 
    241 static void ui_window_set_dpos(ui_window_t *window, gfx_coord2_t *dpos)
    242 {
    243         window->dpos = *dpos;
    244         if (window->xgc != NULL)
    245                 xlate_gc_set_off(window->xgc, &window->dpos);
    246233}
    247234
     
    345332        mem_gc_t *memgc = NULL;
    346333        xlate_gc_t *xgc = NULL;
    347         gfx_coord2_t dpos;
    348334        errno_t rc;
    349335
     
    357343        dparams.rect = params->rect;
    358344        dparams.caption = params->caption;
    359         dparams.min_size = params->min_size;
     345        /* Only allow making the window larger */
     346        gfx_rect_dims(&params->rect, &dparams.min_size);
    360347
    361348        /*
     
    371358        if ((params->flags & ui_wndf_popup) != 0)
    372359                dparams.flags |= wndf_popup;
    373         if ((params->flags & ui_wndf_nofocus) != 0)
    374                 dparams.flags |= wndf_nofocus;
    375360        if ((params->flags & ui_wndf_topmost) != 0)
    376361                dparams.flags |= wndf_topmost;
     
    396381                if (params->placement != ui_wnd_place_default) {
    397382                        /* Set initial display window position */
    398                         ui_window_place(window, &info.rect, &params->rect,
    399                             &params->prect, params->placement, &dparams.pos);
     383                        ui_window_place(window, &info.rect, params,
     384                            &dparams.pos);
    400385
    401386                        dparams.flags |= wndf_setpos;
     
    489474#endif
    490475        if (ui->display == NULL) {
    491                 ui_window_place(window, &ui->rect, &params->rect, &params->prect,
    492                     params->placement, &dpos);
    493                 ui_window_set_dpos(window, &dpos);
     476                ui_window_place(window, &ui->rect, params, &window->dpos);
     477
     478                if (window->xgc != NULL)
     479                        xlate_gc_set_off(window->xgc, &window->dpos);
    494480        }
    495481
     
    549535}
    550536
    551 /** Update window placement after screen resize (only in fullscreen UI).
    552  *
    553  * @param window UI window
    554  */
    555 void ui_window_update_placement(ui_window_t *window)
    556 {
    557         if (window->placement == ui_wnd_place_full_screen ||
    558             (window->flags & uiwf_maximized) != 0) {
    559                 /* Update size of fullscreen or maximized window. */
    560                 (void)ui_window_resize(window, &window->ui->rect);
    561                 ui_window_send_resize(window);
    562         }
    563 }
    564 
    565537/** Destroy window.
    566538 *
     
    597569        /* Need to repaint if windows are emulated */
    598570        if (ui_is_fullscreen(ui)) {
    599                 (void)ui_paint(ui);
     571                ui_paint(ui);
    600572                /* Send focus event to newly active window */
    601573                nwindow = ui_window_get_active(ui);
     
    640612        window->control = NULL;
    641613        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  */
    649 ui_window_t *ui_window_first(ui_t *ui)
    650 {
    651         link_t *link;
    652 
    653         link = list_first(&ui->windows);
    654         if (link == NULL)
    655                 return NULL;
    656 
    657         return list_get_instance(link, ui_window_t, lwindows);
    658 }
    659 
    660 /** Get next window (only valid in fullscreen mode).
    661  *
    662  * @param cur Current window
    663  * @return First window
    664  */
    665 ui_window_t *ui_window_next(ui_window_t *cur)
    666 {
    667         link_t *link;
    668 
    669         link = list_next(&cur->lwindows, &cur->ui->windows);
    670         if (link == NULL)
    671                 return NULL;
    672 
    673         return list_get_instance(link, ui_window_t, lwindows);
    674614}
    675615
     
    710650        gfx_bitmap_alloc_t app_alloc;
    711651        gfx_bitmap_alloc_t win_alloc;
    712         gfx_coord2_t dpos;
    713652        errno_t rc;
    714653
     
    786725                        break;
    787726                }
    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                 }
    803727        }
    804728
     
    808732                /* Window is resized, now we can map the window bitmap again */
    809733                gfx_bitmap_params_init(&win_params);
    810                 if (window->ui->display != NULL)
    811                         win_params.flags |= bmpf_direct_output;
     734                win_params.flags |= bmpf_direct_output;
    812735                win_params.rect = nrect;
    813736
     
    838761                gfx_bitmap_destroy(window->app_bmp);
    839762                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;
    851763        }
    852764
     
    872784errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
    873785{
    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;
     786        return ui_window_size_change(window, rect, ui_wsc_resize);
    885787}
    886788
     
    1073975        ui_t *ui = window->ui;
    1074976
    1075         fibril_mutex_lock(&ui->lock);
     977        ui_lock(ui);
    1076978        ui_window_send_close(window);
    1077         fibril_mutex_unlock(&ui->lock);
     979        ui_unlock(ui);
    1078980}
    1079981
     
    1084986        ui_t *ui = window->ui;
    1085987
    1086         fibril_mutex_lock(&ui->lock);
     988        ui_lock(ui);
    1087989        (void)nfocus;
    1088990
     
    1093995
    1094996        ui_window_send_focus(window, nfocus);
    1095         fibril_mutex_unlock(&ui->lock);
     997        ui_unlock(ui);
    1096998}
    1097999
     
    11021004        ui_t *ui = window->ui;
    11031005
    1104         fibril_mutex_lock(&ui->lock);
     1006        ui_lock(ui);
    11051007        ui_window_send_kbd(window, kbd_event);
    1106         fibril_mutex_unlock(&ui->lock);
     1008        ui_unlock(ui);
    11071009}
    11081010
     
    11181020                return;
    11191021
    1120         fibril_mutex_lock(&ui->lock);
     1022        ui_lock(ui);
    11211023
    11221024        claim = ui_wdecor_pos_event(window->wdecor, event);
    11231025        if (claim == ui_claimed) {
    1124                 fibril_mutex_unlock(&ui->lock);
     1026                ui_unlock(ui);
    11251027                return;
    11261028        }
    11271029
    11281030        ui_window_send_pos(window, event);
    1129         fibril_mutex_unlock(&ui->lock);
     1031        ui_unlock(ui);
    11301032}
    11311033
     
    11431045                return;
    11441046
    1145         fibril_mutex_lock(&ui->lock);
     1047        ui_lock(ui);
    11461048        (void) ui_window_resize(window, rect);
    1147         ui_window_send_resize(window);
    1148         fibril_mutex_unlock(&ui->lock);
     1049        (void) ui_window_paint(window);
     1050        ui_unlock(ui);
    11491051}
    11501052
     
    11551057        ui_t *ui = window->ui;
    11561058
    1157         fibril_mutex_lock(&ui->lock);
     1059        ui_lock(ui);
    11581060
    11591061        if (window->wdecor != NULL && nfocus == 0) {
     
    11631065
    11641066        ui_window_send_unfocus(window, nfocus);
    1165         fibril_mutex_unlock(&ui->lock);
     1067        ui_unlock(ui);
    11661068}
    11671069
     
    13931295void ui_window_send_minimize(ui_window_t *window)
    13941296{
    1395         if (window->cb != NULL && window->cb->minimize != NULL)
     1297        if (window->cb != NULL && window->cb->maximize != NULL)
    13961298                window->cb->minimize(window, window->arg);
    13971299        else
     
    14911393        else
    14921394                return ui_window_def_unfocus(window, nfocus);
    1493 }
    1494 
    1495 /** Send window resize event.
    1496  *
    1497  * @param window Window
    1498  */
    1499 void ui_window_send_resize(ui_window_t *window)
    1500 {
    1501         if (window->cb != NULL && window->cb->resize != NULL)
    1502                 window->cb->resize(window, window->arg);
    1503         else
    1504                 return ui_window_def_resize(window);
    15051395}
    15061396
     
    15841474
    15851475        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 
     1476        (void) ui_window_paint(window);
    15921477        return EOK;
    15931478}
     
    16141499        }
    16151500
    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 
     1501        (void) ui_window_paint(window);
    16221502        return EOK;
    16231503}
     
    16931573        if (window->control != NULL)
    16941574                ui_control_unfocus(window->control, nfocus);
    1695 }
    1696 
    1697 /** Default window resize routine.
    1698  *
    1699  * @param window Window
    1700  * @return EOK on success or an error code
    1701  */
    1702 void ui_window_def_resize(ui_window_t *window)
    1703 {
    1704         ui_window_paint(window);
    17051575}
    17061576
Note: See TracChangeset for help on using the changeset viewer.