Changeset 0680854 in mainline


Ignore:
Timestamp:
2020-03-20T15:42:27Z (5 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0b7e394
Parents:
aeb3037
git-author:
Jiri Svoboda <jiri@…> (2020-03-19 19:42:21)
git-committer:
Jiri Svoboda <jiri@…> (2020-03-20 15:42:27)
Message:

Moving window by client request, emulate window placement flags

Location:
uspace
Files:
11 edited

Legend:

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

    raeb3037 r0680854  
    5656        }
    5757
    58         window_resize(main_window, 0, 0, 648, 508, WINDOW_PLACEMENT_ANY);
     58        window_resize(main_window, 0, 0, 648, 508, WINDOW_PLACEMENT_TOP |
     59            WINDOW_PLACEMENT_LEFT);
    5960        terminal_t *terminal_widget =
    6061            create_terminal(window_root(main_window), NULL, 640, 480);
  • uspace/lib/display/include/disp_srv.h

    raeb3037 r0680854  
    5959        errno_t (*window_resize_req)(void *, sysarg_t, display_wnd_rsztype_t,
    6060            gfx_coord2_t *);
     61        errno_t (*window_move)(void *, sysarg_t, gfx_coord2_t *);
    6162        errno_t (*window_resize)(void *, sysarg_t, gfx_coord2_t *, gfx_rect_t *);
    6263        errno_t (*get_event)(void *, sysarg_t *, display_wnd_ev_t *);
  • uspace/lib/display/include/display.h

    raeb3037 r0680854  
    5656extern errno_t display_window_resize_req(display_window_t *,
    5757    display_wnd_rsztype_t, gfx_coord2_t *);
     58extern errno_t display_window_move(display_window_t *, gfx_coord2_t *);
    5859extern errno_t display_window_resize(display_window_t *,
    5960    gfx_coord2_t *, gfx_rect_t *);
  • uspace/lib/display/include/ipc/display.h

    raeb3037 r0680854  
    4242        DISPLAY_WINDOW_CREATE,
    4343        DISPLAY_WINDOW_DESTROY,
     44        DISPLAY_WINDOW_MOVE,
    4445        DISPLAY_WINDOW_MOVE_REQ,
    4546        DISPLAY_WINDOW_RESIZE,
  • uspace/lib/display/src/disp_srv.c

    raeb3037 r0680854  
    149149}
    150150
    151 static void display_window_resize_req_srv(display_srv_t *srv, ipc_call_t *icall)
    152 {
    153         sysarg_t wnd_id;
    154         ipc_call_t call;
    155         display_wnd_rsztype_t rsztype;
    156         gfx_coord2_t pos;
     151static void display_window_move_srv(display_srv_t *srv, ipc_call_t *icall)
     152{
     153        sysarg_t wnd_id;
     154        ipc_call_t call;
     155        gfx_coord2_t dpos;
    157156        size_t size;
    158157        errno_t rc;
    159158
    160159        wnd_id = ipc_get_arg1(icall);
    161         rsztype = (display_wnd_rsztype_t) ipc_get_arg2(icall);
    162160
    163161        if (!async_data_write_receive(&call, &size)) {
     
    173171        }
    174172
     173        rc = async_data_write_finalize(&call, &dpos, size);
     174        if (rc != EOK) {
     175                async_answer_0(&call, rc);
     176                async_answer_0(icall, rc);
     177                return;
     178        }
     179
     180        if (srv->ops->window_move == NULL) {
     181                async_answer_0(icall, ENOTSUP);
     182                return;
     183        }
     184
     185        rc = srv->ops->window_move(srv->arg, wnd_id, &dpos);
     186        async_answer_0(icall, rc);
     187}
     188
     189
     190static void display_window_resize_req_srv(display_srv_t *srv, ipc_call_t *icall)
     191{
     192        sysarg_t wnd_id;
     193        ipc_call_t call;
     194        display_wnd_rsztype_t rsztype;
     195        gfx_coord2_t pos;
     196        size_t size;
     197        errno_t rc;
     198
     199        wnd_id = ipc_get_arg1(icall);
     200        rsztype = (display_wnd_rsztype_t) ipc_get_arg2(icall);
     201
     202        if (!async_data_write_receive(&call, &size)) {
     203                async_answer_0(&call, EREFUSED);
     204                async_answer_0(icall, EREFUSED);
     205                return;
     206        }
     207
     208        if (size != sizeof(gfx_coord2_t)) {
     209                async_answer_0(&call, EINVAL);
     210                async_answer_0(icall, EINVAL);
     211                return;
     212        }
     213
    175214        rc = async_data_write_finalize(&call, &pos, size);
    176215        if (rc != EOK) {
     
    339378                case DISPLAY_WINDOW_MOVE_REQ:
    340379                        display_window_move_req_srv(srv, &call);
     380                        break;
     381                case DISPLAY_WINDOW_MOVE:
     382                        display_window_move_srv(srv, &call);
    341383                        break;
    342384                case DISPLAY_WINDOW_RESIZE_REQ:
  • uspace/lib/display/src/display.c

    raeb3037 r0680854  
    277277}
    278278
     279/** Move display window.
     280 *
     281 * Set new display position of a window. Display position determines where
     282 * the origin of the window coordinate system lies. Note that the top left
     283 * corner of the window need not coincide with the window's 0,0 point.
     284 *
     285 * @param window Window
     286 * @param dpos New display position
     287 * @return EOK on success or an error code
     288 */
     289errno_t display_window_move(display_window_t *window, gfx_coord2_t *dpos)
     290{
     291        async_exch_t *exch;
     292        aid_t req;
     293        ipc_call_t answer;
     294        errno_t rc;
     295
     296        exch = async_exchange_begin(window->display->sess);
     297        req = async_send_1(exch, DISPLAY_WINDOW_MOVE, window->id, &answer);
     298        rc = async_data_write_start(exch, dpos, sizeof (gfx_coord2_t));
     299        async_exchange_end(exch);
     300        if (rc != EOK) {
     301                async_forget(req);
     302                return rc;
     303        }
     304
     305        async_wait_for(req, &rc);
     306        if (rc != EOK)
     307                return rc;
     308
     309        return EOK;
     310}
     311
     312
    279313/** Request a window resize.
    280314 *
  • uspace/lib/display/test/display.c

    raeb3037 r0680854  
    5757static errno_t test_window_destroy(void *, sysarg_t);
    5858static errno_t test_window_move_req(void *, sysarg_t, gfx_coord2_t *);
     59static errno_t test_window_move(void *, sysarg_t, gfx_coord2_t *);
    5960static errno_t test_window_resize_req(void *, sysarg_t, display_wnd_rsztype_t,
    6061    gfx_coord2_t *);
     
    7071        .window_destroy = test_window_destroy,
    7172        .window_move_req = test_window_move_req,
     73        .window_move = test_window_move,
    7274        .window_resize_req = test_window_resize_req,
    7375        .window_resize = test_window_resize,
     
    106108        sysarg_t move_req_wnd_id;
    107109        gfx_coord2_t move_req_pos;
     110
     111        bool window_move_called;
     112        sysarg_t move_wnd_id;
     113        gfx_coord2_t move_dpos;
    108114
    109115        bool window_resize_req_called;
     
    422428        PCUT_ASSERT_INT_EQUALS(pos.x, resp.move_req_pos.x);
    423429        PCUT_ASSERT_INT_EQUALS(pos.y, resp.move_req_pos.y);
     430
     431        display_window_destroy(wnd);
     432        display_close(disp);
     433        rc = loc_service_unregister(sid);
     434        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     435}
     436
     437/** display_window_move() with server returning error response works. */
     438PCUT_TEST(window_move_failure)
     439{
     440        errno_t rc;
     441        service_id_t sid;
     442        display_t *disp = NULL;
     443        display_wnd_params_t params;
     444        display_window_t *wnd;
     445        gfx_coord2_t dpos;
     446        test_response_t resp;
     447
     448        async_set_fallback_port_handler(test_display_conn, &resp);
     449
     450        // FIXME This causes this test to be non-reentrant!
     451        rc = loc_server_register(test_display_server);
     452        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     453
     454        rc = loc_service_register(test_display_svc, &sid);
     455        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     456
     457        rc = display_open(test_display_svc, &disp);
     458        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     459        PCUT_ASSERT_NOT_NULL(disp);
     460
     461        resp.rc = EOK;
     462        display_wnd_params_init(&params);
     463        params.rect.p0.x = 0;
     464        params.rect.p0.y = 0;
     465        params.rect.p0.x = 100;
     466        params.rect.p0.y = 100;
     467
     468        rc = display_window_create(disp, &params, &test_display_wnd_cb,
     469            (void *) &resp, &wnd);
     470        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     471        PCUT_ASSERT_NOT_NULL(wnd);
     472
     473        resp.rc = EIO;
     474        resp.window_move_called = false;
     475        dpos.x = 11;
     476        dpos.y = 12;
     477
     478        rc = display_window_move(wnd, &dpos);
     479        PCUT_ASSERT_TRUE(resp.window_move_called);
     480        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
     481        PCUT_ASSERT_INT_EQUALS(wnd->id, resp.move_wnd_id);
     482        PCUT_ASSERT_INT_EQUALS(dpos.x, resp.move_dpos.x);
     483        PCUT_ASSERT_INT_EQUALS(dpos.y, resp.move_dpos.y);
     484
     485        display_window_destroy(wnd);
     486        display_close(disp);
     487        rc = loc_service_unregister(sid);
     488        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     489}
     490
     491/** display_window_move() with server returning success response works. */
     492PCUT_TEST(window_move_success)
     493{
     494        errno_t rc;
     495        service_id_t sid;
     496        display_t *disp = NULL;
     497        display_wnd_params_t params;
     498        display_window_t *wnd;
     499        gfx_coord2_t dpos;
     500        test_response_t resp;
     501
     502        async_set_fallback_port_handler(test_display_conn, &resp);
     503
     504        // FIXME This causes this test to be non-reentrant!
     505        rc = loc_server_register(test_display_server);
     506        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     507
     508        rc = loc_service_register(test_display_svc, &sid);
     509        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     510
     511        rc = display_open(test_display_svc, &disp);
     512        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     513        PCUT_ASSERT_NOT_NULL(disp);
     514
     515        resp.rc = EOK;
     516        display_wnd_params_init(&params);
     517        params.rect.p0.x = 0;
     518        params.rect.p0.y = 0;
     519        params.rect.p0.x = 100;
     520        params.rect.p0.y = 100;
     521
     522        rc = display_window_create(disp, &params, &test_display_wnd_cb,
     523            (void *) &resp, &wnd);
     524        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     525        PCUT_ASSERT_NOT_NULL(wnd);
     526
     527        resp.rc = EOK;
     528        resp.window_move_called = false;
     529        dpos.x = 11;
     530        dpos.y = 12;
     531
     532        rc = display_window_move(wnd, &dpos);
     533        PCUT_ASSERT_TRUE(resp.window_move_called);
     534        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
     535        PCUT_ASSERT_INT_EQUALS(wnd->id, resp.move_wnd_id);
     536        PCUT_ASSERT_INT_EQUALS(dpos.x, resp.move_dpos.x);
     537        PCUT_ASSERT_INT_EQUALS(dpos.y, resp.move_dpos.y);
    424538
    425539        display_window_destroy(wnd);
     
    13521466}
    13531467
     1468static errno_t test_window_move(void *arg, sysarg_t wnd_id, gfx_coord2_t *dpos)
     1469{
     1470        test_response_t *resp = (test_response_t *) arg;
     1471
     1472        resp->window_move_called = true;
     1473        resp->move_wnd_id = wnd_id;
     1474        resp->move_dpos = *dpos;
     1475        return resp->rc;
     1476}
     1477
    13541478static errno_t test_window_resize_req(void *arg, sysarg_t wnd_id,
    13551479    display_wnd_rsztype_t rsztype, gfx_coord2_t *pos)
  • uspace/lib/gui/window.c

    raeb3037 r0680854  
    375375        gfx_bitmap_t *new_bitmap = NULL;
    376376        gfx_coord2_t offs;
     377        gfx_coord2_t dpos;
     378        display_info_t dinfo;
     379        gfx_rect_t drect;
    377380        gfx_rect_t nrect;
    378381        errno_t rc;
     
    460463
    461464                surface_destroy(new_surface);
    462         } else {
    463                 if (old_bitmap != NULL)
    464                         gfx_bitmap_destroy(old_bitmap);
    465                 /* Deallocate old surface. */
    466                 if (old_surface)
    467                         surface_destroy(old_surface);
    468 
    469                 (void) gfx_bitmap_render(win->bitmap, NULL, NULL);
    470         }
     465                return;
     466        }
     467
     468        if (old_bitmap != NULL)
     469                gfx_bitmap_destroy(old_bitmap);
     470        /* Deallocate old surface. */
     471        if (old_surface)
     472                surface_destroy(old_surface);
     473
     474        if (placement_flags != WINDOW_PLACEMENT_ANY) {
     475                dpos.x = 0;
     476                dpos.y = 0;
     477
     478                rc = display_get_info(win->display, &dinfo);
     479                if (rc != EOK) {
     480                        (void) gfx_bitmap_render(win->bitmap, NULL, NULL);
     481                        return;
     482                }
     483
     484                drect = dinfo.rect;
     485
     486                if (placement_flags & WINDOW_PLACEMENT_LEFT)
     487                        dpos.x = drect.p0.x;
     488                else if (placement_flags & WINDOW_PLACEMENT_CENTER_X)
     489                        dpos.x = (drect.p0.x + drect.p0.y - width) / 2;
     490                else
     491                        dpos.x = drect.p1.x - width;
     492
     493                if (placement_flags & WINDOW_PLACEMENT_TOP)
     494                        dpos.y = drect.p0.y;
     495                else if (placement_flags & WINDOW_PLACEMENT_CENTER_Y)
     496                        dpos.y = (drect.p0.y + drect.p1.y - height) / 2;
     497                else
     498                        dpos.y = drect.p1.y - height;
     499
     500                (void) display_window_move(win->dwindow, &dpos);
     501        }
     502
     503        (void) gfx_bitmap_render(win->bitmap, NULL, NULL);
    471504}
    472505
  • uspace/srv/hid/display/dsops.c

    raeb3037 r0680854  
    4747static errno_t disp_window_destroy(void *, sysarg_t);
    4848static errno_t disp_window_move_req(void *, sysarg_t, gfx_coord2_t *);
     49static errno_t disp_window_move(void *, sysarg_t, gfx_coord2_t *);
    4950static errno_t disp_window_resize_req(void *, sysarg_t,
    5051    display_wnd_rsztype_t, gfx_coord2_t *);
     
    5859        .window_destroy = disp_window_destroy,
    5960        .window_move_req = disp_window_move_req,
     61        .window_move = disp_window_move,
    6062        .window_resize_req = disp_window_resize_req,
    6163        .window_resize = disp_window_resize,
     
    124126}
    125127
     128static errno_t disp_window_move(void *arg, sysarg_t wnd_id, gfx_coord2_t *pos)
     129{
     130        ds_client_t *client = (ds_client_t *) arg;
     131        ds_window_t *wnd;
     132
     133        wnd = ds_client_find_window(client, wnd_id);
     134        if (wnd == NULL)
     135                return ENOENT;
     136
     137        log_msg(LVL_NOTE, LVL_DEBUG, "disp_window_move()");
     138        ds_window_move(wnd, pos);
     139        return EOK;
     140}
     141
    126142static errno_t disp_window_resize_req(void *arg, sysarg_t wnd_id,
    127143    display_wnd_rsztype_t rsztype, gfx_coord2_t *pos)
  • uspace/srv/hid/display/window.c

    raeb3037 r0680854  
    346346}
    347347
     348/** Bring window to top.
     349 *
     350 * @param wnd Window
     351 */
     352void ds_window_bring_to_top(ds_window_t *wnd)
     353{
     354        ds_display_t *disp = wnd->display;
     355
     356        ds_display_remove_window(wnd);
     357        ds_display_add_window(disp, wnd);
     358}
     359
     360/** Get generic graphic context from window.
     361 *
     362 * @param wnd Window
     363 * @return Graphic context
     364 */
     365gfx_context_t *ds_window_get_ctx(ds_window_t *wnd)
     366{
     367        return wnd->gc;
     368}
     369
     370/** Paint a window using its backing bitmap.
     371 *
     372 * @param wnd Window to paint
     373 * @param rect Display rectangle to paint to
     374 * @return EOK on success or an error code
     375 */
     376errno_t ds_window_paint(ds_window_t *wnd, gfx_rect_t *rect)
     377{
     378        gfx_rect_t srect;
     379        gfx_rect_t *brect;
     380        gfx_rect_t crect;
     381
     382        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_paint");
     383
     384        if (rect != NULL) {
     385                gfx_rect_rtranslate(&wnd->dpos, rect, &srect);
     386
     387                /* Determine if we have anything to do */
     388                gfx_rect_clip(&srect, &wnd->rect, &crect);
     389                if (gfx_rect_is_empty(&crect))
     390                        return EOK;
     391
     392                brect = &srect;
     393        } else {
     394                brect = NULL;
     395        }
     396
     397        /* This can happen in unit tests */
     398        if (wnd->bitmap == NULL)
     399                return EOK;
     400
     401        return gfx_bitmap_render(wnd->bitmap, brect, &wnd->dpos);
     402}
     403
     404/** Start moving a window by mouse drag.
     405 *
     406 * @param wnd Window
     407 * @param event Button press event
     408 */
     409static void ds_window_start_move(ds_window_t *wnd, pos_event_t *event)
     410{
     411        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_start_move (%d, %d)",
     412            (int) event->hpos, (int) event->vpos);
     413
     414        if (wnd->state != dsw_idle)
     415                return;
     416
     417        wnd->orig_pos.x = event->hpos;
     418        wnd->orig_pos.y = event->vpos;
     419        wnd->state = dsw_moving;
     420}
     421
     422/** Finish moving a window by mouse drag.
     423 *
     424 * @param wnd Window
     425 * @param event Button release event
     426 */
     427static void ds_window_finish_move(ds_window_t *wnd, pos_event_t *event)
     428{
     429        gfx_coord2_t pos;
     430        gfx_coord2_t dmove;
     431        gfx_coord2_t nwpos;
     432
     433        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_finish_move (%d, %d)",
     434            (int) event->hpos, (int) event->vpos);
     435
     436        if (wnd->state != dsw_moving)
     437                return;
     438
     439        pos.x = event->hpos;
     440        pos.y = event->vpos;
     441        gfx_coord2_subtract(&pos, &wnd->orig_pos, &dmove);
     442
     443        gfx_coord2_add(&wnd->dpos, &dmove, &nwpos);
     444        wnd->dpos = nwpos;
     445        wnd->state = dsw_idle;
     446
     447        (void) ds_display_paint(wnd->display, NULL);
     448}
     449
     450/** Update window position when moving by mouse drag.
     451 *
     452 * @param wnd Window
     453 * @param event Position update event
     454 */
     455static void ds_window_update_move(ds_window_t *wnd, pos_event_t *event)
     456{
     457        gfx_coord2_t pos;
     458        gfx_coord2_t dmove;
     459        gfx_coord2_t nwpos;
     460        gfx_rect_t drect;
     461        gfx_color_t *color;
     462        gfx_context_t *gc;
     463        errno_t rc;
     464
     465        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_move (%d, %d)",
     466            (int) event->hpos, (int) event->vpos);
     467
     468        if (wnd->state != dsw_moving)
     469                return;
     470
     471        gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
     472
     473        gc = ds_display_get_gc(wnd->display); // XXX
     474        if (gc != NULL) {
     475                gfx_set_color(gc, wnd->display->bg_color);
     476                gfx_fill_rect(gc, &drect);
     477        }
     478
     479        pos.x = event->hpos;
     480        pos.y = event->vpos;
     481        gfx_coord2_subtract(&pos, &wnd->orig_pos, &dmove);
     482
     483        gfx_coord2_add(&wnd->dpos, &dmove, &nwpos);
     484        gfx_rect_translate(&nwpos, &wnd->rect, &drect);
     485
     486        wnd->orig_pos = pos;
     487        wnd->dpos = nwpos;
     488
     489        rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
     490        if (rc != EOK)
     491                return;
     492
     493        gc = ds_display_get_gc(wnd->display); // XXX
     494        if (gc != NULL) {
     495                gfx_set_color(gc, color);
     496                gfx_fill_rect(gc, &drect);
     497        }
     498
     499        gfx_color_delete(color);
     500}
     501
     502/** Finish resizing a window by mouse drag.
     503 *
     504 * @param wnd Window
     505 * @param event Button release event
     506 */
     507static void ds_window_finish_resize(ds_window_t *wnd, pos_event_t *event)
     508{
     509        gfx_coord2_t pos;
     510        gfx_coord2_t dresize;
     511        gfx_rect_t nrect;
     512
     513        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_finish_resize (%d, %d)",
     514            (int) event->hpos, (int) event->vpos);
     515
     516        if (wnd->state != dsw_resizing)
     517                return;
     518
     519        (void) ds_display_paint(wnd->display, NULL);
     520
     521        pos.x = event->hpos;
     522        pos.y = event->vpos;
     523        gfx_coord2_subtract(&pos, &wnd->orig_pos, &dresize);
     524
     525        /* Compute new rectangle */
     526        ds_window_calc_resize(wnd, &dresize, &nrect);
     527
     528        wnd->state = dsw_idle;
     529        ds_client_post_resize_event(wnd->client, wnd, &nrect);
     530}
     531
     532/** Update window position when resizing by mouse drag.
     533 *
     534 * @param wnd Window
     535 * @param event Position update event
     536 */
     537static void ds_window_update_resize(ds_window_t *wnd, pos_event_t *event)
     538{
     539        gfx_coord2_t pos;
     540        gfx_coord2_t dresize;
     541        gfx_rect_t nrect;
     542        gfx_rect_t drect;
     543        gfx_color_t *color;
     544        gfx_context_t *gc;
     545        errno_t rc;
     546
     547        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_resize (%d, %d)",
     548            (int) event->hpos, (int) event->vpos);
     549
     550        if (wnd->state != dsw_resizing)
     551                return;
     552
     553        gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
     554
     555        gc = ds_display_get_gc(wnd->display); // XXX
     556        if (gc != NULL) {
     557                gfx_set_color(gc, wnd->display->bg_color);
     558                gfx_fill_rect(gc, &drect);
     559        }
     560
     561        pos.x = event->hpos;
     562        pos.y = event->vpos;
     563        gfx_coord2_subtract(&pos, &wnd->orig_pos, &dresize);
     564
     565        ds_window_calc_resize(wnd, &dresize, &nrect);
     566        gfx_rect_translate(&wnd->dpos, &nrect, &drect);
     567
     568        rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
     569        if (rc != EOK)
     570                return;
     571
     572        gc = ds_display_get_gc(wnd->display); // XXX
     573        if (gc != NULL) {
     574                gfx_set_color(gc, color);
     575                gfx_fill_rect(gc, &drect);
     576        }
     577
     578        gfx_color_delete(color);
     579}
     580
     581/** Post keyboard event to window.
     582 *
     583 * @param wnd Window
     584 * @param event Event
     585 *
     586 * @return EOK on success or an error code
     587 */
     588errno_t ds_window_post_kbd_event(ds_window_t *wnd, kbd_event_t *event)
     589{
     590        bool alt_or_shift;
     591
     592        alt_or_shift = event->mods & (KM_SHIFT | KM_ALT);
     593
     594        if (event->type == KEY_PRESS && alt_or_shift && event->key == KC_F4) {
     595                /* On Alt-F4 or Shift-F4 send close event to the window */
     596                ds_client_post_close_event(wnd->client, wnd);
     597                return EOK;
     598        }
     599
     600        return ds_client_post_kbd_event(wnd->client, wnd, event);
     601}
     602
     603/** Post position event to window.
     604 *
     605 * @param wnd Window
     606 * @param event Position event
     607 */
     608errno_t ds_window_post_pos_event(ds_window_t *wnd, pos_event_t *event)
     609{
     610        pos_event_t tevent;
     611        gfx_coord2_t pos;
     612        gfx_rect_t drect;
     613        bool inside;
     614
     615        log_msg(LOG_DEFAULT, LVL_DEBUG,
     616            "ds_window_post_pos_event type=%d pos=%d,%d\n", event->type,
     617            (int) event->hpos, (int) event->vpos);
     618
     619        pos.x = event->hpos;
     620        pos.y = event->vpos;
     621        gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
     622        inside = gfx_pix_inside_rect(&pos, &drect);
     623
     624        if (event->type == POS_PRESS && event->btn_num == 2 && inside)
     625                ds_window_start_move(wnd, event);
     626
     627        if (event->type == POS_RELEASE) {
     628                ds_window_finish_move(wnd, event);
     629                ds_window_finish_resize(wnd, event);
     630        }
     631
     632        if (event->type == POS_UPDATE) {
     633                ds_window_update_move(wnd, event);
     634                ds_window_update_resize(wnd, event);
     635        }
     636
     637        /* Transform event coordinates to window-local */
     638        tevent = *event;
     639        tevent.hpos -= wnd->dpos.x;
     640        tevent.vpos -= wnd->dpos.y;
     641
     642        return ds_client_post_pos_event(wnd->client, wnd, &tevent);
     643}
     644
     645/** Post focus event to window.
     646 *
     647 * @param wnd Window
     648 */
     649errno_t ds_window_post_focus_event(ds_window_t *wnd)
     650{
     651        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_focus_event\n");
     652
     653        return ds_client_post_focus_event(wnd->client, wnd);
     654}
     655
     656/** Post unfocus event to window.
     657 *
     658 * @param wnd Window
     659 */
     660errno_t ds_window_post_unfocus_event(ds_window_t *wnd)
     661{
     662        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_unfocus_event\n");
     663
     664        return ds_client_post_unfocus_event(wnd->client, wnd);
     665}
     666
     667/** Start moving a window, detected by client.
     668 *
     669 * @param wnd Window
     670 * @param pos Position where the pointer was when the move started
     671 *            relative to the window
     672 * @param event Button press event
     673 */
     674void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *pos)
     675{
     676        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_move_req (%d, %d)",
     677            (int) pos->x, (int) pos->y);
     678
     679        if (wnd->state != dsw_idle)
     680                return;
     681
     682        gfx_coord2_add(&wnd->dpos, pos, &wnd->orig_pos);
     683        wnd->state = dsw_moving;
     684}
     685
     686/** Move window.
     687 *
     688 * @param wnd Window
     689 */
     690void ds_window_move(ds_window_t *wnd, gfx_coord2_t *dpos)
     691{
     692        wnd->dpos = *dpos;
     693        (void) ds_display_paint(wnd->display, NULL);
     694}
     695
     696/** Start resizing a window, detected by client.
     697 *
     698 * @param wnd Window
     699 * @param rsztype Resize type (which part of window is being dragged)
     700 * @param pos Position where the pointer was when the resize started
     701 *            relative to the window
     702 * @param event Button press event
     703 */
     704void ds_window_resize_req(ds_window_t *wnd, display_wnd_rsztype_t rsztype,
     705    gfx_coord2_t *pos)
     706{
     707        log_msg(LOG_DEFAULT, LVL_NOTE, "ds_window_resize_req (%d, %d, %d)",
     708            (int) rsztype, (int) pos->x, (int) pos->y);
     709
     710        if (wnd->state != dsw_idle)
     711                return;
     712
     713        gfx_coord2_add(&wnd->dpos, pos, &wnd->orig_pos);
     714        wnd->state = dsw_resizing;
     715        wnd->rsztype = rsztype;
     716}
     717
    348718/** Resize window.
    349719 *
     
    400770}
    401771
    402 /** Bring window to top.
    403  *
    404  * @param wnd Window
    405  */
    406 void ds_window_bring_to_top(ds_window_t *wnd)
    407 {
    408         ds_display_t *disp = wnd->display;
    409 
    410         ds_display_remove_window(wnd);
    411         ds_display_add_window(disp, wnd);
    412 }
    413 
    414 /** Get generic graphic context from window.
    415  *
    416  * @param wnd Window
    417  * @return Graphic context
    418  */
    419 gfx_context_t *ds_window_get_ctx(ds_window_t *wnd)
    420 {
    421         return wnd->gc;
    422 }
    423 
    424 /** Paint a window using its backing bitmap.
    425  *
    426  * @param wnd Window to paint
    427  * @param rect Display rectangle to paint to
    428  * @return EOK on success or an error code
    429  */
    430 errno_t ds_window_paint(ds_window_t *wnd, gfx_rect_t *rect)
    431 {
    432         gfx_rect_t srect;
    433         gfx_rect_t *brect;
    434         gfx_rect_t crect;
    435 
    436         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_paint");
    437 
    438         if (rect != NULL) {
    439                 gfx_rect_rtranslate(&wnd->dpos, rect, &srect);
    440 
    441                 /* Determine if we have anything to do */
    442                 gfx_rect_clip(&srect, &wnd->rect, &crect);
    443                 if (gfx_rect_is_empty(&crect))
    444                         return EOK;
    445 
    446                 brect = &srect;
    447         } else {
    448                 brect = NULL;
    449         }
    450 
    451         /* This can happen in unit tests */
    452         if (wnd->bitmap == NULL)
    453                 return EOK;
    454 
    455         return gfx_bitmap_render(wnd->bitmap, brect, &wnd->dpos);
    456 }
    457 
    458 /** Start moving a window by mouse drag.
    459  *
    460  * @param wnd Window
    461  * @param event Button press event
    462  */
    463 static void ds_window_start_move(ds_window_t *wnd, pos_event_t *event)
    464 {
    465         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_start_move (%d, %d)",
    466             (int) event->hpos, (int) event->vpos);
    467 
    468         if (wnd->state != dsw_idle)
    469                 return;
    470 
    471         wnd->orig_pos.x = event->hpos;
    472         wnd->orig_pos.y = event->vpos;
    473         wnd->state = dsw_moving;
    474 }
    475 
    476 /** Finish moving a window by mouse drag.
    477  *
    478  * @param wnd Window
    479  * @param event Button release event
    480  */
    481 static void ds_window_finish_move(ds_window_t *wnd, pos_event_t *event)
    482 {
    483         gfx_coord2_t pos;
    484         gfx_coord2_t dmove;
    485         gfx_coord2_t nwpos;
    486 
    487         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_finish_move (%d, %d)",
    488             (int) event->hpos, (int) event->vpos);
    489 
    490         if (wnd->state != dsw_moving)
    491                 return;
    492 
    493         pos.x = event->hpos;
    494         pos.y = event->vpos;
    495         gfx_coord2_subtract(&pos, &wnd->orig_pos, &dmove);
    496 
    497         gfx_coord2_add(&wnd->dpos, &dmove, &nwpos);
    498         wnd->dpos = nwpos;
    499         wnd->state = dsw_idle;
    500 
    501         (void) ds_display_paint(wnd->display, NULL);
    502 }
    503 
    504 /** Update window position when moving by mouse drag.
    505  *
    506  * @param wnd Window
    507  * @param event Position update event
    508  */
    509 static void ds_window_update_move(ds_window_t *wnd, pos_event_t *event)
    510 {
    511         gfx_coord2_t pos;
    512         gfx_coord2_t dmove;
    513         gfx_coord2_t nwpos;
    514         gfx_rect_t drect;
    515         gfx_color_t *color;
    516         gfx_context_t *gc;
    517         errno_t rc;
    518 
    519         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_move (%d, %d)",
    520             (int) event->hpos, (int) event->vpos);
    521 
    522         if (wnd->state != dsw_moving)
    523                 return;
    524 
    525         gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
    526 
    527         gc = ds_display_get_gc(wnd->display); // XXX
    528         if (gc != NULL) {
    529                 gfx_set_color(gc, wnd->display->bg_color);
    530                 gfx_fill_rect(gc, &drect);
    531         }
    532 
    533         pos.x = event->hpos;
    534         pos.y = event->vpos;
    535         gfx_coord2_subtract(&pos, &wnd->orig_pos, &dmove);
    536 
    537         gfx_coord2_add(&wnd->dpos, &dmove, &nwpos);
    538         gfx_rect_translate(&nwpos, &wnd->rect, &drect);
    539 
    540         wnd->orig_pos = pos;
    541         wnd->dpos = nwpos;
    542 
    543         rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
    544         if (rc != EOK)
    545                 return;
    546 
    547         gc = ds_display_get_gc(wnd->display); // XXX
    548         if (gc != NULL) {
    549                 gfx_set_color(gc, color);
    550                 gfx_fill_rect(gc, &drect);
    551         }
    552 
    553         gfx_color_delete(color);
    554 }
    555 
    556 /** Finish resizing a window by mouse drag.
    557  *
    558  * @param wnd Window
    559  * @param event Button release event
    560  */
    561 static void ds_window_finish_resize(ds_window_t *wnd, pos_event_t *event)
    562 {
    563         gfx_coord2_t pos;
    564         gfx_coord2_t dresize;
    565         gfx_rect_t nrect;
    566 
    567         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_finish_resize (%d, %d)",
    568             (int) event->hpos, (int) event->vpos);
    569 
    570         if (wnd->state != dsw_resizing)
    571                 return;
    572 
    573         (void) ds_display_paint(wnd->display, NULL);
    574 
    575         pos.x = event->hpos;
    576         pos.y = event->vpos;
    577         gfx_coord2_subtract(&pos, &wnd->orig_pos, &dresize);
    578 
    579         /* Compute new rectangle */
    580         ds_window_calc_resize(wnd, &dresize, &nrect);
    581 
    582         wnd->state = dsw_idle;
    583         ds_client_post_resize_event(wnd->client, wnd, &nrect);
    584 }
    585 
    586 /** Update window position when resizing by mouse drag.
    587  *
    588  * @param wnd Window
    589  * @param event Position update event
    590  */
    591 static void ds_window_update_resize(ds_window_t *wnd, pos_event_t *event)
    592 {
    593         gfx_coord2_t pos;
    594         gfx_coord2_t dresize;
    595         gfx_rect_t nrect;
    596         gfx_rect_t drect;
    597         gfx_color_t *color;
    598         gfx_context_t *gc;
    599         errno_t rc;
    600 
    601         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_resize (%d, %d)",
    602             (int) event->hpos, (int) event->vpos);
    603 
    604         if (wnd->state != dsw_resizing)
    605                 return;
    606 
    607         gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
    608 
    609         gc = ds_display_get_gc(wnd->display); // XXX
    610         if (gc != NULL) {
    611                 gfx_set_color(gc, wnd->display->bg_color);
    612                 gfx_fill_rect(gc, &drect);
    613         }
    614 
    615         pos.x = event->hpos;
    616         pos.y = event->vpos;
    617         gfx_coord2_subtract(&pos, &wnd->orig_pos, &dresize);
    618 
    619         ds_window_calc_resize(wnd, &dresize, &nrect);
    620         gfx_rect_translate(&wnd->dpos, &nrect, &drect);
    621 
    622         rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
    623         if (rc != EOK)
    624                 return;
    625 
    626         gc = ds_display_get_gc(wnd->display); // XXX
    627         if (gc != NULL) {
    628                 gfx_set_color(gc, color);
    629                 gfx_fill_rect(gc, &drect);
    630         }
    631 
    632         gfx_color_delete(color);
    633 }
    634 
    635 /** Post keyboard event to window.
    636  *
    637  * @param wnd Window
    638  * @param event Event
    639  *
    640  * @return EOK on success or an error code
    641  */
    642 errno_t ds_window_post_kbd_event(ds_window_t *wnd, kbd_event_t *event)
    643 {
    644         bool alt_or_shift;
    645 
    646         alt_or_shift = event->mods & (KM_SHIFT | KM_ALT);
    647 
    648         if (event->type == KEY_PRESS && alt_or_shift && event->key == KC_F4) {
    649                 /* On Alt-F4 or Shift-F4 send close event to the window */
    650                 ds_client_post_close_event(wnd->client, wnd);
    651                 return EOK;
    652         }
    653 
    654         return ds_client_post_kbd_event(wnd->client, wnd, event);
    655 }
    656 
    657 /** Post position event to window.
    658  *
    659  * @param wnd Window
    660  * @param event Position event
    661  */
    662 errno_t ds_window_post_pos_event(ds_window_t *wnd, pos_event_t *event)
    663 {
    664         pos_event_t tevent;
    665         gfx_coord2_t pos;
    666         gfx_rect_t drect;
    667         bool inside;
    668 
    669         log_msg(LOG_DEFAULT, LVL_DEBUG,
    670             "ds_window_post_pos_event type=%d pos=%d,%d\n", event->type,
    671             (int) event->hpos, (int) event->vpos);
    672 
    673         pos.x = event->hpos;
    674         pos.y = event->vpos;
    675         gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
    676         inside = gfx_pix_inside_rect(&pos, &drect);
    677 
    678         if (event->type == POS_PRESS && event->btn_num == 2 && inside)
    679                 ds_window_start_move(wnd, event);
    680 
    681         if (event->type == POS_RELEASE) {
    682                 ds_window_finish_move(wnd, event);
    683                 ds_window_finish_resize(wnd, event);
    684         }
    685 
    686         if (event->type == POS_UPDATE) {
    687                 ds_window_update_move(wnd, event);
    688                 ds_window_update_resize(wnd, event);
    689         }
    690 
    691         /* Transform event coordinates to window-local */
    692         tevent = *event;
    693         tevent.hpos -= wnd->dpos.x;
    694         tevent.vpos -= wnd->dpos.y;
    695 
    696         return ds_client_post_pos_event(wnd->client, wnd, &tevent);
    697 }
    698 
    699 /** Post focus event to window.
    700  *
    701  * @param wnd Window
    702  */
    703 errno_t ds_window_post_focus_event(ds_window_t *wnd)
    704 {
    705         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_focus_event\n");
    706 
    707         return ds_client_post_focus_event(wnd->client, wnd);
    708 }
    709 
    710 /** Post unfocus event to window.
    711  *
    712  * @param wnd Window
    713  */
    714 errno_t ds_window_post_unfocus_event(ds_window_t *wnd)
    715 {
    716         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_unfocus_event\n");
    717 
    718         return ds_client_post_unfocus_event(wnd->client, wnd);
    719 }
    720 
    721 /** Start moving a window, detected by client.
    722  *
    723  * @param wnd Window
    724  * @param pos Position where the pointer was when the move started
    725  *            relative to the window
    726  * @param event Button press event
    727  */
    728 void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *pos)
    729 {
    730         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_move_req (%d, %d)",
    731             (int) pos->x, (int) pos->y);
    732 
    733         if (wnd->state != dsw_idle)
    734                 return;
    735 
    736         gfx_coord2_add(&wnd->dpos, pos, &wnd->orig_pos);
    737         wnd->state = dsw_moving;
    738 }
    739 
    740 /** Start resizing a window, detected by client.
    741  *
    742  * @param wnd Window
    743  * @param rsztype Resize type (which part of window is being dragged)
    744  * @param pos Position where the pointer was when the resize started
    745  *            relative to the window
    746  * @param event Button press event
    747  */
    748 void ds_window_resize_req(ds_window_t *wnd, display_wnd_rsztype_t rsztype,
    749     gfx_coord2_t *pos)
    750 {
    751         log_msg(LOG_DEFAULT, LVL_NOTE, "ds_window_resize_req (%d, %d, %d)",
    752             (int) rsztype, (int) pos->x, (int) pos->y);
    753 
    754         if (wnd->state != dsw_idle)
    755                 return;
    756 
    757         gfx_coord2_add(&wnd->dpos, pos, &wnd->orig_pos);
    758         wnd->state = dsw_resizing;
    759         wnd->rsztype = rsztype;
    760 }
    761 
    762772/** Compute new window rectangle after resize operation.
    763773 *
  • uspace/srv/hid/display/window.h

    raeb3037 r0680854  
    5252    ds_window_t **);
    5353extern void ds_window_destroy(ds_window_t *);
    54 extern errno_t ds_window_resize(ds_window_t *, gfx_coord2_t *, gfx_rect_t *);
    5554extern void ds_window_bring_to_top(ds_window_t *);
    5655extern gfx_context_t *ds_window_get_ctx(ds_window_t *);
     
    6059extern errno_t ds_window_post_focus_event(ds_window_t *);
    6160extern errno_t ds_window_post_unfocus_event(ds_window_t *);
    62 extern void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *);
    63 extern void ds_window_resize_req(ds_window_t *wnd, display_wnd_rsztype_t,
     61extern void ds_window_move_req(ds_window_t *, gfx_coord2_t *);
     62extern void ds_window_move(ds_window_t *, gfx_coord2_t *);
     63extern void ds_window_resize_req(ds_window_t *, display_wnd_rsztype_t,
    6464    gfx_coord2_t *);
    65 extern void ds_window_calc_resize(ds_window_t *wnd, gfx_coord2_t *,
     65extern errno_t ds_window_resize(ds_window_t *, gfx_coord2_t *, gfx_rect_t *);
     66extern void ds_window_calc_resize(ds_window_t *, gfx_coord2_t *,
    6667    gfx_rect_t *);
    6768
Note: See TracChangeset for help on using the changeset viewer.