Changeset 0e6e77f in mainline for uspace/lib/display


Ignore:
Timestamp:
2020-02-28T15:44:55Z (5 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a8eed5f
Parents:
2a515dcd
git-author:
Jiri Svoboda <jiri@…> (2020-02-26 18:26:13)
git-committer:
Jiri Svoboda <jiri@…> (2020-02-28 15:44:55)
Message:

Window resize by client request

Location:
uspace/lib/display
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/display/include/disp_srv.h

    r2a515dcd r0e6e77f  
    3838#include <async.h>
    3939#include <errno.h>
     40#include <gfx/coord.h>
    4041#include "display/wndparams.h"
    4142#include "types/display/event.h"
     
    5354        errno_t (*window_create)(void *, display_wnd_params_t *, sysarg_t *);
    5455        errno_t (*window_destroy)(void *, sysarg_t);
     56        errno_t (*window_resize)(void *, sysarg_t, gfx_coord2_t *, gfx_rect_t *);
    5557        errno_t (*get_event)(void *, sysarg_t *, display_wnd_ev_t *);
    5658};
  • uspace/lib/display/include/display.h

    r2a515dcd r0e6e77f  
    3838#include <errno.h>
    3939#include <gfx/context.h>
     40#include <gfx/coord.h>
    4041#include <stdbool.h>
    4142#include "display/wndparams.h"
     
    4849extern errno_t display_window_destroy(display_window_t *);
    4950extern errno_t display_window_get_gc(display_window_t *, gfx_context_t **);
     51extern errno_t display_window_resize(display_window_t *,
     52    gfx_coord2_t *, gfx_rect_t *);
    5053
    5154#endif
  • uspace/lib/display/include/ipc/display.h

    r2a515dcd r0e6e77f  
    4242        DISPLAY_WINDOW_CREATE,
    4343        DISPLAY_WINDOW_DESTROY,
     44        DISPLAY_WINDOW_RESIZE,
    4445        DISPLAY_GET_EVENT
    4546} display_request_t;
  • uspace/lib/display/src/disp_srv.c

    r2a515dcd r0e6e77f  
    4343#include <stdlib.h>
    4444#include <stddef.h>
     45#include "../private/params.h"
    4546
    4647static void display_callback_create_srv(display_srv_t *srv, ipc_call_t *call)
     
    108109}
    109110
     111static void display_window_resize_srv(display_srv_t *srv, ipc_call_t *icall)
     112{
     113        sysarg_t wnd_id;
     114        ipc_call_t call;
     115        display_wnd_move_t wmove;
     116        size_t size;
     117        errno_t rc;
     118
     119        wnd_id = ipc_get_arg1(icall);
     120
     121        if (!async_data_write_receive(&call, &size)) {
     122                async_answer_0(&call, EREFUSED);
     123                async_answer_0(icall, EREFUSED);
     124                return;
     125        }
     126
     127        if (size != sizeof(display_wnd_move_t)) {
     128                async_answer_0(&call, EINVAL);
     129                async_answer_0(icall, EINVAL);
     130                return;
     131        }
     132
     133        rc = async_data_write_finalize(&call, &wmove, size);
     134        if (rc != EOK) {
     135                async_answer_0(&call, rc);
     136                async_answer_0(icall, rc);
     137                return;
     138        }
     139
     140        if (srv->ops->window_resize == NULL) {
     141                async_answer_0(icall, ENOTSUP);
     142                return;
     143        }
     144
     145        rc = srv->ops->window_resize(srv->arg, wnd_id, &wmove.offs,
     146            &wmove.nrect);
     147        async_answer_0(icall, rc);
     148}
     149
    110150static void display_get_event_srv(display_srv_t *srv, ipc_call_t *icall)
    111151{
     
    175215                case DISPLAY_WINDOW_DESTROY:
    176216                        display_window_destroy_srv(srv, &call);
     217                        break;
     218                case DISPLAY_WINDOW_RESIZE:
     219                        display_window_resize_srv(srv, &call);
    177220                        break;
    178221                case DISPLAY_GET_EVENT:
  • uspace/lib/display/src/display.c

    r2a515dcd r0e6e77f  
    3838#include <mem.h>
    3939#include <stdlib.h>
     40#include "../private/params.h"
    4041
    4142static errno_t display_callback_create(display_t *);
     
    237238
    238239        *rgc = ipc_gc_get_ctx(gc);
     240        return EOK;
     241}
     242
     243/** Resize display window.
     244 *
     245 * It seems resizing windows should be easy with bounding rectangles.
     246 * You have an old bounding rectangle and a new bounding rectangle (@a nrect).
     247 * Change .p0 and top-left corner moves. Change .p1 and bottom-right corner
     248 * moves. Piece of cake!
     249 *
     250 * There's always a catch, though. By series of resizes and moves .p0 could
     251 * drift outside of the range of @c gfx_coord_t. Now what? @a offs to the
     252 * rescue! @a offs moves the @em boundaries of the window with respect
     253 * to the display, while keeping the @em contents of the window in the
     254 * same place (with respect to the display). In other words, @a offs shifts
     255 * the window's internal coordinate system.
     256 *
     257 * A few examples follow:
     258 *
     259 * Enlarge window by moving bottom-right corner 1 right, 1 down:
     260 *
     261 *   bound = (0, 0, 10, 10)
     262 *   offs  = (0, 0)
     263 *   nrect = (0, 0, 11, 11)
     264 *
     265 * Enlarge window by moving top-left corner, 1 up, 1 left, allowing the
     266 * window-relative coordinate of the top-left corner to drift (undesirable)
     267 *
     268 *   bound = (0, 0, 10, 10)
     269 *   offs  = (0, 0)
     270 *   nrect = (-1, -1, 10, 10) <- this is the new bounding rectangle
     271 *
     272 * Enlarge window by moving top-left corner 1 up, 1 left, keeping top-left
     273 * corner locked to (0,0) window-relative coordinates (desirable):
     274 *
     275 *   bound = (0, 0, 10, 10)
     276 *   off   = (-1,-1)        <- top-left corner goes 1 up, 1 left
     277 *   nrect = (0, 0, 11, 11) <- window still starts at 0,0 window-relative
     278 *
     279 * @param window Window
     280 * @param nrect New bounding rectangle
     281 * @param offs
     282 * @return EOK on success or an error code. In both cases @a window must
     283 *         not be accessed anymore
     284 */
     285errno_t display_window_resize(display_window_t *window, gfx_coord2_t *offs,
     286    gfx_rect_t *nrect)
     287{
     288        async_exch_t *exch;
     289        aid_t req;
     290        ipc_call_t answer;
     291        display_wnd_move_t wmove;
     292        errno_t rc;
     293
     294        wmove.offs = *offs;
     295        wmove.nrect = *nrect;
     296
     297        exch = async_exchange_begin(window->display->sess);
     298        req = async_send_1(exch, DISPLAY_WINDOW_RESIZE, window->id, &answer);
     299        rc = async_data_write_start(exch, &wmove, sizeof (display_wnd_move_t));
     300        async_exchange_end(exch);
     301        if (rc != EOK) {
     302                async_forget(req);
     303                return rc;
     304        }
     305
     306        async_wait_for(req, &rc);
     307        if (rc != EOK)
     308                return rc;
     309
    239310        return EOK;
    240311}
  • uspace/lib/display/test/display.c

    r2a515dcd r0e6e77f  
    5555static errno_t test_window_create(void *, display_wnd_params_t *, sysarg_t *);
    5656static errno_t test_window_destroy(void *, sysarg_t);
     57static errno_t test_window_resize(void *, sysarg_t, gfx_coord2_t *,
     58    gfx_rect_t *);
    5759static errno_t test_get_event(void *, sysarg_t *, display_wnd_ev_t *);
    5860
     
    6264        .window_create = test_window_create,
    6365        .window_destroy = test_window_destroy,
     66        .window_resize = test_window_resize,
    6467        .get_event = test_get_event
    6568};
     
    8891        gfx_rect_t create_rect;
    8992        bool window_destroy_called;
     93        sysarg_t destroy_wnd_id;
     94
     95        bool window_resize_called;
     96        gfx_coord2_t resize_offs;
     97        gfx_rect_t resize_nbound;
     98        sysarg_t resize_wnd_id;
     99
    90100        bool get_event_called;
    91101        bool set_color_called;
     
    220230        rc = display_window_destroy(wnd);
    221231        PCUT_ASSERT_TRUE(resp.window_destroy_called);
     232        PCUT_ASSERT_INT_EQUALS(wnd->id, resp.destroy_wnd_id);
    222233        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    223234
     
    272283        rc = display_window_destroy(wnd);
    273284        PCUT_ASSERT_TRUE(resp.window_destroy_called);
     285        PCUT_ASSERT_INT_EQUALS(wnd->id, resp.destroy_wnd_id);
    274286        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
    275287
     288        display_close(disp);
     289        rc = loc_service_unregister(sid);
     290        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     291}
     292
     293/** display_window_resize() with server returning error response works. */
     294PCUT_TEST(window_resize_failure)
     295{
     296        errno_t rc;
     297        service_id_t sid;
     298        display_t *disp = NULL;
     299        display_wnd_params_t params;
     300        display_window_t *wnd;
     301        gfx_coord2_t offs;
     302        gfx_rect_t nrect;
     303        test_response_t resp;
     304
     305        async_set_fallback_port_handler(test_display_conn, &resp);
     306
     307        // FIXME This causes this test to be non-reentrant!
     308        rc = loc_server_register(test_display_server);
     309        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     310
     311        rc = loc_service_register(test_display_svc, &sid);
     312        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     313
     314        rc = display_open(test_display_svc, &disp);
     315        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     316        PCUT_ASSERT_NOT_NULL(disp);
     317
     318        resp.rc = EOK;
     319        display_wnd_params_init(&params);
     320        params.rect.p0.x = 0;
     321        params.rect.p0.y = 0;
     322        params.rect.p0.x = 100;
     323        params.rect.p0.y = 100;
     324
     325        rc = display_window_create(disp, &params, &test_display_wnd_cb,
     326            (void *) &resp, &wnd);
     327        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     328        PCUT_ASSERT_NOT_NULL(wnd);
     329
     330        resp.rc = EIO;
     331        resp.window_resize_called = false;
     332        offs.x = 11;
     333        offs.y = 12;
     334        nrect.p0.x = 13;
     335        nrect.p0.y = 14;
     336        nrect.p1.x = 15;
     337        nrect.p1.y = 16;
     338
     339        rc = display_window_resize(wnd, &offs, &nrect);
     340        PCUT_ASSERT_TRUE(resp.window_resize_called);
     341        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
     342        PCUT_ASSERT_INT_EQUALS(wnd->id, resp.resize_wnd_id);
     343        PCUT_ASSERT_INT_EQUALS(offs.x, resp.resize_offs.x);
     344        PCUT_ASSERT_INT_EQUALS(offs.y, resp.resize_offs.y);
     345        PCUT_ASSERT_INT_EQUALS(nrect.p0.x, resp.resize_nbound.p0.x);
     346        PCUT_ASSERT_INT_EQUALS(nrect.p0.y, resp.resize_nbound.p0.y);
     347        PCUT_ASSERT_INT_EQUALS(nrect.p1.x, resp.resize_nbound.p1.x);
     348        PCUT_ASSERT_INT_EQUALS(nrect.p1.y, resp.resize_nbound.p1.y);
     349
     350        display_window_destroy(wnd);
     351        display_close(disp);
     352        rc = loc_service_unregister(sid);
     353        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     354}
     355
     356/** display_window_resize() with server returning success response works. */
     357PCUT_TEST(window_resize_success)
     358{
     359        errno_t rc;
     360        service_id_t sid;
     361        display_t *disp = NULL;
     362        display_wnd_params_t params;
     363        display_window_t *wnd;
     364        gfx_coord2_t offs;
     365        gfx_rect_t nrect;
     366        test_response_t resp;
     367
     368        async_set_fallback_port_handler(test_display_conn, &resp);
     369
     370        // FIXME This causes this test to be non-reentrant!
     371        rc = loc_server_register(test_display_server);
     372        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     373
     374        rc = loc_service_register(test_display_svc, &sid);
     375        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     376
     377        rc = display_open(test_display_svc, &disp);
     378        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     379        PCUT_ASSERT_NOT_NULL(disp);
     380
     381        resp.rc = EOK;
     382        display_wnd_params_init(&params);
     383        params.rect.p0.x = 0;
     384        params.rect.p0.y = 0;
     385        params.rect.p0.x = 100;
     386        params.rect.p0.y = 100;
     387
     388        rc = display_window_create(disp, &params, &test_display_wnd_cb,
     389            (void *) &resp, &wnd);
     390        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     391        PCUT_ASSERT_NOT_NULL(wnd);
     392
     393        resp.rc = EOK;
     394        resp.window_resize_called = false;
     395        offs.x = 11;
     396        offs.y = 12;
     397        nrect.p0.x = 13;
     398        nrect.p0.y = 14;
     399        nrect.p1.x = 15;
     400        nrect.p1.y = 16;
     401
     402        rc = display_window_resize(wnd, &offs, &nrect);
     403        PCUT_ASSERT_TRUE(resp.window_resize_called);
     404        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
     405        PCUT_ASSERT_INT_EQUALS(offs.x, resp.resize_offs.x);
     406        PCUT_ASSERT_INT_EQUALS(offs.y, resp.resize_offs.y);
     407        PCUT_ASSERT_INT_EQUALS(nrect.p0.x, resp.resize_nbound.p0.x);
     408        PCUT_ASSERT_INT_EQUALS(nrect.p0.y, resp.resize_nbound.p0.y);
     409        PCUT_ASSERT_INT_EQUALS(nrect.p1.x, resp.resize_nbound.p1.x);
     410        PCUT_ASSERT_INT_EQUALS(nrect.p1.y, resp.resize_nbound.p1.y);
     411
     412        display_window_destroy(wnd);
    276413        display_close(disp);
    277414        rc = loc_service_unregister(sid);
     
    792929
    793930        resp->window_destroy_called = true;
     931        resp->destroy_wnd_id = wnd_id;
     932        return resp->rc;
     933}
     934
     935static errno_t test_window_resize(void *arg, sysarg_t wnd_id,
     936    gfx_coord2_t *offs, gfx_rect_t *nrect)
     937{
     938        test_response_t *resp = (test_response_t *) arg;
     939
     940        resp->window_resize_called = true;
     941        resp->resize_wnd_id = wnd_id;
     942        resp->resize_offs = *offs;
     943        resp->resize_nbound = *nrect;
    794944        return resp->rc;
    795945}
Note: See TracChangeset for help on using the changeset viewer.