Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset a40ae0d in mainline


Ignore:
Timestamp:
2020-01-09T16:44:57Z (8 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
946a666
Parents:
8e9781f
git-author:
Jiri Svoboda <jiri@…> (2020-01-09 18:44:03)
git-committer:
Jiri Svoboda <jiri@…> (2020-01-09 16:44:57)
Message:

Moving windows by mouse drag

Location:
uspace
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/gfx/include/types/gfx/ops/context.h

    r8e9781f ra40ae0d  
    4747/** Graphics context ops */
    4848typedef struct {
    49         /** Set drawing collor */
     49        /** Set drawing color */
    5050        errno_t (*set_color)(void *, gfx_color_t *);
    5151        /** Fill rectangle using the current drawing color */
  • uspace/srv/hid/display/seat.c

    r8e9781f ra40ae0d  
    215215/** Post pointing device event to the seat
    216216 *
     217 * Update pointer position and generate position event.
     218 *
    217219 * @param seat Seat
    218220 * @param event Event
     
    223225errno_t ds_seat_post_ptd_event(ds_seat_t *seat, ptd_event_t *event)
    224226{
     227        gfx_coord2_t npos;
    225228        ds_window_t *wnd;
    226         gfx_coord2_t npos;
     229        pos_event_t pevent;
     230        errno_t rc;
    227231
    228232        printf("ds_seat_post_ptd_event\n");
     233        wnd = ds_display_window_by_pos(seat->display, &seat->pntpos);
     234
    229235        /* Focus window on button press */
    230         if (event->type == PTD_PRESS) {
    231                 printf("PTD_PRESS\n");
    232                 wnd = ds_display_window_by_pos(seat->display, &seat->pntpos);
     236        if (event->type == PTD_PRESS && event->btn_num == 1) {
     237                printf("PTD_PRESS (button = %d)\n", event->btn_num);
    233238                if (wnd != NULL) {
    234239                        printf("set focus\n");
    235240                        ds_seat_set_focus(seat, wnd);
    236                         return EOK;
    237241                }
     242        }
     243
     244        if (event->type == PTD_PRESS || event->type == PTD_RELEASE) {
     245                pevent.pos_id = 0;
     246                pevent.type = (event->type == PTD_PRESS) ?
     247                    POS_PRESS : POS_RELEASE;
     248                pevent.btn_num = event->btn_num;
     249                pevent.hpos = seat->pntpos.x;
     250                pevent.vpos = seat->pntpos.y;
     251
     252                rc = ds_seat_post_pos_event(seat, &pevent);
     253                if (rc != EOK)
     254                        return rc;
    238255        }
    239256
    240257        if (event->type == PTD_MOVE) {
    241258                printf("PTD_MOVE\n");
     259
    242260                gfx_coord2_add(&seat->pntpos, &event->dmove, &npos);
    243261                if (npos.x < 0)
     
    253271                (void) ds_seat_draw_pointer(seat, false);
    254272                seat->pntpos = npos;
     273
     274                pevent.pos_id = 0;
     275                pevent.type = POS_UPDATE;
     276                pevent.btn_num = 0;
     277                pevent.hpos = seat->pntpos.x;
     278                pevent.vpos = seat->pntpos.y;
     279
     280                rc = ds_seat_post_pos_event(seat, &pevent);
     281                if (rc != EOK)
     282                        return rc;
     283
    255284                printf("draw pointer\n");
    256285                (void) ds_seat_draw_pointer(seat, true);
     
    260289}
    261290
     291/** Post position event to seat.
     292 *
     293 * Deliver event to relevant windows.
     294 *
     295 * @param seat Seat
     296 * @param event Position event
     297 */
     298errno_t ds_seat_post_pos_event(ds_seat_t *seat, pos_event_t *event)
     299{
     300        ds_window_t *wnd;
     301        errno_t rc;
     302
     303        printf("ds_seat_post_pos_event\n");
     304
     305        wnd = ds_display_window_by_pos(seat->display, &seat->pntpos);
     306        if (wnd != NULL) {
     307                printf("send event to window at pointer position\n");
     308                rc = ds_window_post_pos_event(wnd, event);
     309                if (rc != EOK)
     310                        return rc;
     311        }
     312
     313        if (seat->focus != wnd) {
     314                printf("send event to focused window\n");
     315
     316                rc = ds_window_post_pos_event(seat->focus, event);
     317                if (rc != EOK)
     318                        return rc;
     319        }
     320
     321        return EOK;
     322}
     323
    262324/** @}
    263325 */
  • uspace/srv/hid/display/seat.h

    r8e9781f ra40ae0d  
    3939#include <errno.h>
    4040#include <io/kbd_event.h>
     41#include <io/pos_event.h>
    4142#include "types/display/display.h"
    4243#include "types/display/seat.h"
     
    5051extern errno_t ds_seat_post_kbd_event(ds_seat_t *, kbd_event_t *);
    5152extern errno_t ds_seat_post_ptd_event(ds_seat_t *, ptd_event_t *);
     53extern errno_t ds_seat_post_pos_event(ds_seat_t *, pos_event_t *);
    5254
    5355#endif
  • uspace/srv/hid/display/test/client.c

    r8e9781f ra40ae0d  
    164164
    165165/** Test ds_client_get_event(), ds_client_post_kbd_event(). */
    166 PCUT_TEST(display_get_post_kbd_event)
     166PCUT_TEST(client_get_post_kbd_event)
    167167{
    168168        ds_display_t *disp;
  • uspace/srv/hid/display/test/display.c

    r8e9781f ra40ae0d  
    388388
    389389        event.type = PTD_MOVE;
    390         event.dmove.x = -400;
    391         event.dmove.y = -400;
     390        event.dmove.x = -400 + 10;
     391        event.dmove.y = -400 + 10;
    392392        rc = ds_display_post_ptd_event(disp, &event);
    393393        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
  • uspace/srv/hid/display/test/seat.c

    r8e9781f ra40ae0d  
    134134}
    135135
     136/** Test ds_seat_post_kbd_event() with Alt-Tab switches focus */
     137PCUT_TEST(post_kbd_event_alt_tab)
     138{
     139        ds_display_t *disp;
     140        ds_client_t *client;
     141        ds_seat_t *seat;
     142        ds_window_t *w0;
     143        ds_window_t *w1;
     144        display_wnd_params_t params;
     145        kbd_event_t event;
     146        errno_t rc;
     147
     148        rc = ds_display_create(NULL, &disp);
     149        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     150
     151        rc = ds_client_create(disp, &test_ds_client_cb, NULL, &client);
     152        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     153
     154        rc = ds_seat_create(disp, &seat);
     155        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     156
     157        display_wnd_params_init(&params);
     158        params.rect.p0.x = params.rect.p0.y = 0;
     159        params.rect.p1.x = params.rect.p1.y = 1;
     160
     161        rc = ds_window_create(client, &params, &w1);
     162        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     163
     164        rc = ds_window_create(client, &params, &w0);
     165        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     166
     167        ds_seat_set_focus(seat, w1);
     168        PCUT_ASSERT_EQUALS(w1, seat->focus);
     169
     170        event.type = KEY_PRESS;
     171        event.mods = KM_ALT;
     172        event.key = KC_TAB;
     173        rc = ds_seat_post_kbd_event(seat, &event);
     174        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     175        PCUT_ASSERT_EQUALS(w0, seat->focus);
     176
     177        ds_window_destroy(w0);
     178        ds_window_destroy(w1);
     179        ds_seat_destroy(seat);
     180        ds_client_destroy(client);
     181        ds_display_destroy(disp);
     182}
     183
     184/** Test ds_seat_post_kbd_event() with regular key press delivers to client queue */
     185PCUT_TEST(post_kbd_event_regular)
     186{
     187        ds_display_t *disp;
     188        ds_client_t *client;
     189        ds_seat_t *seat;
     190        ds_window_t *wnd;
     191        display_wnd_params_t params;
     192        kbd_event_t event;
     193        ds_window_t *rwindow;
     194        display_wnd_ev_t revent;
     195        bool called_cb = NULL;
     196        errno_t rc;
     197
     198        rc = ds_display_create(NULL, &disp);
     199        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     200
     201        rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
     202        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     203
     204        rc = ds_seat_create(disp, &seat);
     205        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     206
     207        display_wnd_params_init(&params);
     208        params.rect.p0.x = params.rect.p0.y = 0;
     209        params.rect.p1.x = params.rect.p1.y = 1;
     210
     211        rc = ds_window_create(client, &params, &wnd);
     212        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     213
     214        ds_seat_set_focus(seat, wnd);
     215        PCUT_ASSERT_EQUALS(wnd, seat->focus);
     216
     217        event.type = KEY_PRESS;
     218        event.key = KC_ENTER;
     219        event.mods = 0;
     220        event.c = L'\0';
     221
     222        PCUT_ASSERT_FALSE(called_cb);
     223
     224        rc = ds_client_get_event(client, &rwindow, &revent);
     225        PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
     226
     227        rc = ds_seat_post_kbd_event(seat, &event);
     228        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     229        PCUT_ASSERT_TRUE(called_cb);
     230
     231        rc = ds_client_get_event(client, &rwindow, &revent);
     232        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     233        PCUT_ASSERT_EQUALS(wnd, rwindow);
     234        PCUT_ASSERT_EQUALS(event.type, revent.kbd_event.type);
     235        PCUT_ASSERT_EQUALS(event.key, revent.kbd_event.key);
     236        PCUT_ASSERT_EQUALS(event.mods, revent.kbd_event.mods);
     237        PCUT_ASSERT_EQUALS(event.c, revent.kbd_event.c);
     238
     239        rc = ds_client_get_event(client, &rwindow, &revent);
     240        PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
     241
     242        ds_window_destroy(wnd);
     243        ds_client_destroy(client);
     244        ds_display_destroy(disp);
     245}
     246
     247/** Test ds_seat_post_ptd_event() with click on window switches focus
     248 */
     249PCUT_TEST(post_ptd_event_wnd_switch)
     250{
     251        ds_display_t *disp;
     252        ds_seat_t *seat;
     253        ds_client_t *client;
     254        ds_window_t *w0, *w1;
     255        display_wnd_params_t params;
     256        ptd_event_t event;
     257        bool called_cb = false;
     258        errno_t rc;
     259
     260        rc = ds_display_create(NULL, &disp);
     261        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     262
     263        rc = ds_seat_create(disp, &seat);
     264        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     265
     266        rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
     267        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     268
     269        display_wnd_params_init(&params);
     270        params.rect.p0.x = params.rect.p0.y = 0;
     271        params.rect.p1.x = params.rect.p1.y = 1;
     272
     273        rc = ds_window_create(client, &params, &w0);
     274        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     275
     276        rc = ds_window_create(client, &params, &w1);
     277        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     278
     279        w0->dpos.x = 10;
     280        w0->dpos.y = 10;
     281
     282        w1->dpos.x = 400;
     283        w1->dpos.y = 400;
     284
     285        PCUT_ASSERT_FALSE(called_cb);
     286
     287        ds_seat_set_focus(seat, w0);
     288
     289        event.type = PTD_MOVE;
     290        event.dmove.x = 400;
     291        event.dmove.y = 400;
     292        rc = ds_seat_post_ptd_event(seat, &event);
     293        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     294        PCUT_ASSERT_FALSE(called_cb);
     295
     296        event.type = PTD_PRESS;
     297        event.btn_num = 1;
     298        rc = ds_seat_post_ptd_event(seat, &event);
     299        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     300        PCUT_ASSERT_FALSE(called_cb);
     301
     302        PCUT_ASSERT_EQUALS(w1, seat->focus);
     303
     304        event.type = PTD_MOVE;
     305        event.dmove.x = -400 + 10;
     306        event.dmove.y = -400 + 10;
     307        rc = ds_seat_post_ptd_event(seat, &event);
     308        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     309        PCUT_ASSERT_FALSE(called_cb);
     310
     311        event.type = PTD_PRESS;
     312        event.btn_num = 1;
     313        rc = ds_seat_post_ptd_event(seat, &event);
     314        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     315        PCUT_ASSERT_FALSE(called_cb);
     316
     317        PCUT_ASSERT_EQUALS(w0, seat->focus);
     318
     319        ds_window_destroy(w0);
     320        ds_window_destroy(w1);
     321        ds_client_destroy(client);
     322        ds_seat_destroy(seat);
     323        ds_display_destroy(disp);
     324}
     325
     326/** Test ds_seat_post_pos_event() */
     327PCUT_TEST(post_pos_event)
     328{
     329        // XXX
     330}
     331
    136332PCUT_EXPORT(seat);
  • uspace/srv/hid/display/test/window.c

    r8e9781f ra40ae0d  
    2929#include <disp_srv.h>
    3030#include <errno.h>
     31#include <gfx/context.h>
    3132#include <pcut/pcut.h>
    3233#include <stdio.h>
     
    4041
    4142PCUT_TEST_SUITE(window);
     43
     44static errno_t dummy_set_color(void *, gfx_color_t *);
     45static errno_t dummy_fill_rect(void *, gfx_rect_t *);
     46
     47static gfx_context_ops_t dummy_ops = {
     48        .set_color = dummy_set_color,
     49        .fill_rect = dummy_fill_rect
     50};
    4251
    4352/** Test ds_window_get_ctx(). */
     
    7281}
    7382
     83/** Test ds_window_post_pos_event() */
     84PCUT_TEST(window_post_pos_event)
     85{
     86        gfx_context_t *gc;
     87        ds_display_t *disp;
     88        ds_client_t *client;
     89        ds_window_t *wnd;
     90        display_wnd_params_t params;
     91        pos_event_t event;
     92        errno_t rc;
     93
     94        rc = gfx_context_new(&dummy_ops, NULL, &gc);
     95        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     96
     97        rc = ds_display_create(gc, &disp);
     98        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     99
     100        rc = ds_client_create(disp, NULL, NULL, &client);
     101        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     102
     103        display_wnd_params_init(&params);
     104        params.rect.p0.x = params.rect.p0.y = 0;
     105        params.rect.p1.x = params.rect.p1.y = 1;
     106
     107        rc = ds_window_create(client, &params, &wnd);
     108        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     109
     110        PCUT_ASSERT_INT_EQUALS(dsw_idle, wnd->state);
     111
     112        event.type = POS_PRESS;
     113        event.hpos = 10;
     114        event.vpos = 10;
     115        rc = ds_window_post_pos_event(wnd, &event);
     116        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     117
     118        PCUT_ASSERT_INT_EQUALS(dsw_moving, wnd->state);
     119
     120        event.type = POS_UPDATE;
     121        event.hpos = 11;
     122        event.vpos = 12;
     123        rc = ds_window_post_pos_event(wnd, &event);
     124        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     125
     126        PCUT_ASSERT_INT_EQUALS(dsw_moving, wnd->state);
     127        PCUT_ASSERT_INT_EQUALS(wnd->dpos.x, 0);
     128        PCUT_ASSERT_INT_EQUALS(wnd->dpos.y, 0);
     129
     130        event.type = POS_RELEASE;
     131        event.hpos = 13;
     132        event.vpos = 14;
     133
     134        rc = ds_window_post_pos_event(wnd, &event);
     135        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     136
     137        PCUT_ASSERT_INT_EQUALS(dsw_idle, wnd->state);
     138        PCUT_ASSERT_INT_EQUALS(wnd->dpos.x, 3);
     139        PCUT_ASSERT_INT_EQUALS(wnd->dpos.y, 4);
     140
     141        ds_window_destroy(wnd);
     142        ds_client_destroy(client);
     143        ds_display_destroy(disp);
     144}
     145
     146static errno_t dummy_set_color(void *arg, gfx_color_t *color)
     147{
     148        return EOK;
     149}
     150
     151static errno_t dummy_fill_rect(void *arg, gfx_rect_t *rect)
     152{
     153        return EOK;
     154}
     155
    74156PCUT_EXPORT(window);
  • uspace/srv/hid/display/types/display/window.h

    r8e9781f ra40ae0d  
    4444typedef sysarg_t ds_wnd_id_t;
    4545
     46/** Window state */
     47typedef enum {
     48        /** Idle */
     49        dsw_idle,
     50        /** Moving by mouse drag */
     51        dsw_moving
     52} ds_window_state_t;
     53
    4654/** Display server window */
    4755typedef struct ds_window {
     
    6270        /** Graphic context */
    6371        gfx_context_t *gc;
     72
     73        /** State */
     74        ds_window_state_t state;
     75        /** Original position before started to move the window */
     76        gfx_coord2_t orig_pos;
    6477} ds_window_t;
    6578
  • uspace/srv/hid/display/window.c

    r8e9781f ra40ae0d  
    270270}
    271271
     272/** Start moving a window by mouse drag.
     273 *
     274 * @param wnd Window
     275 * @param event Button press event
     276 */
     277static void ds_window_start_move(ds_window_t *wnd, pos_event_t *event)
     278{
     279        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_start_move (%d, %d)",
     280            (int) event->hpos, (int) event->vpos);
     281
     282        assert(wnd->state == dsw_idle);
     283
     284        wnd->orig_pos.x = event->hpos;
     285        wnd->orig_pos.y = event->vpos;
     286        wnd->state = dsw_moving;
     287}
     288
     289/** Finish moving a window by mouse drag.
     290 *
     291 * @param wnd Window
     292 * @param event Button release event
     293 */
     294static void ds_window_finish_move(ds_window_t *wnd, pos_event_t *event)
     295{
     296        gfx_coord2_t pos;
     297        gfx_coord2_t dmove;
     298        gfx_coord2_t nwpos;
     299
     300        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_finish_move (%d, %d)",
     301            (int) event->hpos, (int) event->vpos);
     302
     303        assert(wnd->state == dsw_moving);
     304        pos.x = event->hpos;
     305        pos.y = event->vpos;
     306        gfx_coord2_subtract(&pos, &wnd->orig_pos, &dmove);
     307
     308        gfx_coord2_add(&wnd->dpos, &dmove, &nwpos);
     309        wnd->dpos = nwpos;
     310        wnd->state = dsw_idle;
     311}
     312
     313/** Update window position when moving by mouse drag.
     314 *
     315 * @param wnd Window
     316 * @param event Position update event
     317 */
     318static void ds_window_update_move(ds_window_t *wnd, pos_event_t *event)
     319{
     320        gfx_coord2_t pos;
     321        gfx_coord2_t dmove;
     322        gfx_coord2_t nwpos;
     323        gfx_rect_t drect;
     324        gfx_color_t *color;
     325        gfx_context_t *gc;
     326        errno_t rc;
     327
     328        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_move (%d, %d)",
     329            (int) event->hpos, (int) event->vpos);
     330
     331        assert(wnd->state == dsw_moving);
     332        pos.x = event->hpos;
     333        pos.y = event->vpos;
     334        gfx_coord2_subtract(&pos, &wnd->orig_pos, &dmove);
     335
     336        gfx_coord2_add(&wnd->dpos, &dmove, &nwpos);
     337        gfx_rect_translate(&nwpos, &wnd->rect, &drect);
     338
     339        rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
     340        if (rc != EOK)
     341                return;
     342
     343        gc = ds_display_get_gc(wnd->display); // XXX
     344        if (gc != NULL) {
     345                gfx_set_color(ds_display_get_gc(wnd->display), color);
     346                gfx_fill_rect(ds_display_get_gc(wnd->display), &drect);
     347        }
     348
     349        gfx_color_delete(color);
     350}
     351
     352/** Post position event to window.
     353 *
     354 * @param wnd Window
     355 * @param event Position event
     356 */
     357errno_t ds_window_post_pos_event(ds_window_t *wnd, pos_event_t *event)
     358{
     359        log_msg(LOG_DEFAULT, LVL_DEBUG,
     360            "ds_window_post_pos_event type=%d pos=%d,%d\n", event->type,
     361            (int) event->hpos, (int) event->vpos);
     362
     363        if (event->type == POS_PRESS) {
     364                if (wnd->state == dsw_idle)
     365                        ds_window_start_move(wnd, event);
     366        }
     367
     368        if (event->type == POS_RELEASE) {
     369                if (wnd->state == dsw_moving)
     370                        ds_window_finish_move(wnd, event);
     371        }
     372
     373        if (event->type == POS_UPDATE) {
     374                if (wnd->state == dsw_moving)
     375                        ds_window_update_move(wnd, event);
     376        }
     377
     378        return EOK;
     379}
     380
    272381/** @}
    273382 */
  • uspace/srv/hid/display/window.h

    r8e9781f ra40ae0d  
    3838
    3939#include <errno.h>
     40#include <io/pos_event.h>
    4041#include <types/gfx/context.h>
    4142#include <types/gfx/ops/context.h>
     
    5051extern void ds_window_destroy(ds_window_t *);
    5152extern gfx_context_t *ds_window_get_ctx(ds_window_t *);
     53extern errno_t ds_window_post_pos_event(ds_window_t *, pos_event_t *);
    5254
    5355#endif
Note: See TracChangeset for help on using the changeset viewer.