Changeset 35cffea in mainline


Ignore:
Timestamp:
2022-05-19T08:02:31Z (3 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ad698f4
Parents:
fd05ea6
git-author:
Jiri Svoboda <jiri@…> (2022-05-18 17:02:12)
git-committer:
Jiri Svoboda <jiri@…> (2022-05-19 08:02:31)
Message:

Maximizing/unmaximizing a window

Location:
uspace
Files:
26 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/uidemo/uidemo.c

    rfd05ea6 r35cffea  
    609609        ui_wnd_params_init(&params);
    610610        params.caption = "UI Demo";
    611         params.style |= ui_wds_resizable;
     611        params.style |= ui_wds_maximize_btn | ui_wds_resizable;
    612612
    613613        /* FIXME: Auto layout */
  • uspace/lib/display/include/disp_srv.h

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6262        errno_t (*window_move)(void *, sysarg_t, gfx_coord2_t *);
    6363        errno_t (*window_get_pos)(void *, sysarg_t, gfx_coord2_t *);
     64        errno_t (*window_get_max_rect)(void *, sysarg_t, gfx_rect_t *);
    6465        errno_t (*window_resize)(void *, sysarg_t, gfx_coord2_t *, gfx_rect_t *);
     66        errno_t (*window_maximize)(void *, sysarg_t);
     67        errno_t (*window_unmaximize)(void *, sysarg_t);
    6568        errno_t (*window_set_cursor)(void *, sysarg_t, display_stock_cursor_t);
    6669        errno_t (*get_event)(void *, sysarg_t *, display_wnd_ev_t *);
  • uspace/lib/display/include/display.h

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5959extern errno_t display_window_move(display_window_t *, gfx_coord2_t *);
    6060extern errno_t display_window_get_pos(display_window_t *, gfx_coord2_t *);
     61extern errno_t display_window_get_max_rect(display_window_t *, gfx_rect_t *);
    6162extern errno_t display_window_resize(display_window_t *,
    6263    gfx_coord2_t *, gfx_rect_t *);
     64extern errno_t display_window_maximize(display_window_t *);
     65extern errno_t display_window_unmaximize(display_window_t *);
    6366extern errno_t display_window_set_cursor(display_window_t *,
    6467    display_stock_cursor_t);
  • uspace/lib/display/include/ipc/display.h

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4242        DISPLAY_WINDOW_CREATE,
    4343        DISPLAY_WINDOW_DESTROY,
     44        DISPLAY_WINDOW_MAXIMIZE,
    4445        DISPLAY_WINDOW_MOVE,
    4546        DISPLAY_WINDOW_MOVE_REQ,
    4647        DISPLAY_WINDOW_GET_POS,
     48        DISPLAY_WINDOW_GET_MAX_RECT,
    4749        DISPLAY_WINDOW_RESIZE,
    4850        DISPLAY_WINDOW_RESIZE_REQ,
    4951        DISPLAY_WINDOW_SET_CURSOR,
     52        DISPLAY_WINDOW_UNMAXIMIZE,
    5053        DISPLAY_GET_EVENT,
    5154        DISPLAY_GET_INFO
  • uspace/lib/display/include/types/display/wndparams.h

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4343        wndf_popup = 0x1,
    4444        /** Set specific initial window position */
    45         wndf_setpos = 0x2
     45        wndf_setpos = 0x2,
     46        /** Window is maximized */
     47        wndf_maximized = 0x4
    4648} display_wnd_flags_t;
    4749
  • uspace/lib/display/src/disp_srv.c

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    230230}
    231231
     232static void display_window_get_max_rect_srv(display_srv_t *srv,
     233    ipc_call_t *icall)
     234{
     235        sysarg_t wnd_id;
     236        ipc_call_t call;
     237        gfx_rect_t rect;
     238        size_t size;
     239        errno_t rc;
     240
     241        wnd_id = ipc_get_arg1(icall);
     242
     243        if (srv->ops->window_get_max_rect == NULL) {
     244                async_answer_0(icall, ENOTSUP);
     245                return;
     246        }
     247
     248        if (!async_data_read_receive(&call, &size)) {
     249                async_answer_0(icall, EREFUSED);
     250                return;
     251        }
     252
     253        rc = srv->ops->window_get_max_rect(srv->arg, wnd_id, &rect);
     254        if (rc != EOK) {
     255                async_answer_0(&call, rc);
     256                async_answer_0(icall, rc);
     257                return;
     258        }
     259
     260        if (size != sizeof(gfx_rect_t)) {
     261                async_answer_0(&call, EINVAL);
     262                async_answer_0(icall, EINVAL);
     263                return;
     264        }
     265
     266        rc = async_data_read_finalize(&call, &rect, size);
     267        if (rc != EOK) {
     268                async_answer_0(&call, rc);
     269                async_answer_0(icall, rc);
     270                return;
     271        }
     272
     273        async_answer_0(icall, EOK);
     274}
     275
    232276static void display_window_resize_req_srv(display_srv_t *srv, ipc_call_t *icall)
    233277{
     
    306350        rc = srv->ops->window_resize(srv->arg, wnd_id, &wresize.offs,
    307351            &wresize.nrect);
     352        async_answer_0(icall, rc);
     353}
     354
     355static void display_window_maximize_srv(display_srv_t *srv, ipc_call_t *icall)
     356{
     357        sysarg_t wnd_id;
     358        errno_t rc;
     359
     360        wnd_id = ipc_get_arg1(icall);
     361
     362        if (srv->ops->window_maximize == NULL) {
     363                async_answer_0(icall, ENOTSUP);
     364                return;
     365        }
     366
     367        rc = srv->ops->window_maximize(srv->arg, wnd_id);
     368        async_answer_0(icall, rc);
     369}
     370
     371static void display_window_unmaximize_srv(display_srv_t *srv, ipc_call_t *icall)
     372{
     373        sysarg_t wnd_id;
     374        errno_t rc;
     375
     376        wnd_id = ipc_get_arg1(icall);
     377
     378        if (srv->ops->window_unmaximize == NULL) {
     379                async_answer_0(icall, ENOTSUP);
     380                return;
     381        }
     382
     383        rc = srv->ops->window_unmaximize(srv->arg, wnd_id);
    308384        async_answer_0(icall, rc);
    309385}
     
    445521                        display_window_get_pos_srv(srv, &call);
    446522                        break;
     523                case DISPLAY_WINDOW_GET_MAX_RECT:
     524                        display_window_get_max_rect_srv(srv, &call);
     525                        break;
    447526                case DISPLAY_WINDOW_RESIZE_REQ:
    448527                        display_window_resize_req_srv(srv, &call);
     
    450529                case DISPLAY_WINDOW_RESIZE:
    451530                        display_window_resize_srv(srv, &call);
     531                        break;
     532                case DISPLAY_WINDOW_MAXIMIZE:
     533                        display_window_maximize_srv(srv, &call);
     534                        break;
     535                case DISPLAY_WINDOW_UNMAXIMIZE:
     536                        display_window_unmaximize_srv(srv, &call);
    452537                        break;
    453538                case DISPLAY_WINDOW_SET_CURSOR:
  • uspace/lib/display/src/display.c

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    350350}
    351351
     352/** Get display window maximized rectangle.
     353 *
     354 * Get the rectangle to which a window would be maximized.
     355 *
     356 * @param window Window
     357 * @param rect Place to store maximized rectangle
     358 * @return EOK on success or an error code
     359 */
     360errno_t display_window_get_max_rect(display_window_t *window, gfx_rect_t *rect)
     361{
     362        async_exch_t *exch;
     363        aid_t req;
     364        ipc_call_t answer;
     365        errno_t rc;
     366
     367        exch = async_exchange_begin(window->display->sess);
     368        req = async_send_1(exch, DISPLAY_WINDOW_GET_MAX_RECT, window->id,
     369            &answer);
     370        rc = async_data_read_start(exch, rect, sizeof (gfx_rect_t));
     371        async_exchange_end(exch);
     372        if (rc != EOK) {
     373                async_forget(req);
     374                return rc;
     375        }
     376
     377        async_wait_for(req, &rc);
     378        if (rc != EOK)
     379                return rc;
     380
     381        return EOK;
     382}
     383
    352384/** Request a window resize.
    353385 *
     
    453485
    454486        return EOK;
     487}
     488
     489/** Maximize window.
     490 *
     491 * @param window Window
     492 * @return EOK on success or an error code
     493 */
     494errno_t display_window_maximize(display_window_t *window)
     495{
     496        async_exch_t *exch;
     497        errno_t rc;
     498
     499        exch = async_exchange_begin(window->display->sess);
     500        rc = async_req_1_0(exch, DISPLAY_WINDOW_MAXIMIZE, window->id);
     501        async_exchange_end(exch);
     502
     503        return rc;
     504}
     505
     506/** Unmaximize window.
     507 *
     508 * @param window Window
     509 * @return EOK on success or an error code
     510 */
     511errno_t display_window_unmaximize(display_window_t *window)
     512{
     513        async_exch_t *exch;
     514        errno_t rc;
     515
     516        exch = async_exchange_begin(window->display->sess);
     517        rc = async_req_1_0(exch, DISPLAY_WINDOW_UNMAXIMIZE, window->id);
     518        async_exchange_end(exch);
     519
     520        return rc;
    455521}
    456522
  • uspace/lib/display/test/display.c

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6060static errno_t test_window_move(void *, sysarg_t, gfx_coord2_t *);
    6161static errno_t test_window_get_pos(void *, sysarg_t, gfx_coord2_t *);
     62static errno_t test_window_get_max_rect(void *, sysarg_t, gfx_rect_t *);
    6263static errno_t test_window_resize_req(void *, sysarg_t, display_wnd_rsztype_t,
    6364    gfx_coord2_t *);
    6465static errno_t test_window_resize(void *, sysarg_t, gfx_coord2_t *,
    6566    gfx_rect_t *);
     67static errno_t test_window_maximize(void *, sysarg_t);
     68static errno_t test_window_unmaximize(void *, sysarg_t);
    6669static errno_t test_window_set_cursor(void *, sysarg_t, display_stock_cursor_t);
    6770static errno_t test_get_event(void *, sysarg_t *, display_wnd_ev_t *);
     
    7679        .window_move = test_window_move,
    7780        .window_get_pos = test_window_get_pos,
     81        .window_get_max_rect = test_window_get_max_rect,
    7882        .window_resize_req = test_window_resize_req,
    7983        .window_resize = test_window_resize,
     84        .window_maximize = test_window_maximize,
     85        .window_unmaximize = test_window_unmaximize,
    8086        .window_set_cursor = test_window_set_cursor,
    8187        .get_event = test_get_event,
     
    122128        gfx_coord2_t get_pos_rpos;
    123129
     130        bool window_get_max_rect_called;
     131        sysarg_t get_max_rect_wnd_id;
     132        gfx_rect_t get_max_rect_rrect;
     133
    124134        bool window_resize_req_called;
    125135        sysarg_t resize_req_wnd_id;
     
    131141        gfx_rect_t resize_nbound;
    132142        sysarg_t resize_wnd_id;
     143
     144        bool window_maximize_called;
     145        bool window_unmaximize_called;
    133146
    134147        bool window_set_cursor_called;
     
    674687}
    675688
     689/** display_window_get_max_rect() with server returning error response works. */
     690PCUT_TEST(window_get_max_rect_failure)
     691{
     692        errno_t rc;
     693        service_id_t sid;
     694        display_t *disp = NULL;
     695        display_wnd_params_t params;
     696        display_window_t *wnd;
     697        gfx_rect_t rect;
     698        test_response_t resp;
     699
     700        async_set_fallback_port_handler(test_display_conn, &resp);
     701
     702        // FIXME This causes this test to be non-reentrant!
     703        rc = loc_server_register(test_display_server);
     704        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     705
     706        rc = loc_service_register(test_display_svc, &sid);
     707        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     708
     709        rc = display_open(test_display_svc, &disp);
     710        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     711        PCUT_ASSERT_NOT_NULL(disp);
     712
     713        resp.rc = EOK;
     714        display_wnd_params_init(&params);
     715        params.rect.p0.x = 0;
     716        params.rect.p0.y = 0;
     717        params.rect.p0.x = 100;
     718        params.rect.p0.y = 100;
     719
     720        rc = display_window_create(disp, &params, &test_display_wnd_cb,
     721            (void *) &resp, &wnd);
     722        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     723        PCUT_ASSERT_NOT_NULL(wnd);
     724
     725        resp.rc = EIO;
     726        resp.window_get_max_rect_called = false;
     727
     728        rect.p0.x = 0;
     729        rect.p0.y = 0;
     730        rect.p1.x = 0;
     731        rect.p1.y = 0;
     732
     733        rc = display_window_get_max_rect(wnd, &rect);
     734        PCUT_ASSERT_TRUE(resp.window_get_max_rect_called);
     735        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
     736        PCUT_ASSERT_INT_EQUALS(wnd->id, resp.get_max_rect_wnd_id);
     737        PCUT_ASSERT_INT_EQUALS(0, rect.p0.x);
     738        PCUT_ASSERT_INT_EQUALS(0, rect.p0.y);
     739        PCUT_ASSERT_INT_EQUALS(0, rect.p1.x);
     740        PCUT_ASSERT_INT_EQUALS(0, rect.p1.y);
     741
     742        display_window_destroy(wnd);
     743        display_close(disp);
     744        rc = loc_service_unregister(sid);
     745        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     746}
     747
     748/** display_window_get_max_rect() with server returning success response works. */
     749PCUT_TEST(window_get_max_rect_success)
     750{
     751        errno_t rc;
     752        service_id_t sid;
     753        display_t *disp = NULL;
     754        display_wnd_params_t params;
     755        display_window_t *wnd;
     756        gfx_rect_t rect;
     757        test_response_t resp;
     758
     759        async_set_fallback_port_handler(test_display_conn, &resp);
     760
     761        // FIXME This causes this test to be non-reentrant!
     762        rc = loc_server_register(test_display_server);
     763        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     764
     765        rc = loc_service_register(test_display_svc, &sid);
     766        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     767
     768        rc = display_open(test_display_svc, &disp);
     769        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     770        PCUT_ASSERT_NOT_NULL(disp);
     771
     772        resp.rc = EOK;
     773        display_wnd_params_init(&params);
     774        params.rect.p0.x = 0;
     775        params.rect.p0.y = 0;
     776        params.rect.p0.x = 100;
     777        params.rect.p0.y = 100;
     778
     779        rc = display_window_create(disp, &params, &test_display_wnd_cb,
     780            (void *) &resp, &wnd);
     781        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     782        PCUT_ASSERT_NOT_NULL(wnd);
     783
     784        resp.rc = EOK;
     785        resp.window_get_max_rect_called = false;
     786        resp.get_max_rect_rrect.p0.x = 11;
     787        resp.get_max_rect_rrect.p0.y = 12;
     788        resp.get_max_rect_rrect.p1.x = 13;
     789        resp.get_max_rect_rrect.p1.y = 14;
     790
     791        rect.p0.x = 0;
     792        rect.p0.y = 0;
     793        rect.p1.x = 0;
     794        rect.p1.y = 0;
     795
     796        rc = display_window_get_max_rect(wnd, &rect);
     797        PCUT_ASSERT_TRUE(resp.window_get_max_rect_called);
     798        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
     799        PCUT_ASSERT_INT_EQUALS(wnd->id, resp.get_max_rect_wnd_id);
     800        PCUT_ASSERT_INT_EQUALS(resp.get_max_rect_rrect.p0.x, rect.p0.x);
     801        PCUT_ASSERT_INT_EQUALS(resp.get_max_rect_rrect.p0.y, rect.p0.y);
     802        PCUT_ASSERT_INT_EQUALS(resp.get_max_rect_rrect.p1.x, rect.p1.x);
     803        PCUT_ASSERT_INT_EQUALS(resp.get_max_rect_rrect.p1.y, rect.p1.y);
     804
     805        display_window_destroy(wnd);
     806        display_close(disp);
     807        rc = loc_service_unregister(sid);
     808        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     809}
     810
    676811/** display_window_resize_req() with server returning error response works. */
    677812PCUT_TEST(window_resize_req_failure)
     
    9081043        PCUT_ASSERT_INT_EQUALS(nrect.p1.x, resp.resize_nbound.p1.x);
    9091044        PCUT_ASSERT_INT_EQUALS(nrect.p1.y, resp.resize_nbound.p1.y);
     1045
     1046        display_window_destroy(wnd);
     1047        display_close(disp);
     1048        rc = loc_service_unregister(sid);
     1049        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1050}
     1051
     1052/** display_window_maximize() with server returning error response works. */
     1053PCUT_TEST(window_maximize_failure)
     1054{
     1055        errno_t rc;
     1056        service_id_t sid;
     1057        display_t *disp = NULL;
     1058        display_wnd_params_t params;
     1059        display_window_t *wnd;
     1060        test_response_t resp;
     1061
     1062        async_set_fallback_port_handler(test_display_conn, &resp);
     1063
     1064        // FIXME This causes this test to be non-reentrant!
     1065        rc = loc_server_register(test_display_server);
     1066        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1067
     1068        rc = loc_service_register(test_display_svc, &sid);
     1069        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1070
     1071        rc = display_open(test_display_svc, &disp);
     1072        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1073        PCUT_ASSERT_NOT_NULL(disp);
     1074
     1075        resp.rc = EOK;
     1076        display_wnd_params_init(&params);
     1077        params.rect.p0.x = 0;
     1078        params.rect.p0.y = 0;
     1079        params.rect.p0.x = 100;
     1080        params.rect.p0.y = 100;
     1081
     1082        rc = display_window_create(disp, &params, &test_display_wnd_cb,
     1083            (void *) &resp, &wnd);
     1084        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1085        PCUT_ASSERT_NOT_NULL(wnd);
     1086
     1087        resp.rc = EIO;
     1088        resp.window_maximize_called = false;
     1089
     1090        rc = display_window_maximize(wnd);
     1091        PCUT_ASSERT_TRUE(resp.window_maximize_called);
     1092        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
     1093
     1094        display_window_destroy(wnd);
     1095        display_close(disp);
     1096        rc = loc_service_unregister(sid);
     1097        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1098}
     1099
     1100/** display_window_maximize() with server returning success response works. */
     1101PCUT_TEST(window_maximize_success)
     1102{
     1103        errno_t rc;
     1104        service_id_t sid;
     1105        display_t *disp = NULL;
     1106        display_wnd_params_t params;
     1107        display_window_t *wnd;
     1108        test_response_t resp;
     1109
     1110        async_set_fallback_port_handler(test_display_conn, &resp);
     1111
     1112        // FIXME This causes this test to be non-reentrant!
     1113        rc = loc_server_register(test_display_server);
     1114        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1115
     1116        rc = loc_service_register(test_display_svc, &sid);
     1117        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1118
     1119        rc = display_open(test_display_svc, &disp);
     1120        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1121        PCUT_ASSERT_NOT_NULL(disp);
     1122
     1123        resp.rc = EOK;
     1124        display_wnd_params_init(&params);
     1125        params.rect.p0.x = 0;
     1126        params.rect.p0.y = 0;
     1127        params.rect.p0.x = 100;
     1128        params.rect.p0.y = 100;
     1129
     1130        rc = display_window_create(disp, &params, &test_display_wnd_cb,
     1131            (void *) &resp, &wnd);
     1132        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1133        PCUT_ASSERT_NOT_NULL(wnd);
     1134
     1135        resp.rc = EOK;
     1136        resp.window_maximize_called = false;
     1137
     1138        rc = display_window_maximize(wnd);
     1139        PCUT_ASSERT_TRUE(resp.window_maximize_called);
     1140        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
    9101141
    9111142        display_window_destroy(wnd);
     
    17191950}
    17201951
     1952static errno_t test_window_get_max_rect(void *arg, sysarg_t wnd_id,
     1953    gfx_rect_t *rect)
     1954{
     1955        test_response_t *resp = (test_response_t *) arg;
     1956
     1957        resp->window_get_max_rect_called = true;
     1958        resp->get_max_rect_wnd_id = wnd_id;
     1959
     1960        if (resp->rc == EOK)
     1961                *rect = resp->get_max_rect_rrect;
     1962
     1963        return resp->rc;
     1964}
     1965
    17211966static errno_t test_window_resize_req(void *arg, sysarg_t wnd_id,
    17221967    display_wnd_rsztype_t rsztype, gfx_coord2_t *pos)
     
    17401985        resp->resize_offs = *offs;
    17411986        resp->resize_nbound = *nrect;
     1987        return resp->rc;
     1988}
     1989
     1990static errno_t test_window_maximize(void *arg, sysarg_t wnd_id)
     1991{
     1992        test_response_t *resp = (test_response_t *) arg;
     1993
     1994        resp->window_maximize_called = true;
     1995        resp->resize_wnd_id = wnd_id;
     1996        return resp->rc;
     1997}
     1998
     1999static errno_t test_window_unmaximize(void *arg, sysarg_t wnd_id)
     2000{
     2001        test_response_t *resp = (test_response_t *) arg;
     2002
     2003        resp->window_unmaximize_called = true;
     2004        resp->resize_wnd_id = wnd_id;
    17422005        return resp->rc;
    17432006}
  • uspace/lib/ui/include/types/ui/wdecor.h

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5151        /** Window has a title bar */
    5252        ui_wds_titlebar = 0x2,
     53        /** Window has a maximize button */
     54        ui_wds_maximize_btn = 0x4,
    5355        /** Window has a close button */
    54         ui_wds_close_btn = 0x4,
     56        ui_wds_close_btn = 0x8,
    5557        /** Window is resizable */
    56         ui_wds_resizable = 0x8,
     58        ui_wds_resizable = 0x10,
    5759        /** Window is decorated (default decoration) */
    5860        ui_wds_decorated = ui_wds_frame | ui_wds_titlebar | ui_wds_close_btn
     
    7678/** Window decoration callbacks */
    7779typedef struct ui_wdecor_cb {
     80        void (*maximize)(ui_wdecor_t *, void *);
     81        void (*unmaximize)(ui_wdecor_t *, void *);
    7882        void (*close)(ui_wdecor_t *, void *);
    7983        void (*move)(ui_wdecor_t *, void *, gfx_coord2_t *);
  • uspace/lib/ui/include/types/ui/window.h

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    8787/** Window callbacks */
    8888typedef struct ui_window_cb {
     89        void (*maximize)(ui_window_t *, void *);
     90        void (*unmaximize)(ui_window_t *, void *);
    8991        void (*close)(ui_window_t *, void *);
    9092        void (*focus)(ui_window_t *, void *);
  • uspace/lib/ui/include/ui/paint.h

    rfd05ea6 r35cffea  
    6565extern errno_t ui_paint_cross(gfx_context_t *, gfx_coord2_t *, gfx_coord_t,
    6666    gfx_coord_t, gfx_coord_t);
     67extern errno_t ui_paint_maxicon(ui_resource_t *, gfx_coord2_t *, gfx_coord_t,
     68    gfx_coord_t);
     69extern errno_t ui_paint_unmaxicon(ui_resource_t *, gfx_coord2_t *, gfx_coord_t,
     70    gfx_coord_t, gfx_coord_t, gfx_coord_t);
    6771extern errno_t ui_paint_text_box(ui_resource_t *, gfx_rect_t *,
    6872    ui_box_style_t, gfx_color_t *);
  • uspace/lib/ui/include/ui/wdecor.h

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5151extern void ui_wdecor_set_rect(ui_wdecor_t *, gfx_rect_t *);
    5252extern void ui_wdecor_set_active(ui_wdecor_t *, bool);
     53extern void ui_wdecor_set_maximized(ui_wdecor_t *, bool);
    5354extern errno_t ui_wdecor_set_caption(ui_wdecor_t *, const char *);
    5455extern errno_t ui_wdecor_paint(ui_wdecor_t *);
  • uspace/lib/ui/include/ui/window.h

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6565extern void ui_window_set_ctl_cursor(ui_window_t *, ui_stock_cursor_t);
    6666extern errno_t ui_window_paint(ui_window_t *);
     67extern errno_t ui_window_def_maximize(ui_window_t *);
     68extern errno_t ui_window_def_unmaximize(ui_window_t *);
    6769extern ui_evclaim_t ui_window_def_kbd(ui_window_t *, kbd_event_t *);
    6870extern errno_t ui_window_def_paint(ui_window_t *);
  • uspace/lib/ui/private/wdecor.h

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6363        /** Window is active */
    6464        bool active;
     65        /** Window is maximized */
     66        bool maximized;
     67        /** Maximize button */
     68        struct ui_pbutton *btn_max;
    6569        /** Close button */
    6670        struct ui_pbutton *btn_close;
     
    7680        /** Title bar rectangle */
    7781        gfx_rect_t title_bar_rect;
     82        /** Maximize button rectangle */
     83        gfx_rect_t btn_max_rect;
    7884        /** Close button rectangle */
    7985        gfx_rect_t btn_close_rect;
     
    8288} ui_wdecor_geom_t;
    8389
     90extern void ui_wdecor_maximize(ui_wdecor_t *);
     91extern void ui_wdecor_unmaximize(ui_wdecor_t *);
    8492extern void ui_wdecor_close(ui_wdecor_t *);
    8593extern void ui_wdecor_move(ui_wdecor_t *, gfx_coord2_t *);
  • uspace/lib/ui/private/window.h

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    7777        /** Window rectangle */
    7878        gfx_rect_t rect;
     79        /** Normal window rectangle (when not maximized) */
     80        gfx_rect_t normal_rect;
    7981        /** Display position (if fullscreen mode) */
    8082        gfx_coord2_t dpos;
     
    99101};
    100102
     103/** Size change operation */
     104typedef enum {
     105        /** Resize window */
     106        ui_wsc_resize,
     107        /** Maximize window */
     108        ui_wsc_maximize,
     109        /** Unmaximize window */
     110        ui_wsc_unmaximize
     111} ui_wnd_sc_op_t;
     112
    101113extern display_stock_cursor_t wnd_dcursor_from_cursor(ui_stock_cursor_t);
     114extern void ui_window_send_maximize(ui_window_t *);
     115extern void ui_window_send_unmaximize(ui_window_t *);
    102116extern void ui_window_send_close(ui_window_t *);
    103117extern void ui_window_send_focus(ui_window_t *);
     
    106120extern void ui_window_send_pos(ui_window_t *, pos_event_t *);
    107121extern void ui_window_send_unfocus(ui_window_t *);
     122extern errno_t ui_window_size_change(ui_window_t *, gfx_rect_t *,
     123    ui_wnd_sc_op_t);
    108124
    109125#endif
  • uspace/lib/ui/src/paint.c

    rfd05ea6 r35cffea  
    529529}
    530530
     531/** Paint maximize icon.
     532 *
     533 * @param resource UI resource
     534 * @param pos Center position
     535 * @param w Icon width
     536 * @param h Icon height
     537 * @return EOK on success or an error code
     538 */
     539errno_t ui_paint_maxicon(ui_resource_t *resource, gfx_coord2_t *pos,
     540    gfx_coord_t w, gfx_coord_t h)
     541{
     542        gfx_rect_t rect;
     543        errno_t rc;
     544
     545        rc = gfx_set_color(resource->gc, resource->btn_text_color);
     546        if (rc != EOK)
     547                return rc;
     548
     549        rect.p0.x = pos->x - w / 2;
     550        rect.p0.y = pos->y - h / 2;
     551        rect.p1.x = rect.p0.x + w;
     552        rect.p1.y = rect.p0.y + h;
     553        rc = gfx_fill_rect(resource->gc, &rect);
     554        if (rc != EOK)
     555                return rc;
     556
     557        rc = gfx_set_color(resource->gc, resource->btn_face_color);
     558        if (rc != EOK)
     559                return rc;
     560
     561        rect.p0.x += 1;
     562        rect.p0.y += 2;
     563        rect.p1.x -= 1;
     564        rect.p1.y -= 1;
     565        rc = gfx_fill_rect(resource->gc, &rect);
     566        if (rc != EOK)
     567                return rc;
     568
     569        return EOK;
     570}
     571
     572/** Paint unmaximize icon.
     573 *
     574 * Unmaximize icon consists of two overlapping window icons.
     575 *
     576 * @param resource UI resource
     577 * @param pos Center position
     578 * @param w Window icon width
     579 * @param h Window icon height
     580 * @param dw Horizontal distance between window icon centers
     581 * @param dh Vertical distance between window icon centers
     582 * @return EOK on success or an error code
     583 */
     584errno_t ui_paint_unmaxicon(ui_resource_t *resource, gfx_coord2_t *pos,
     585    gfx_coord_t w, gfx_coord_t h, gfx_coord_t dw, gfx_coord_t dh)
     586{
     587        gfx_coord2_t p;
     588        errno_t rc;
     589
     590        p.x = pos->x + dw / 2;
     591        p.y = pos->y - dh / 2;
     592        rc = ui_paint_maxicon(resource, &p, w, h);
     593        if (rc != EOK)
     594                return rc;
     595
     596        p.x = pos->x - dw / 2;
     597        p.y = pos->y + dh / 2;
     598        rc = ui_paint_maxicon(resource, &p, w, h);
     599        if (rc != EOK)
     600                return rc;
     601
     602        return EOK;
     603}
     604
    531605/** Paint a text box.
    532606 *
  • uspace/lib/ui/src/wdecor.c

    rfd05ea6 r35cffea  
    4949#include "../private/wdecor.h"
    5050
    51 static void ui_wdecor_btn_clicked(ui_pbutton_t *, void *);
     51static void ui_wdecor_btn_max_clicked(ui_pbutton_t *, void *);
     52static errno_t ui_wdecor_btn_max_paint(ui_pbutton_t *, void *,
     53    gfx_coord2_t *);
     54
     55static void ui_wdecor_btn_close_clicked(ui_pbutton_t *, void *);
    5256static errno_t ui_wdecor_btn_close_paint(ui_pbutton_t *, void *,
    5357    gfx_coord2_t *);
    5458
     59static ui_pbutton_cb_t ui_wdecor_btn_max_cb = {
     60        .clicked = ui_wdecor_btn_max_clicked
     61};
     62
     63static ui_pbutton_decor_ops_t ui_wdecor_btn_max_decor_ops = {
     64        .paint = ui_wdecor_btn_max_paint
     65};
     66
    5567static ui_pbutton_cb_t ui_wdecor_btn_close_cb = {
    56         .clicked = ui_wdecor_btn_clicked
     68        .clicked = ui_wdecor_btn_close_clicked
    5769};
    5870
     
    6274
    6375enum {
     76        /** Width of corner drag area */
    6477        wdecor_corner_w = 24,
     78        /** Height of corner drag area */
    6579        wdecor_corner_h = 24,
     80        /** Window resizing edge witdth */
    6681        wdecor_edge_w = 4,
     82        /** Window resizing edge height */
    6783        wdecor_edge_h = 4,
     84        /** Title bar height */
    6885        wdecor_tbar_h = 22,
     86        /** Window width */
    6987        wdecor_frame_w = 4,
     88        /** Window frame width in text mode */
    7089        wdecor_frame_w_text = 1,
     90        /** Close button cross leg length */
    7191        wdecor_close_cross_n = 5,
     92        /** Close button cross pen width */
    7293        wdecor_close_cross_w = 2,
    73         wdecor_close_cross_h = 1
     94        /** Close button cross pen height */
     95        wdecor_close_cross_h = 1,
     96        /** Maximize icon width */
     97        wdecor_max_w = 10,
     98        /** Maximize icon height */
     99        wdecor_max_h = 10,
     100        /** Unmaximize icon window width */
     101        wdecor_unmax_w = 8,
     102        /** Unmaximize icon window height */
     103        wdecor_unmax_h = 8,
     104        /** Unmaximize icon window horizontal distance */
     105        wdecor_unmax_dw = 4,
     106        /** Unmaximize icon window vertical distance */
     107        wdecor_unmax_dh = 4
    74108};
    75109
     
    98132        }
    99133
    100         rc = ui_pbutton_create(resource, "X", &wdecor->btn_close);
    101         if (rc != EOK) {
    102                 free(wdecor->caption);
    103                 free(wdecor);
    104                 return rc;
    105         }
    106 
    107         ui_pbutton_set_cb(wdecor->btn_close, &ui_wdecor_btn_close_cb,
    108             (void *)wdecor);
    109 
    110         ui_pbutton_set_decor_ops(wdecor->btn_close,
    111             &ui_wdecor_btn_close_decor_ops, (void *)wdecor);
     134        if ((style & ui_wds_maximize_btn) != 0) {
     135                rc = ui_pbutton_create(resource, "^", &wdecor->btn_max);
     136                if (rc != EOK) {
     137                        ui_wdecor_destroy(wdecor);
     138                        return rc;
     139                }
     140
     141                ui_pbutton_set_cb(wdecor->btn_max, &ui_wdecor_btn_max_cb,
     142                    (void *)wdecor);
     143
     144                ui_pbutton_set_decor_ops(wdecor->btn_max,
     145                    &ui_wdecor_btn_max_decor_ops, (void *)wdecor);
     146        }
     147
     148        if ((style & ui_wds_close_btn) != 0) {
     149                rc = ui_pbutton_create(resource, "X", &wdecor->btn_close);
     150                if (rc != EOK) {
     151                        ui_wdecor_destroy(wdecor);
     152                        return rc;
     153                }
     154
     155                ui_pbutton_set_cb(wdecor->btn_close, &ui_wdecor_btn_close_cb,
     156                    (void *)wdecor);
     157
     158                ui_pbutton_set_decor_ops(wdecor->btn_close,
     159                    &ui_wdecor_btn_close_decor_ops, (void *)wdecor);
     160        }
    112161
    113162        wdecor->res = resource;
     
    127176                return;
    128177
     178        ui_pbutton_destroy(wdecor->btn_max);
    129179        ui_pbutton_destroy(wdecor->btn_close);
    130180        free(wdecor->caption);
     
    156206
    157207        ui_wdecor_get_geom(wdecor, &geom);
    158         ui_pbutton_set_rect(wdecor->btn_close, &geom.btn_close_rect);
     208
     209        if (wdecor->btn_max != NULL)
     210                ui_pbutton_set_rect(wdecor->btn_max, &geom.btn_max_rect);
     211        if (wdecor->btn_close != NULL)
     212                ui_pbutton_set_rect(wdecor->btn_close, &geom.btn_close_rect);
    159213}
    160214
     
    169223{
    170224        wdecor->active = active;
     225}
     226
     227/** Set maximized flag.
     228 *
     229 * Active window is the one receiving keyboard events.
     230 *
     231 * @param wdecor Window decoration
     232 * @param maximized @c true iff window is maximized
     233 */
     234void ui_wdecor_set_maximized(ui_wdecor_t *wdecor, bool maximized)
     235{
     236        wdecor->maximized = maximized;
    171237}
    172238
     
    289355                        return rc;
    290356
    291                 if ((wdecor->style & ui_wds_close_btn) != 0) {
     357                if (wdecor->btn_max != NULL) {
     358                        rc = ui_pbutton_paint(wdecor->btn_max);
     359                        if (rc != EOK)
     360                                return rc;
     361                }
     362
     363                if (wdecor->btn_close != NULL) {
    292364                        rc = ui_pbutton_paint(wdecor->btn_close);
    293365                        if (rc != EOK)
     
    303375}
    304376
     377/** Send decoration maximize event.
     378 *
     379 * @param wdecor Window decoration
     380 */
     381void ui_wdecor_maximize(ui_wdecor_t *wdecor)
     382{
     383        if (wdecor->cb != NULL && wdecor->cb->maximize != NULL)
     384                wdecor->cb->maximize(wdecor, wdecor->arg);
     385}
     386
     387/** Send decoration unmaximize event.
     388 *
     389 * @param wdecor Window decoration
     390 */
     391void ui_wdecor_unmaximize(ui_wdecor_t *wdecor)
     392{
     393        if (wdecor->cb != NULL && wdecor->cb->unmaximize != NULL)
     394                wdecor->cb->unmaximize(wdecor, wdecor->arg);
     395}
     396
    305397/** Send decoration close event.
    306398 *
     
    356448{
    357449        gfx_coord_t frame_w;
     450        gfx_coord_t btn_x;
     451        gfx_coord_t btn_y;
    358452
    359453        /* Does window have a frame? */
     
    376470                        geom->title_bar_rect.p1.x = wdecor->rect.p1.x;
    377471                        geom->title_bar_rect.p1.y = wdecor->rect.p0.y + 1;
     472
     473                        btn_x = geom->title_bar_rect.p1.x - 1;
     474                        btn_y = geom->title_bar_rect.p0.y;
    378475                } else {
    379476                        geom->title_bar_rect.p0 = geom->interior_rect.p0;
     
    381478                        geom->title_bar_rect.p1.y = geom->interior_rect.p0.y +
    382479                            wdecor_tbar_h;
     480
     481                        btn_x = geom->title_bar_rect.p1.x - 1;
     482                        btn_y = geom->title_bar_rect.p0.y + 1;
    383483                }
    384484
     
    386486                geom->app_area_rect.p0.y = geom->title_bar_rect.p1.y;
    387487                geom->app_area_rect.p1 = geom->interior_rect.p1;
     488
    388489        } else {
    389490                geom->title_bar_rect.p0.x = 0;
     
    393494
    394495                geom->app_area_rect = geom->interior_rect;
     496                btn_x = 0;
     497                btn_y = 0;
    395498        }
    396499
     
    398501        if ((wdecor->style & ui_wds_close_btn) != 0) {
    399502                if (wdecor->res->textmode == false) {
    400                         geom->btn_close_rect.p0.x =
    401                             geom->title_bar_rect.p1.x - 1 - 20;
    402                         geom->btn_close_rect.p0.y =
    403                             geom->title_bar_rect.p0.y + 1;
    404                         geom->btn_close_rect.p1.x =
    405                             geom->title_bar_rect.p1.x - 1;
    406                         geom->btn_close_rect.p1.y =
    407                             geom->title_bar_rect.p0.y + 1 + 20;
     503                        geom->btn_close_rect.p0.x = btn_x - 20;
     504                        geom->btn_close_rect.p0.y = btn_y;
     505                        geom->btn_close_rect.p1.x = btn_x;
     506                        geom->btn_close_rect.p1.y = btn_y + 20;
     507
     508                        btn_x -= 20;
    408509                } else {
    409                         geom->btn_close_rect.p0.x =
    410                             geom->title_bar_rect.p1.x - 1 - 3;
    411                         geom->btn_close_rect.p0.y =
    412                             geom->title_bar_rect.p0.y;
    413                         geom->btn_close_rect.p1.x =
    414                             geom->title_bar_rect.p1.x - 1;
    415                         geom->btn_close_rect.p1.y =
    416                             geom->title_bar_rect.p0.y + 1;
     510                        geom->btn_close_rect.p0.x = btn_x - 3;
     511                        geom->btn_close_rect.p0.y = btn_y;
     512                        geom->btn_close_rect.p1.x = btn_x;
     513                        geom->btn_close_rect.p1.y = btn_y + 1;
     514
     515                        btn_x -= 3;
    417516                }
    418517        } else {
     
    422521                geom->btn_close_rect.p1.y = 0;
    423522        }
     523
     524        /* Does window have a (un)maximize button? */
     525        if ((wdecor->style & ui_wds_maximize_btn) != 0) {
     526                if (wdecor->res->textmode == false) {
     527                        geom->btn_max_rect.p0.x = btn_x - 20;
     528                        geom->btn_max_rect.p0.y = btn_y;
     529                        geom->btn_max_rect.p1.x = btn_x;
     530                        geom->btn_max_rect.p1.y = btn_y + 20;
     531                } else {
     532                        geom->btn_max_rect.p0.x = btn_x - 3;
     533                        geom->btn_max_rect.p0.y = btn_y;
     534                        geom->btn_max_rect.p1.x = btn_x;
     535                        geom->btn_max_rect.p1.y = btn_y + 1;
     536                }
     537        } else {
     538                geom->btn_max_rect.p0.x = 0;
     539                geom->btn_max_rect.p0.y = 0;
     540                geom->btn_max_rect.p1.x = 0;
     541                geom->btn_max_rect.p1.y = 0;
     542        }
    424543}
    425544
     
    495614                return ui_wr_none;
    496615
     616        /* Window is maximized? */
     617        if (wdecor->maximized)
     618                return ui_wr_none;
     619
    497620        /* Position not inside window? */
    498621        if (!gfx_pix_inside_rect(pos, &wdecor->rect))
     
    627750        ui_wdecor_get_geom(wdecor, &geom);
    628751
    629         if ((wdecor->style & ui_wds_close_btn) != 0) {
     752        if (wdecor->btn_max != NULL) {
     753                claim = ui_pbutton_pos_event(wdecor->btn_max, event);
     754                if (claim == ui_claimed)
     755                        return ui_claimed;
     756        }
     757
     758        if (wdecor->btn_close != NULL) {
    630759                claim = ui_pbutton_pos_event(wdecor->btn_close, event);
    631760                if (claim == ui_claimed)
     
    635764        ui_wdecor_frame_pos_event(wdecor, event);
    636765
    637         if ((wdecor->style & ui_wds_titlebar) != 0) {
     766        if ((wdecor->style & ui_wds_titlebar) != 0 && !wdecor->maximized) {
    638767                if (event->type == POS_PRESS &&
    639768                    gfx_pix_inside_rect(&pos, &geom.title_bar_rect)) {
     
    646775}
    647776
    648 /** Window decoration close button was clicked.
     777/** Window decoration (un)maximize button was clicked.
    649778 *
    650779 * @param pbutton Close button
    651780 * @param arg Argument (ui_wdecor_t)
    652781 */
    653 static void ui_wdecor_btn_clicked(ui_pbutton_t *pbutton, void *arg)
     782static void ui_wdecor_btn_max_clicked(ui_pbutton_t *pbutton, void *arg)
     783{
     784        ui_wdecor_t *wdecor = (ui_wdecor_t *) arg;
     785
     786        (void) pbutton;
     787
     788        if (wdecor->maximized)
     789                ui_wdecor_unmaximize(wdecor);
     790        else
     791                ui_wdecor_maximize(wdecor);
     792}
     793
     794/** Paint (un)maximize button decoration.
     795 *
     796 * @param pbutton Push button
     797 * @param arg Argument (ui_wdecor_t *)
     798 * @param pos Center position
     799 */
     800static errno_t ui_wdecor_btn_max_paint(ui_pbutton_t *pbutton,
     801    void *arg, gfx_coord2_t *pos)
     802{
     803        ui_wdecor_t *wdecor = (ui_wdecor_t *)arg;
     804        errno_t rc;
     805
     806        if (wdecor->maximized) {
     807                rc = ui_paint_unmaxicon(wdecor->res, pos, wdecor_unmax_w,
     808                    wdecor_unmax_h, wdecor_unmax_dw, wdecor_unmax_dh);
     809        } else {
     810                rc = ui_paint_maxicon(wdecor->res, pos, wdecor_max_w,
     811                    wdecor_max_h);
     812        }
     813
     814        return rc;
     815}
     816
     817/** Window decoration close button was clicked.
     818 *
     819 * @param pbutton Close button
     820 * @param arg Argument (ui_wdecor_t)
     821 */
     822static void ui_wdecor_btn_close_clicked(ui_pbutton_t *pbutton, void *arg)
    654823{
    655824        ui_wdecor_t *wdecor = (ui_wdecor_t *) arg;
  • uspace/lib/ui/src/window.c

    rfd05ea6 r35cffea  
    7474};
    7575
     76static void wd_maximize(ui_wdecor_t *, void *);
     77static void wd_unmaximize(ui_wdecor_t *, void *);
    7678static void wd_close(ui_wdecor_t *, void *);
    7779static void wd_move(ui_wdecor_t *, void *, gfx_coord2_t *);
     
    8183
    8284static ui_wdecor_cb_t wdecor_cb = {
     85        .maximize = wd_maximize,
     86        .unmaximize = wd_unmaximize,
    8387        .close = wd_close,
    8488        .move = wd_move,
     
    469473}
    470474
    471 /** Resize/move window.
    472  *
    473  * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
    474  * the top-left corner of the window will move on the screen accordingly.
     475/** Resize or (un)maximize window.
    475476 *
    476477 * @param window Window
    477478 * @param rect Rectangle
     479 * @param scop Size change operation
    478480 *
    479481 * @return EOK on success or an error code
    480482 */
    481 errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
     483errno_t ui_window_size_change(ui_window_t *window, gfx_rect_t *rect,
     484    ui_wnd_sc_op_t scop)
    482485{
    483486        gfx_coord2_t offs;
     
    545548        }
    546549
    547         /* dwindow can be NULL in case of unit tests */
     550        /* dwindow can be NULL in case of unit tests or fullscreen mode */
    548551        if (window->dwindow != NULL) {
    549                 rc = display_window_resize(window->dwindow, &offs, &nrect);
    550                 if (rc != EOK)
    551                         goto error;
     552                switch (scop) {
     553                case ui_wsc_resize:
     554                        rc = display_window_resize(window->dwindow, &offs,
     555                            &nrect);
     556                        if (rc != EOK)
     557                                goto error;
     558                        break;
     559                case ui_wsc_maximize:
     560                        rc = display_window_maximize(window->dwindow);
     561                        if (rc != EOK)
     562                                goto error;
     563                        break;
     564                case ui_wsc_unmaximize:
     565                        rc = display_window_unmaximize(window->dwindow);
     566                        if (rc != EOK)
     567                                goto error;
     568                        break;
     569                }
    552570        }
    553571
     
    597615}
    598616
     617/** Resize/move window.
     618 *
     619 * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
     620 * the top-left corner of the window will move on the screen accordingly.
     621 *
     622 * @param window Window
     623 * @param rect Rectangle
     624 *
     625 * @return EOK on success or an error code
     626 */
     627errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
     628{
     629        return ui_window_size_change(window, rect, ui_wsc_resize);
     630}
     631
    599632/** Set window callbacks.
    600633 *
     
    846879        ui_window_send_unfocus(window);
    847880        ui_unlock(window->ui);
     881}
     882
     883/** Window decoration requested window maximization.
     884 *
     885 * @param wdecor Window decoration
     886 * @param arg Argument (window)
     887 */
     888static void wd_maximize(ui_wdecor_t *wdecor, void *arg)
     889{
     890        ui_window_t *window = (ui_window_t *) arg;
     891
     892        ui_window_send_maximize(window);
     893}
     894
     895/** Window decoration requested window unmaximization.
     896 *
     897 * @param wdecor Window decoration
     898 * @param arg Argument (window)
     899 */
     900static void wd_unmaximize(ui_wdecor_t *wdecor, void *arg)
     901{
     902        ui_window_t *window = (ui_window_t *) arg;
     903
     904        ui_window_send_unmaximize(window);
    848905}
    849906
     
    9481005}
    9491006
     1007/** Send window maximize event.
     1008 *
     1009 * @param window Window
     1010 */
     1011void ui_window_send_maximize(ui_window_t *window)
     1012{
     1013        if (window->cb != NULL && window->cb->maximize != NULL)
     1014                window->cb->maximize(window, window->arg);
     1015        else
     1016                ui_window_def_maximize(window);
     1017}
     1018
     1019/** Send window unmaximize event.
     1020 *
     1021 * @param window Window
     1022 */
     1023void ui_window_send_unmaximize(ui_window_t *window)
     1024{
     1025        if (window->cb != NULL && window->cb->unmaximize != NULL)
     1026                window->cb->unmaximize(window, window->arg);
     1027        else
     1028                ui_window_def_unmaximize(window);
     1029}
     1030
    9501031/** Send window close event.
    9511032 *
     
    10141095        else
    10151096                return ui_window_def_unfocus(window);
     1097}
     1098
     1099/** Default window maximize routine.
     1100 *
     1101 * @param window Window
     1102 * @return EOK on success or an error code
     1103 */
     1104errno_t ui_window_def_maximize(ui_window_t *window)
     1105{
     1106        errno_t rc;
     1107        gfx_rect_t old_rect;
     1108        gfx_rect_t rect;
     1109
     1110        old_rect = window->rect;
     1111
     1112        if (window->dwindow != NULL) {
     1113                rc = display_window_get_max_rect(window->dwindow, &rect);
     1114                if (rc != EOK)
     1115                        return rc;
     1116        } else {
     1117                rect = window->ui->rect;
     1118        }
     1119
     1120        ui_wdecor_set_maximized(window->wdecor, true);
     1121
     1122        rc = ui_window_size_change(window, &rect, ui_wsc_maximize);
     1123        if (rc != EOK) {
     1124                ui_wdecor_set_maximized(window->wdecor, false);
     1125                return rc;
     1126        }
     1127
     1128        window->normal_rect = old_rect;
     1129        (void) ui_window_paint(window);
     1130        return EOK;
     1131}
     1132
     1133/** Default window unmaximize routine.
     1134 *
     1135 * @param window Window
     1136 * @return EOK on success or an error code
     1137 */
     1138errno_t ui_window_def_unmaximize(ui_window_t *window)
     1139{
     1140        errno_t rc;
     1141
     1142        ui_wdecor_set_maximized(window->wdecor, false);
     1143
     1144        rc = ui_window_size_change(window, &window->normal_rect,
     1145            ui_wsc_unmaximize);
     1146        if (rc != EOK) {
     1147                ui_wdecor_set_maximized(window->wdecor, true);
     1148                printf("ui_window_size_change->error\n");
     1149                return rc;
     1150        }
     1151
     1152        (void) ui_window_paint(window);
     1153        return EOK;
    10161154}
    10171155
  • uspace/lib/ui/test/paint.c

    rfd05ea6 r35cffea  
    354354}
    355355
     356/** Paint maximize icon */
     357PCUT_TEST(maxicon)
     358{
     359        errno_t rc;
     360        gfx_context_t *gc = NULL;
     361        ui_resource_t *resource = NULL;
     362        test_gc_t tgc;
     363        gfx_coord2_t center;
     364
     365        memset(&tgc, 0, sizeof(tgc));
     366        rc = gfx_context_new(&ops, &tgc, &gc);
     367        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     368
     369        rc = ui_resource_create(gc, false, &resource);
     370        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     371        PCUT_ASSERT_NOT_NULL(resource);
     372
     373        center.x = 0;
     374        center.y = 0;
     375
     376        rc = ui_paint_maxicon(resource, &center, 8, 6);
     377        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     378
     379        ui_resource_destroy(resource);
     380        rc = gfx_context_delete(gc);
     381        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     382}
     383
     384/** Paint unmaximize icon */
     385PCUT_TEST(unmaxicon)
     386{
     387        errno_t rc;
     388        gfx_context_t *gc = NULL;
     389        ui_resource_t *resource = NULL;
     390        test_gc_t tgc;
     391        gfx_coord2_t center;
     392
     393        memset(&tgc, 0, sizeof(tgc));
     394        rc = gfx_context_new(&ops, &tgc, &gc);
     395        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     396
     397        rc = ui_resource_create(gc, false, &resource);
     398        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     399        PCUT_ASSERT_NOT_NULL(resource);
     400
     401        center.x = 0;
     402        center.y = 0;
     403
     404        rc = ui_paint_unmaxicon(resource, &center, 8, 8, 3, 3);
     405        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     406
     407        ui_resource_destroy(resource);
     408        rc = gfx_context_delete(gc);
     409        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     410}
     411
    356412/** Paint text box */
    357413PCUT_TEST(text_box)
  • uspace/lib/ui/test/wdecor.c

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6262};
    6363
     64static void test_wdecor_maximize(ui_wdecor_t *, void *);
     65static void test_wdecor_unmaximize(ui_wdecor_t *, void *);
    6466static void test_wdecor_close(ui_wdecor_t *, void *);
    6567static void test_wdecor_move(ui_wdecor_t *, void *, gfx_coord2_t *);
     
    6971
    7072static ui_wdecor_cb_t test_wdecor_cb = {
     73        .maximize = test_wdecor_maximize,
     74        .unmaximize = test_wdecor_unmaximize,
    7175        .close = test_wdecor_close,
    7276        .move = test_wdecor_move,
     
    96100
    97101typedef struct {
     102        bool maximize;
     103        bool unmaximize;
    98104        bool close;
    99105        bool move;
     
    168174}
    169175
     176/** Set window decoration maximized sets internal field */
     177PCUT_TEST(set_maximized)
     178{
     179        ui_wdecor_t *wdecor;
     180        errno_t rc;
     181
     182        rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
     183        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     184
     185        PCUT_ASSERT_TRUE(wdecor->active);
     186
     187        ui_wdecor_set_maximized(wdecor, false);
     188        PCUT_ASSERT_FALSE(wdecor->maximized);
     189
     190        ui_wdecor_set_maximized(wdecor, true);
     191        PCUT_ASSERT_TRUE(wdecor->maximized);
     192
     193        ui_wdecor_destroy(wdecor);
     194}
     195
    170196/** Paint button */
    171197PCUT_TEST(paint)
     
    196222        rc = gfx_context_delete(gc);
    197223        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     224}
     225
     226/** Test ui_wdecor_maximize() */
     227PCUT_TEST(maximize)
     228{
     229        errno_t rc;
     230        ui_wdecor_t *wdecor;
     231        test_cb_resp_t resp;
     232
     233        rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
     234        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     235
     236        /* Maximize callback with no callbacks set */
     237        ui_wdecor_maximize(wdecor);
     238
     239        /* Maxmimize callback with maximize callback not implemented */
     240        ui_wdecor_set_cb(wdecor, &dummy_wdecor_cb, NULL);
     241        ui_wdecor_maximize(wdecor);
     242
     243        /* Maximize callback with real callback set */
     244        resp.maximize = false;
     245        ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
     246        ui_wdecor_maximize(wdecor);
     247        PCUT_ASSERT_TRUE(resp.maximize);
     248
     249        ui_wdecor_destroy(wdecor);
     250}
     251
     252/** Test ui_wdecor_unmaximize() */
     253PCUT_TEST(unmaximize)
     254{
     255        errno_t rc;
     256        ui_wdecor_t *wdecor;
     257        test_cb_resp_t resp;
     258
     259        rc = ui_wdecor_create(NULL, "Hello", ui_wds_none, &wdecor);
     260        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     261
     262        /* Unmaximize callback with no callbacks set */
     263        ui_wdecor_unmaximize(wdecor);
     264
     265        /* Unmaximize callback with unmaximize callback not implemented */
     266        ui_wdecor_set_cb(wdecor, &dummy_wdecor_cb, NULL);
     267        ui_wdecor_unmaximize(wdecor);
     268
     269        /* Unmaximize callback with real callback set */
     270        resp.unmaximize = false;
     271        ui_wdecor_set_cb(wdecor, &test_wdecor_cb, &resp);
     272        ui_wdecor_unmaximize(wdecor);
     273        PCUT_ASSERT_TRUE(resp.unmaximize);
     274
     275        ui_wdecor_destroy(wdecor);
    198276}
    199277
     
    9361014}
    9371015
     1016static void test_wdecor_maximize(ui_wdecor_t *wdecor, void *arg)
     1017{
     1018        test_cb_resp_t *resp = (test_cb_resp_t *) arg;
     1019
     1020        resp->maximize = true;
     1021}
     1022
     1023static void test_wdecor_unmaximize(ui_wdecor_t *wdecor, void *arg)
     1024{
     1025        test_cb_resp_t *resp = (test_cb_resp_t *) arg;
     1026
     1027        resp->unmaximize = true;
     1028}
     1029
    9381030static void test_wdecor_close(ui_wdecor_t *wdecor, void *arg)
    9391031{
  • uspace/lib/ui/test/window.c

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4545PCUT_TEST_SUITE(window);
    4646
     47static void test_window_maximize(ui_window_t *, void *);
     48static void test_window_unmaximize(ui_window_t *, void *);
    4749static void test_window_close(ui_window_t *, void *);
    4850static void test_window_focus(ui_window_t *, void *);
     
    5355
    5456static ui_window_cb_t test_window_cb = {
     57        .maximize = test_window_maximize,
     58        .unmaximize = test_window_unmaximize,
    5559        .close = test_window_close,
    5660        .focus = test_window_focus,
     
    7680typedef struct {
    7781        errno_t rc;
     82        bool maximize;
     83        bool unmaximize;
    7884        bool close;
    7985        bool focus;
     
    526532        /* Need to remove first because we didn't implement the destructor */
    527533        ui_window_remove(window, control);
     534
     535        ui_window_destroy(window);
     536        ui_destroy(ui);
     537}
     538
     539/** ui_window_send_maximize() calls maximize callback set via ui_window_set_cb() */
     540PCUT_TEST(send_maximize)
     541{
     542        errno_t rc;
     543        ui_t *ui = NULL;
     544        ui_wnd_params_t params;
     545        ui_window_t *window = NULL;
     546        test_cb_resp_t resp;
     547
     548        rc = ui_create_disp(NULL, &ui);
     549        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     550
     551        ui_wnd_params_init(&params);
     552        params.caption = "Hello";
     553
     554        rc = ui_window_create(ui, &params, &window);
     555        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     556        PCUT_ASSERT_NOT_NULL(window);
     557
     558        /* Maximize callback with no callbacks set */
     559        ui_window_send_maximize(window);
     560
     561        /* Maximize callback with maximize callback not implemented */
     562        ui_window_set_cb(window, &dummy_window_cb, NULL);
     563        ui_window_send_maximize(window);
     564
     565        /* Maximize callback with real callback set */
     566        resp.maximize = false;
     567        ui_window_set_cb(window, &test_window_cb, &resp);
     568        ui_window_send_maximize(window);
     569        PCUT_ASSERT_TRUE(resp.maximize);
     570
     571        ui_window_destroy(window);
     572        ui_destroy(ui);
     573}
     574
     575/** ui_window_send_unmaximize() calls unmaximize callback set via ui_window_set_cb() */
     576PCUT_TEST(send_unmaximize)
     577{
     578        errno_t rc;
     579        ui_t *ui = NULL;
     580        ui_wnd_params_t params;
     581        ui_window_t *window = NULL;
     582        test_cb_resp_t resp;
     583
     584        rc = ui_create_disp(NULL, &ui);
     585        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     586
     587        ui_wnd_params_init(&params);
     588        params.caption = "Hello";
     589
     590        rc = ui_window_create(ui, &params, &window);
     591        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     592        PCUT_ASSERT_NOT_NULL(window);
     593
     594        /* Unmaximize callback with no callbacks set */
     595        ui_window_send_unmaximize(window);
     596
     597        /* Unmaximize callback with unmaximize callback not implemented */
     598        ui_window_set_cb(window, &dummy_window_cb, NULL);
     599        ui_window_send_unmaximize(window);
     600
     601        /* Unmaximize callback with real callback set */
     602        resp.unmaximize = false;
     603        ui_window_set_cb(window, &test_window_cb, &resp);
     604        ui_window_send_unmaximize(window);
     605        PCUT_ASSERT_TRUE(resp.unmaximize);
    528606
    529607        ui_window_destroy(window);
     
    771849}
    772850
     851static void test_window_maximize(ui_window_t *window, void *arg)
     852{
     853        test_cb_resp_t *resp = (test_cb_resp_t *) arg;
     854
     855        resp->maximize = true;
     856}
     857
     858static void test_window_unmaximize(ui_window_t *window, void *arg)
     859{
     860        test_cb_resp_t *resp = (test_cb_resp_t *) arg;
     861
     862        resp->unmaximize = true;
     863}
     864
    773865static void test_window_close(ui_window_t *window, void *arg)
    774866{
  • uspace/srv/hid/display/dsops.c

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4949static errno_t disp_window_move(void *, sysarg_t, gfx_coord2_t *);
    5050static errno_t disp_window_get_pos(void *, sysarg_t, gfx_coord2_t *);
     51static errno_t disp_window_get_max_rect(void *, sysarg_t, gfx_rect_t *);
    5152static errno_t disp_window_resize_req(void *, sysarg_t,
    5253    display_wnd_rsztype_t, gfx_coord2_t *);
    5354static errno_t disp_window_resize(void *, sysarg_t, gfx_coord2_t *,
    5455    gfx_rect_t *);
     56static errno_t disp_window_maximize(void *, sysarg_t);
     57static errno_t disp_window_unmaximize(void *, sysarg_t);
    5558static errno_t disp_window_set_cursor(void *, sysarg_t, display_stock_cursor_t);
    5659static errno_t disp_get_event(void *, sysarg_t *, display_wnd_ev_t *);
     
    6366        .window_move = disp_window_move,
    6467        .window_get_pos = disp_window_get_pos,
     68        .window_get_max_rect = disp_window_get_max_rect,
    6569        .window_resize_req = disp_window_resize_req,
    6670        .window_resize = disp_window_resize,
     71        .window_maximize = disp_window_maximize,
     72        .window_unmaximize = disp_window_unmaximize,
    6773        .window_set_cursor = disp_window_set_cursor,
    6874        .get_event = disp_get_event,
     
    175181}
    176182
     183static errno_t disp_window_get_max_rect(void *arg, sysarg_t wnd_id,
     184    gfx_rect_t *rect)
     185{
     186        ds_client_t *client = (ds_client_t *) arg;
     187        ds_window_t *wnd;
     188
     189        ds_display_lock(client->display);
     190
     191        wnd = ds_client_find_window(client, wnd_id);
     192        if (wnd == NULL) {
     193                ds_display_unlock(client->display);
     194                return ENOENT;
     195        }
     196
     197        log_msg(LOG_DEFAULT, LVL_DEBUG, "disp_window_get_max_rect()");
     198        ds_window_get_max_rect(wnd, rect);
     199        ds_display_unlock(client->display);
     200        return EOK;
     201}
     202
    177203static errno_t disp_window_resize_req(void *arg, sysarg_t wnd_id,
    178204    display_wnd_rsztype_t rsztype, gfx_coord2_t *pos)
     
    219245}
    220246
     247static errno_t disp_window_maximize(void *arg, sysarg_t wnd_id)
     248{
     249        ds_client_t *client = (ds_client_t *) arg;
     250        ds_window_t *wnd;
     251        errno_t rc;
     252
     253        ds_display_lock(client->display);
     254
     255        wnd = ds_client_find_window(client, wnd_id);
     256        if (wnd == NULL) {
     257                ds_display_unlock(client->display);
     258                return ENOENT;
     259        }
     260
     261        log_msg(LOG_DEFAULT, LVL_DEBUG, "disp_window_maximize()");
     262        rc = ds_window_maximize(wnd);
     263        ds_display_unlock(client->display);
     264        return rc;
     265}
     266
     267static errno_t disp_window_unmaximize(void *arg, sysarg_t wnd_id)
     268{
     269        ds_client_t *client = (ds_client_t *) arg;
     270        ds_window_t *wnd;
     271        errno_t rc;
     272
     273        ds_display_lock(client->display);
     274
     275        wnd = ds_client_find_window(client, wnd_id);
     276        if (wnd == NULL) {
     277                ds_display_unlock(client->display);
     278                return ENOENT;
     279        }
     280
     281        log_msg(LOG_DEFAULT, LVL_DEBUG, "disp_window_unmaximize()");
     282        rc = ds_window_unmaximize(wnd);
     283        ds_display_unlock(client->display);
     284        return rc;
     285}
     286
    221287static errno_t disp_window_set_cursor(void *arg, sysarg_t wnd_id,
    222288    display_stock_cursor_t cursor)
  • uspace/srv/hid/display/test/window.c

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    9999}
    100100
     101/** Test ds_window_get_pos(). */
     102PCUT_TEST(get_pos)
     103{
     104        ds_display_t *disp;
     105        ds_client_t *client;
     106        ds_seat_t *seat;
     107        ds_window_t *wnd;
     108        display_wnd_params_t params;
     109        gfx_coord2_t pos;
     110        errno_t rc;
     111
     112        rc = ds_display_create(NULL, df_none, &disp);
     113        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     114
     115        rc = ds_client_create(disp, NULL, NULL, &client);
     116        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     117
     118        rc = ds_seat_create(disp, &seat);
     119        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     120
     121        display_wnd_params_init(&params);
     122        params.rect.p0.x = params.rect.p0.y = 0;
     123        params.rect.p1.x = params.rect.p1.y = 10;
     124
     125        rc = ds_window_create(client, &params, &wnd);
     126        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     127
     128        wnd->dpos.x = 100;
     129        wnd->dpos.y = 100;
     130
     131        ds_window_get_pos(wnd, &pos);
     132
     133        PCUT_ASSERT_INT_EQUALS(100, pos.x);
     134        PCUT_ASSERT_INT_EQUALS(100, pos.y);
     135
     136        ds_window_destroy(wnd);
     137        ds_seat_destroy(seat);
     138        ds_client_destroy(client);
     139        ds_display_destroy(disp);
     140}
     141
     142/** Test ds_window_get_max_rect(). */
     143PCUT_TEST(get_max_rect)
     144{
     145        ds_display_t *disp;
     146        ds_client_t *client;
     147        ds_seat_t *seat;
     148        ds_window_t *wnd;
     149        display_wnd_params_t params;
     150        gfx_rect_t rect;
     151        errno_t rc;
     152
     153        rc = ds_display_create(NULL, df_none, &disp);
     154        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     155
     156        rc = ds_client_create(disp, NULL, NULL, &client);
     157        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     158
     159        rc = ds_seat_create(disp, &seat);
     160        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     161
     162        display_wnd_params_init(&params);
     163        params.rect.p0.x = params.rect.p0.y = 0;
     164        params.rect.p1.x = params.rect.p1.y = 10;
     165
     166        rc = ds_window_create(client, &params, &wnd);
     167        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     168
     169        wnd->dpos.x = 100;
     170        wnd->dpos.y = 100;
     171
     172        ds_window_get_max_rect(wnd, &rect);
     173
     174        PCUT_ASSERT_INT_EQUALS(disp->rect.p0.x, rect.p0.x);
     175        PCUT_ASSERT_INT_EQUALS(disp->rect.p0.y, rect.p0.y);
     176        PCUT_ASSERT_INT_EQUALS(disp->rect.p1.x, rect.p1.x);
     177        PCUT_ASSERT_INT_EQUALS(disp->rect.p1.y, rect.p1.y);
     178
     179        ds_window_destroy(wnd);
     180        ds_seat_destroy(seat);
     181        ds_client_destroy(client);
     182        ds_display_destroy(disp);
     183}
     184
     185/** Test ds_window_maximize(). */
     186PCUT_TEST(window_maximize)
     187{
     188        ds_display_t *disp;
     189        ds_client_t *client;
     190        ds_seat_t *seat;
     191        ds_window_t *wnd;
     192        display_wnd_params_t params;
     193        errno_t rc;
     194
     195        rc = ds_display_create(NULL, df_none, &disp);
     196        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     197
     198        rc = ds_client_create(disp, NULL, NULL, &client);
     199        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     200
     201        rc = ds_seat_create(disp, &seat);
     202        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     203
     204        display_wnd_params_init(&params);
     205        params.rect.p0.x = params.rect.p0.y = 0;
     206        params.rect.p1.x = params.rect.p1.y = 10;
     207
     208        rc = ds_window_create(client, &params, &wnd);
     209        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     210
     211        wnd->dpos.x = 100;
     212        wnd->dpos.y = 100;
     213
     214        rc = ds_window_maximize(wnd);
     215        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     216
     217        PCUT_ASSERT_INT_EQUALS(wndf_maximized, wnd->flags & wndf_maximized);
     218
     219        ds_window_destroy(wnd);
     220        ds_seat_destroy(seat);
     221        ds_client_destroy(client);
     222        ds_display_destroy(disp);
     223}
     224
     225/** Test ds_window_unmaximize(). */
     226PCUT_TEST(window_unmaximize)
     227{
     228        ds_display_t *disp;
     229        ds_client_t *client;
     230        ds_seat_t *seat;
     231        ds_window_t *wnd;
     232        display_wnd_params_t params;
     233        errno_t rc;
     234
     235        rc = ds_display_create(NULL, df_none, &disp);
     236        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     237
     238        rc = ds_client_create(disp, NULL, NULL, &client);
     239        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     240
     241        rc = ds_seat_create(disp, &seat);
     242        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     243
     244        display_wnd_params_init(&params);
     245        params.rect.p0.x = params.rect.p0.y = 0;
     246        params.rect.p1.x = params.rect.p1.y = 10;
     247
     248        rc = ds_window_create(client, &params, &wnd);
     249        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     250
     251        wnd->dpos.x = 100;
     252        wnd->dpos.y = 100;
     253
     254        rc = ds_window_maximize(wnd);
     255        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     256
     257        rc = ds_window_unmaximize(wnd);
     258        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     259
     260        PCUT_ASSERT_INT_EQUALS(0, wnd->flags & wndf_maximized);
     261
     262        ds_window_destroy(wnd);
     263        ds_seat_destroy(seat);
     264        ds_client_destroy(client);
     265        ds_display_destroy(disp);
     266}
     267
    101268/** Test ds_window_get_ctx(). */
    102269PCUT_TEST(window_get_ctx)
  • uspace/srv/hid/display/types/display/window.h

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    7979        /** Minimum size */
    8080        gfx_coord2_t min_size;
     81        /** Normal rectangle (when not maximized or minimized) */
     82        gfx_rect_t normal_rect;
     83        /** Normal display position (when not maximized or minimized) */
     84        gfx_coord2_t normal_dpos;
    8185        /** Window ID */
    8286        ds_wnd_id_t id;
  • uspace/srv/hid/display/window.c

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    580580 * @param wnd Window
    581581 * @param event Position event
     582 *
     583 * @return EOK on success or an error code
    582584 */
    583585errno_t ds_window_post_pos_event(ds_window_t *wnd, pos_event_t *event)
     
    597599        inside = gfx_pix_inside_rect(&pos, &drect);
    598600
    599         if (event->type == POS_PRESS && event->btn_num == 2 && inside) {
     601        if (event->type == POS_PRESS && event->btn_num == 2 && inside &&
     602            (wnd->flags & wndf_maximized) == 0) {
    600603                ds_window_start_move(wnd, &pos);
    601604                return EOK;
     
    637640 *
    638641 * @param wnd Window
     642 * @return EOK on success or an error code
    639643 */
    640644errno_t ds_window_post_focus_event(ds_window_t *wnd)
     
    648652 *
    649653 * @param wnd Window
     654 * @return EOK on success or an error code
    650655 */
    651656errno_t ds_window_post_unfocus_event(ds_window_t *wnd)
     
    691696{
    692697        *dpos = wnd->dpos;
     698}
     699
     700/** Get maximized window rectangle.
     701 *
     702 * @param wnd Window
     703 */
     704void ds_window_get_max_rect(ds_window_t *wnd, gfx_rect_t *rect)
     705{
     706        *rect = wnd->display->rect;
    693707}
    694708
     
    716730 *
    717731 * @param wnd Window
     732 * @return EOK on success or an error code
    718733 */
    719734errno_t ds_window_resize(ds_window_t *wnd, gfx_coord2_t *offs,
     
    770785}
    771786
     787/** Maximize window.
     788 *
     789 * @param wnd Window
     790 * @return EOK on success or an error code
     791 */
     792errno_t ds_window_maximize(ds_window_t *wnd)
     793{
     794        gfx_coord2_t old_dpos;
     795        gfx_rect_t old_rect;
     796        gfx_coord2_t offs;
     797        gfx_rect_t max_rect;
     798        gfx_rect_t nrect;
     799        errno_t rc;
     800
     801        /* If already maximized, do nothing and return success. */
     802        if ((wnd->flags & wndf_maximized) != 0)
     803                return EOK;
     804
     805        /* Remember the old window rectangle and display position */
     806        old_rect = wnd->rect;
     807        old_dpos = wnd->dpos;
     808
     809        ds_window_get_max_rect(wnd, &max_rect);
     810
     811        /* Keep window contents on the same position on the screen */
     812        offs.x = max_rect.p0.x - wnd->dpos.x;
     813        offs.y = max_rect.p0.y - wnd->dpos.y;
     814
     815        /* Maximized window's coordinates will start at 0,0 */
     816        gfx_rect_rtranslate(&max_rect.p0, &max_rect, &nrect);
     817
     818        rc = ds_window_resize(wnd, &offs, &nrect);
     819        if (rc != EOK)
     820                return rc;
     821
     822        /* Set window flags, remember normal rectangle */
     823        wnd->flags |= wndf_maximized;
     824        wnd->normal_rect = old_rect;
     825        wnd->normal_dpos = old_dpos;
     826
     827        return EOK;
     828}
     829
     830/** Unmaximize window.
     831 *
     832 * @param wnd Window
     833 * @return EOK on success or an error code
     834 */
     835errno_t ds_window_unmaximize(ds_window_t *wnd)
     836{
     837        gfx_coord2_t offs;
     838        errno_t rc;
     839
     840        /* If not maximized, do nothing and return success. */
     841        if ((wnd->flags & wndf_maximized) == 0)
     842                return EOK;
     843
     844        /* Keep window contents on the same position on the screen */
     845        offs.x = wnd->normal_dpos.x - wnd->dpos.x;
     846        offs.y = wnd->normal_dpos.y - wnd->dpos.y;
     847
     848        rc = ds_window_resize(wnd, &offs, &wnd->normal_rect);
     849        if (rc != EOK)
     850                return rc;
     851
     852        /* Set window flags, remember normal rectangle */
     853        wnd->flags &= ~wndf_maximized;
     854
     855        return EOK;
     856}
     857
    772858/** Compute new window rectangle after resize operation.
    773859 *
  • uspace/srv/hid/display/window.h

    rfd05ea6 r35cffea  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
     2 * Copyright (c) 2022 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6464extern void ds_window_move(ds_window_t *, gfx_coord2_t *);
    6565extern void ds_window_get_pos(ds_window_t *, gfx_coord2_t *);
     66extern void ds_window_get_max_rect(ds_window_t *, gfx_rect_t *);
    6667extern void ds_window_resize_req(ds_window_t *, display_wnd_rsztype_t,
    6768    gfx_coord2_t *);
    6869extern errno_t ds_window_resize(ds_window_t *, gfx_coord2_t *, gfx_rect_t *);
     70extern errno_t ds_window_maximize(ds_window_t *);
     71extern errno_t ds_window_unmaximize(ds_window_t *);
    6972extern void ds_window_calc_resize(ds_window_t *, gfx_coord2_t *,
    7073    gfx_rect_t *);
Note: See TracChangeset for help on using the changeset viewer.