Changeset 0e6e77f in mainline


Ignore:
Timestamp:
2020-02-28T15:44:55Z (4 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
Files:
15 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}
  • uspace/lib/gfx/include/gfx/coord.h

    r2a515dcd r0e6e77f  
    5252extern void gfx_rect_clip(gfx_rect_t *, gfx_rect_t *, gfx_rect_t *);
    5353extern void gfx_rect_points_sort(gfx_rect_t *, gfx_rect_t *);
     54extern void gfx_rect_dims(gfx_rect_t *, gfx_coord2_t *);
    5455extern bool gfx_rect_is_empty(gfx_rect_t *);
    5556extern bool gfx_pix_inside_rect(gfx_coord2_t *, gfx_rect_t *);
  • uspace/lib/gfx/src/coord.c

    r2a515dcd r0e6e77f  
    235235}
    236236
     237/** Get rectangle dimensions.
     238 *
     239 * Get a vector containing the x, y dimensions of a rectangle. These are
     240 * always nonnegative.
     241 *
     242 * @param rect Rectangle
     243 * @param dims Place to store dimensions
     244 */
     245void gfx_rect_dims(gfx_rect_t *rect, gfx_coord2_t *dims)
     246{
     247        gfx_rect_t srect;
     248
     249        gfx_rect_points_sort(rect, &srect);
     250        gfx_coord2_subtract(&srect.p1, &srect.p0, dims);
     251}
     252
    237253/** Return true if pixel at coordinate @a coord lies within rectangle @a rect. */
    238254bool gfx_pix_inside_rect(gfx_coord2_t *coord, gfx_rect_t *rect)
  • uspace/lib/gfx/test/coord.c

    r2a515dcd r0e6e77f  
    239239
    240240/** Sorting span with hight start and lower end point results in transposed span. */
    241 PCUT_TEST(span_points_sort_decs)
     241PCUT_TEST(span_points_sort_desc)
    242242{
    243243        gfx_coord_t a, b;
     
    580580}
    581581
     582/** Rectangle dimensions for straight rectangle are computed correctly */
     583PCUT_TEST(rect_dims_straight)
     584{
     585        gfx_rect_t rect;
     586        gfx_coord2_t dims;
     587
     588        rect.p0.x = 1;
     589        rect.p0.y = 10;
     590        rect.p1.x = 100;
     591        rect.p1.y = 1000;
     592
     593        gfx_rect_dims(&rect, &dims);
     594
     595        PCUT_ASSERT_INT_EQUALS(99, dims.x);
     596        PCUT_ASSERT_INT_EQUALS(990, dims.y);
     597}
     598
     599/** Rectangle dimensions for reversed rectangle are computed correctly */
     600PCUT_TEST(rect_dims_straight)
     601{
     602        gfx_rect_t rect;
     603        gfx_coord2_t dims;
     604
     605        rect.p0.x = 1000;
     606        rect.p0.y = 100;
     607        rect.p1.x = 10;
     608        rect.p1.y = 1;
     609
     610        gfx_rect_dims(&rect, &dims);
     611
     612        PCUT_ASSERT_INT_EQUALS(990, dims.x);
     613        PCUT_ASSERT_INT_EQUALS(99, dims.y);
     614}
     615
    582616/** gfx_rect_is_empty for straight rectangle with zero columns returns true */
    583617PCUT_TEST(rect_is_empty_pos_x)
  • uspace/lib/gui/window.c

    r2a515dcd r0e6e77f  
    382382    sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
    383383{
    384         display_wnd_params_t wparams;
    385         display_window_t *new_window = NULL;
    386384        gfx_bitmap_params_t params;
    387385        gfx_bitmap_alloc_t alloc;
    388386        gfx_bitmap_t *new_bitmap = NULL;
    389         gfx_context_t *new_gc = NULL;
     387        gfx_coord2_t offs;
     388        gfx_rect_t nrect;
    390389        errno_t rc;
    391390
     
    406405                return;
    407406
    408         display_wnd_params_init(&wparams);
    409         wparams.rect.p0.x = 0;
    410         wparams.rect.p0.y = 0;
    411         wparams.rect.p1.x = width;
    412         wparams.rect.p1.y = height;
    413 
    414         rc = display_window_create(win->display, &wparams, &window_cb,
    415             (void *) win, &new_window);
    416         if (rc != EOK) {
    417                 surface_destroy(new_surface);
    418                 return;
    419         }
    420 
    421         rc = display_window_get_gc(new_window, &new_gc);
    422         if (rc != EOK) {
    423                 display_window_destroy(new_window);
    424                 surface_destroy(new_surface);
    425                 return;
    426         }
    427 
    428407        params.rect.p0.x = 0;
    429408        params.rect.p0.y = 0;
     
    435414        alloc.pixels = surface_direct_access(new_surface);
    436415
    437         rc = gfx_bitmap_create(new_gc, &params, &alloc, &new_bitmap);
     416        rc = gfx_bitmap_create(win->gc, &params, &alloc, &new_bitmap);
    438417        if (rc != EOK) {
    439                 gfx_context_delete(new_gc);
    440                 display_window_destroy(new_window);
    441418                surface_destroy(new_surface);
    442419                return;
     
    447424        surface_t *old_surface = win->surface;
    448425        gfx_bitmap_t *old_bitmap = win->bitmap;
    449         display_window_t *old_window = win->dwindow;
    450         gfx_context_t *old_gc = win->gc;
    451426        win->surface = new_surface;
    452427        win->bitmap = new_bitmap;
    453         win->dwindow = new_window;
    454         win->gc = new_gc;
    455428        fibril_mutex_unlock(&win->guard);
    456429
     
    465438        fibril_mutex_unlock(&win->guard);
    466439
    467         /* Inform compositor about new surface. */
    468 #if 0
    469         errno_t rc = win_resize(win->osess, offset_x, offset_y, width, height,
    470             placement_flags, surface_direct_access(new_surface));
    471 #endif
    472         rc = EOK;
    473 
     440        /* Resize the display window. */
     441        offs.x = offset_x;
     442        offs.y = offset_y;
     443        nrect.p0.x = 0;
     444        nrect.p0.y = 0;
     445        nrect.p1.x = width;
     446        nrect.p1.y = height;
     447
     448        rc = display_window_resize(win->dwindow, &offs, &nrect);
    474449        if (rc != EOK) {
    475450                /* Rollback to old surface. Reverse all changes. */
     
    484459                win->surface = old_surface;
    485460                win->bitmap = old_bitmap;
    486                 win->dwindow = old_window;
    487                 win->gc = old_gc;
    488461                fibril_mutex_unlock(&win->guard);
    489462
     
    498471                surface_destroy(new_surface);
    499472        } else {
    500                 if (old_window != NULL)
    501                         display_window_destroy(old_window);
    502                 if (old_gc != NULL)
    503                         gfx_context_delete(old_gc);
    504473                if (old_bitmap != NULL)
    505474                        gfx_bitmap_destroy(old_bitmap);
     
    643612    window_flags_t flags, const char *caption)
    644613{
     614        display_wnd_params_t wparams;
     615
    645616        window_t *win = (window_t *) calloc(1, sizeof(window_t));
    646617        if (!win)
     
    663634        win->grab = NULL;
    664635        win->focus = NULL;
    665         win->surface = NULL;
     636
     637        /* Allocate resources for new surface. */
     638        win->surface = surface_create(100, 100, NULL, SURFACE_FLAG_SHARED);
     639        if (win->surface == NULL) {
     640                free(win);
     641                return NULL;
     642        }
    666643
    667644        errno_t rc = display_open(winreg, &win->display);
    668645        if (rc != EOK) {
     646                surface_destroy(win->surface);
     647                free(win);
     648                return NULL;
     649        }
     650
     651        /* Window dimensions are not know at this time */
     652        display_wnd_params_init(&wparams);
     653        wparams.rect.p0.x = 0;
     654        wparams.rect.p0.y = 0;
     655        wparams.rect.p1.x = 100;
     656        wparams.rect.p1.y = 100;
     657
     658        rc = display_window_create(win->display, &wparams, &window_cb,
     659            (void *) win, &win->dwindow);
     660        if (rc != EOK) {
     661                display_close(win->display);
     662                surface_destroy(win->surface);
     663                free(win);
     664                return NULL;
     665        }
     666
     667        rc = display_window_get_gc(win->dwindow, &win->gc);
     668        if (rc != EOK) {
     669                display_window_destroy(win->dwindow);
     670                display_close(win->display);
     671                surface_destroy(win->surface);
    669672                free(win);
    670673                return NULL;
  • uspace/srv/hid/display/dsops.c

    r2a515dcd r0e6e77f  
    3636#include <disp_srv.h>
    3737#include <errno.h>
     38#include <gfx/coord.h>
    3839#include <io/log.h>
    3940#include "client.h"
     
    4546static errno_t disp_window_create(void *, display_wnd_params_t *, sysarg_t *);
    4647static errno_t disp_window_destroy(void *, sysarg_t);
     48static errno_t disp_window_resize(void *, sysarg_t, gfx_coord2_t *,
     49    gfx_rect_t *);
    4750static errno_t disp_get_event(void *, sysarg_t *, display_wnd_ev_t *);
    4851
     
    5053        .window_create = disp_window_create,
    5154        .window_destroy = disp_window_destroy,
     55        .window_resize = disp_window_resize,
    5256        .get_event = disp_get_event
    5357};
     
    98102}
    99103
     104static errno_t disp_window_resize(void *arg, sysarg_t wnd_id,
     105    gfx_coord2_t *offs, gfx_rect_t *nbound)
     106{
     107        ds_client_t *client = (ds_client_t *) arg;
     108        ds_window_t *wnd;
     109
     110        wnd = ds_client_find_window(client, wnd_id);
     111        if (wnd == NULL)
     112                return ENOENT;
     113
     114        log_msg(LOG_DEFAULT, LVL_NOTE, "disp_window_resize()");
     115        return ds_window_resize(wnd, offs, nbound);
     116}
     117
    100118static errno_t disp_get_event(void *arg, sysarg_t *wnd_id,
    101119    display_wnd_ev_t *event)
  • uspace/srv/hid/display/test/display.c

    r2a515dcd r0e6e77f  
    5353        printf("test_ds_ev_pending\n");
    5454        *called_cb = true;
    55 
    5655}
    5756
     
    265264        event.c = L'\0';
    266265
    267         PCUT_ASSERT_FALSE(called_cb);
     266        called_cb = false;
    268267
    269268        rc = ds_display_post_kbd_event(disp, &event);
     
    316315        event.c = L'\0';
    317316
    318         PCUT_ASSERT_FALSE(called_cb);
     317        called_cb = false;
    319318
    320319        rc = ds_display_post_kbd_event(disp, &event);
    321320        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    322         PCUT_ASSERT_FALSE(called_cb);
     321
     322        /* Got gocus/unfocus events */
     323        PCUT_ASSERT_TRUE(called_cb);
    323324
    324325        /* Next window should be focused */
    325326        PCUT_ASSERT_EQUALS(w1, seat->focus);
    326327
     328        called_cb = false;
     329
    327330        rc = ds_display_post_kbd_event(disp, &event);
    328331        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    329         PCUT_ASSERT_FALSE(called_cb);
     332
     333        /* Got gocus/unfocus events */
     334        PCUT_ASSERT_TRUE(called_cb);
    330335
    331336        /* Focus should be back to the first window */
     
    361366        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    362367
     368        /*
     369         * For PTD_MOVE to work we need to set display dimensions (as pointer
     370         * move is clipped to the display rectangle. Here we do it directly
     371         * instead of adding a display device.
     372         */
     373        disp->rect.p0.x = 0;
     374        disp->rect.p0.y = 0;
     375        disp->rect.p1.x = 500;
     376        disp->rect.p1.y = 500;
     377
    363378        display_wnd_params_init(&params);
    364379        params.rect.p0.x = params.rect.p0.y = 0;
  • uspace/srv/hid/display/test/window.c

    r2a515dcd r0e6e77f  
    4949        .fill_rect = dummy_fill_rect
    5050};
     51
     52/** Test ds_window_resize(). */
     53PCUT_TEST(window_resize)
     54{
     55        ds_display_t *disp;
     56        ds_client_t *client;
     57        ds_window_t *wnd;
     58        display_wnd_params_t params;
     59        gfx_coord2_t offs;
     60        gfx_rect_t nrect;
     61        errno_t rc;
     62
     63        rc = ds_display_create(NULL, &disp);
     64        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     65
     66        rc = ds_client_create(disp, NULL, NULL, &client);
     67        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     68
     69        display_wnd_params_init(&params);
     70        params.rect.p0.x = params.rect.p0.y = 0;
     71        params.rect.p1.x = params.rect.p1.y = 10;
     72
     73        rc = ds_window_create(client, &params, &wnd);
     74        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     75
     76        wnd->dpos.x = 100;
     77        wnd->dpos.y = 100;
     78
     79        offs.x = -2;
     80        offs.y = -3;
     81        params.rect.p0.x = params.rect.p0.y = 0;
     82        params.rect.p1.x = 12;
     83        params.rect.p1.y = 13;
     84        rc = ds_window_resize(wnd, &offs, &nrect);
     85        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     86
     87        PCUT_ASSERT_INT_EQUALS(98, wnd->dpos.x);
     88        PCUT_ASSERT_INT_EQUALS(97, wnd->dpos.y);
     89
     90        ds_window_destroy(wnd);
     91        ds_client_destroy(client);
     92        ds_display_destroy(disp);
     93}
    5194
    5295/** Test ds_window_get_ctx(). */
  • uspace/srv/hid/display/window.c

    r2a515dcd r0e6e77f  
    264264        gfx_context_t *gc = NULL;
    265265        gfx_context_t *dgc;
    266         gfx_rect_t rect;
    267266        gfx_coord2_t dims;
    268267        gfx_bitmap_params_t bparams;
     
    282281        ds_client_add_window(client, wnd);
    283282        ds_display_add_window(client->display, wnd);
    284 
    285         gfx_rect_points_sort(&params->rect, &rect);
    286         gfx_coord2_subtract(&rect.p1, &rect.p0, &dims);
    287283
    288284        bparams.rect = params->rect;
     
    298294                        goto error;
    299295
     296                gfx_rect_dims(&params->rect, &dims);
    300297                wnd->pixelmap.width = dims.x;
    301298                wnd->pixelmap.height = dims.y;
    302299                wnd->pixelmap.data = alloc.pixels;
    303 
    304                 if (wnd->pixelmap.data == NULL) {
    305                         rc = ENOMEM;
    306                         goto error;
    307                 }
    308300        }
    309301
     
    323315}
    324316
    325 /** Delete window GC.
    326  *
    327  * @param wnd Window GC
     317/** Destroy window.
     318 *
     319 * @param wnd Window
    328320 */
    329321void ds_window_destroy(ds_window_t *wnd)
     
    343335
    344336        (void) ds_display_paint(disp, NULL);
     337}
     338
     339/** Resize window.
     340 *
     341 * @param wnd Window
     342 */
     343errno_t ds_window_resize(ds_window_t *wnd, gfx_coord2_t *offs,
     344    gfx_rect_t *nrect)
     345{
     346        gfx_context_t *dgc;
     347        gfx_bitmap_params_t bparams;
     348        gfx_bitmap_t *nbitmap;
     349        pixelmap_t npixelmap;
     350        gfx_coord2_t dims;
     351        gfx_bitmap_alloc_t alloc;
     352        gfx_coord2_t ndpos;
     353        errno_t rc;
     354
     355        dgc = ds_display_get_gc(wnd->display); // XXX
     356        if (dgc != NULL) {
     357                bparams.rect = *nrect;
     358
     359                rc = gfx_bitmap_create(dgc, &bparams, NULL, &nbitmap);
     360                if (rc != EOK)
     361                        return ENOMEM;
     362
     363                rc = gfx_bitmap_get_alloc(nbitmap, &alloc);
     364                if (rc != EOK) {
     365                        gfx_bitmap_destroy(nbitmap);
     366                        return ENOMEM;
     367                }
     368
     369                gfx_rect_dims(nrect, &dims);
     370                npixelmap.width = dims.x;
     371                npixelmap.height = dims.y;
     372                npixelmap.data = alloc.pixels;
     373
     374                /* TODO: Transfer contents within overlap */
     375
     376                if (wnd->bitmap != NULL)
     377                        gfx_bitmap_destroy(wnd->bitmap);
     378
     379                wnd->bitmap = nbitmap;
     380                wnd->pixelmap = npixelmap;
     381        }
     382
     383        gfx_coord2_add(&wnd->dpos, offs, &ndpos);
     384
     385        wnd->dpos = ndpos;
     386        wnd->rect = *nrect;
     387
     388        (void) ds_display_paint(wnd->display, NULL);
     389        return EOK;
    345390}
    346391
  • uspace/srv/hid/display/window.h

    r2a515dcd r0e6e77f  
    5151    ds_window_t **);
    5252extern void ds_window_destroy(ds_window_t *);
     53extern errno_t ds_window_resize(ds_window_t *, gfx_coord2_t *, gfx_rect_t *);
    5354extern gfx_context_t *ds_window_get_ctx(ds_window_t *);
    5455extern errno_t ds_window_paint(ds_window_t *, gfx_rect_t *);
Note: See TracChangeset for help on using the changeset viewer.