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

Changeset f7fb2b21 in mainline


Ignore:
Timestamp:
2020-02-10T19:01:42Z (10 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
b43edabe
Parents:
287688f
Message:

Propagate position event to display clients

Location:
uspace
Files:
11 edited

Legend:

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

    r287688f rf7fb2b21  
    3939#include <fibril_synch.h>
    4040#include <io/kbd_event.h>
     41#include <io/pos_event.h>
    4142#include <stdint.h>
    4243
     
    5859typedef struct {
    5960        void (*kbd_event)(void *, kbd_event_t *);
     61        void (*pos_event)(void *, pos_event_t *);
    6062} display_wnd_cb_t;
    6163
  • uspace/lib/display/include/types/display/event.h

    r287688f rf7fb2b21  
    3737
    3838#include <io/kbd_event.h>
     39#include <io/pos_event.h>
     40
     41typedef enum {
     42        wev_kbd,
     43        wev_pos
     44} display_wnd_ev_type_t;
    3945
    4046typedef struct {
    41         kbd_event_t kbd_event;
     47        display_wnd_ev_type_t etype;
     48        union {
     49                kbd_event_t kbd;
     50                pos_event_t pos;
     51        } ev;
    4252} display_wnd_ev_t;
    4353
  • uspace/lib/display/src/display.c

    r287688f rf7fb2b21  
    295295                        break;
    296296
    297                 if (window->cb != NULL && window->cb->kbd_event != NULL)
    298                         window->cb->kbd_event(window->cb_arg, &event.kbd_event);
     297                switch (event.etype) {
     298                case wev_kbd:
     299                        if (window->cb != NULL && window->cb->kbd_event != NULL) {
     300                                window->cb->kbd_event(window->cb_arg,
     301                                    &event.ev.kbd);
     302                        }
     303                        break;
     304                case wev_pos:
     305                        if (window->cb != NULL && window->cb->pos_event != NULL) {
     306                                window->cb->pos_event(window->cb_arg,
     307                                    &event.ev.pos);
     308                        }
     309                        break;
     310                }
    299311        }
    300312
  • uspace/lib/display/test/display.c

    r287688f rf7fb2b21  
    4848static void test_display_conn(ipc_call_t *, void *);
    4949static void test_kbd_event(void *, kbd_event_t *);
     50static void test_pos_event(void *, pos_event_t *);
    5051
    5152static errno_t test_window_create(void *, display_wnd_params_t *, sysarg_t *);
     
    6263
    6364static display_wnd_cb_t test_display_wnd_cb = {
    64         .kbd_event = test_kbd_event
     65        .kbd_event = test_kbd_event,
     66        .pos_event = test_pos_event
    6567};
    6668
     
    8486        bool set_color_called;
    8587        bool kbd_event_called;
    86         fibril_condvar_t kbd_event_cv;
    87         fibril_mutex_t kbd_event_lock;
     88        bool pos_event_called;
     89        fibril_condvar_t event_cv;
     90        fibril_mutex_t event_lock;
    8891        display_srv_t *srv;
    8992} test_response_t;
     
    392395        display_window_t *wnd;
    393396        test_response_t resp;
    394         gfx_context_t *gc;
    395397
    396398        async_set_fallback_port_handler(test_display_conn, &resp);
     
    421423        PCUT_ASSERT_NOT_NULL(wnd);
    422424
    423         gc = NULL;
    424         rc = display_window_get_gc(wnd, &gc);
    425         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    426         PCUT_ASSERT_NOT_NULL(gc);
    427 
    428425        resp.event_cnt = 1;
    429         resp.event.kbd_event.type = KEY_PRESS;
    430         resp.event.kbd_event.key = KC_ENTER;
    431         resp.event.kbd_event.mods = 0;
    432         resp.event.kbd_event.c = L'\0';
     426        resp.event.etype = wev_kbd;
     427        resp.event.ev.kbd.type = KEY_PRESS;
     428        resp.event.ev.kbd.key = KC_ENTER;
     429        resp.event.ev.kbd.mods = 0;
     430        resp.event.ev.kbd.c = L'\0';
    433431        resp.wnd_id = wnd->id;
    434432        resp.kbd_event_called = false;
    435         fibril_mutex_initialize(&resp.kbd_event_lock);
    436         fibril_condvar_initialize(&resp.kbd_event_cv);
     433        fibril_mutex_initialize(&resp.event_lock);
     434        fibril_condvar_initialize(&resp.event_cv);
    437435        display_srv_ev_pending(resp.srv);
    438436
    439437        /* Wait for the event handler to be called. */
    440         fibril_mutex_lock(&resp.kbd_event_lock);
     438        fibril_mutex_lock(&resp.event_lock);
    441439        while (!resp.kbd_event_called) {
    442                 fibril_condvar_wait(&resp.kbd_event_cv, &resp.kbd_event_lock);
     440                fibril_condvar_wait(&resp.event_cv, &resp.event_lock);
    443441        }
    444         fibril_mutex_unlock(&resp.kbd_event_lock);
     442        fibril_mutex_unlock(&resp.event_lock);
    445443
    446444        /* Verify that the event was delivered correctly */
    447         PCUT_ASSERT_EQUALS(resp.event.kbd_event.type,
    448             resp.revent.kbd_event.type);
    449         PCUT_ASSERT_EQUALS(resp.event.kbd_event.key,
    450             resp.revent.kbd_event.key);
    451         PCUT_ASSERT_EQUALS(resp.event.kbd_event.mods,
    452             resp.revent.kbd_event.mods);
    453         PCUT_ASSERT_EQUALS(resp.event.kbd_event.c,
    454             resp.revent.kbd_event.c);
     445        PCUT_ASSERT_EQUALS(resp.event.etype,
     446            resp.revent.etype);
     447        PCUT_ASSERT_EQUALS(resp.event.ev.kbd.type,
     448            resp.revent.ev.kbd.type);
     449        PCUT_ASSERT_EQUALS(resp.event.ev.kbd.key,
     450            resp.revent.ev.kbd.key);
     451        PCUT_ASSERT_EQUALS(resp.event.ev.kbd.mods,
     452            resp.revent.ev.kbd.mods);
     453        PCUT_ASSERT_EQUALS(resp.event.ev.kbd.c,
     454            resp.revent.ev.kbd.c);
     455
     456        rc = display_window_destroy(wnd);
     457        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     458
     459        display_close(disp);
     460
     461        rc = loc_service_unregister(sid);
     462        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     463}
     464
     465/** Position event can be delivered from server to client callback function */
     466PCUT_TEST(pos_event_deliver)
     467{
     468        errno_t rc;
     469        service_id_t sid;
     470        display_t *disp = NULL;
     471        display_wnd_params_t params;
     472        display_window_t *wnd;
     473        test_response_t resp;
     474
     475        async_set_fallback_port_handler(test_display_conn, &resp);
     476
     477        // FIXME This causes this test to be non-reentrant!
     478        rc = loc_server_register(test_display_server);
     479        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     480
     481        rc = loc_service_register(test_display_svc, &sid);
     482        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     483
     484        rc = display_open(test_display_svc, &disp);
     485        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     486        PCUT_ASSERT_NOT_NULL(disp);
     487        PCUT_ASSERT_NOT_NULL(resp.srv);
     488
     489        wnd = NULL;
     490        resp.rc = EOK;
     491        display_wnd_params_init(&params);
     492        params.rect.p0.x = 0;
     493        params.rect.p0.y = 0;
     494        params.rect.p0.x = 100;
     495        params.rect.p0.y = 100;
     496
     497        rc = display_window_create(disp, &params, &test_display_wnd_cb,
     498            (void *) &resp, &wnd);
     499        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     500        PCUT_ASSERT_NOT_NULL(wnd);
     501
     502        resp.event_cnt = 1;
     503        resp.event.etype = wev_pos;
     504        resp.event.ev.pos.type = POS_PRESS;
     505        resp.event.ev.pos.btn_num = 1;
     506        resp.event.ev.pos.hpos = 2;
     507        resp.event.ev.pos.vpos = 3;
     508        resp.wnd_id = wnd->id;
     509        resp.pos_event_called = false;
     510        fibril_mutex_initialize(&resp.event_lock);
     511        fibril_condvar_initialize(&resp.event_cv);
     512        display_srv_ev_pending(resp.srv);
     513
     514        /* Wait for the event handler to be called. */
     515        fibril_mutex_lock(&resp.event_lock);
     516        while (!resp.pos_event_called) {
     517                fibril_condvar_wait(&resp.event_cv, &resp.event_lock);
     518        }
     519        fibril_mutex_unlock(&resp.event_lock);
     520
     521        /* Verify that the event was delivered correctly */
     522        PCUT_ASSERT_EQUALS(resp.event.etype,
     523            resp.revent.etype);
     524        PCUT_ASSERT_EQUALS(resp.event.ev.pos.type,
     525            resp.revent.ev.pos.type);
     526        PCUT_ASSERT_EQUALS(resp.event.ev.pos.btn_num,
     527            resp.revent.ev.pos.btn_num);
     528        PCUT_ASSERT_EQUALS(resp.event.ev.pos.hpos,
     529            resp.revent.ev.pos.hpos);
     530        PCUT_ASSERT_EQUALS(resp.event.ev.pos.vpos,
     531            resp.revent.ev.pos.vpos);
    455532
    456533        rc = display_window_destroy(wnd);
     
    514591        test_response_t *resp = (test_response_t *) arg;
    515592
    516         resp->revent.kbd_event = *event;
    517 
    518         fibril_mutex_lock(&resp->kbd_event_lock);
     593        resp->revent.etype = wev_kbd;
     594        resp->revent.ev.kbd = *event;
     595
     596        fibril_mutex_lock(&resp->event_lock);
    519597        resp->kbd_event_called = true;
    520         fibril_condvar_broadcast(&resp->kbd_event_cv);
    521         fibril_mutex_unlock(&resp->kbd_event_lock);
     598        fibril_condvar_broadcast(&resp->event_cv);
     599        fibril_mutex_unlock(&resp->event_lock);
     600}
     601
     602static void test_pos_event(void *arg, pos_event_t *event)
     603{
     604        test_response_t *resp = (test_response_t *) arg;
     605
     606        resp->revent.etype = wev_pos;
     607        resp->revent.ev.pos = *event;
     608
     609        fibril_mutex_lock(&resp->event_lock);
     610        resp->pos_event_called = true;
     611        fibril_condvar_broadcast(&resp->event_cv);
     612        fibril_mutex_unlock(&resp->event_lock);
    522613}
    523614
  • uspace/lib/gui/window.c

    r287688f rf7fb2b21  
    8484
    8585static void window_kbd_event(void *, kbd_event_t *);
     86static void window_pos_event(void *, pos_event_t *);
    8687
    8788static display_wnd_cb_t window_cb = {
    88         .kbd_event = window_kbd_event
     89        .kbd_event = window_kbd_event,
     90        .pos_event = window_pos_event
    8991};
    9092
     
    815817}
    816818
     819static void window_pos_event(void *arg, pos_event_t *pevent)
     820{
     821        window_t *win = (window_t *) arg;
     822        window_event_t *event;
     823
     824        event = (window_event_t *) calloc(1, sizeof(window_event_t));
     825        if (event == NULL)
     826                return;
     827
     828        link_initialize(&event->link);
     829        event->type = ET_POSITION_EVENT;
     830        event->data.pos = *pevent;
     831        prodcons_produce(&win->events, &event->link);
     832}
     833
    817834/** @}
    818835 */
  • uspace/srv/hid/display/client.c

    r287688f rf7fb2b21  
    221221
    222222        wevent->window = ewindow;
    223         wevent->event.kbd_event = *event;
     223        wevent->event.etype = wev_kbd;
     224        wevent->event.ev.kbd = *event;
    224225        list_append(&wevent->levents, &client->events);
    225226
     
    231232}
    232233
     234/** Post position event to the client's message queue.
     235 *
     236 * @param client Client
     237 * @param ewindow Window that the message is targetted to
     238 * @param event Event
     239 *
     240 * @return EOK on success or an error code
     241 */
     242errno_t ds_client_post_pos_event(ds_client_t *client, ds_window_t *ewindow,
     243    pos_event_t *event)
     244{
     245        ds_window_ev_t *wevent;
     246
     247        wevent = calloc(1, sizeof(ds_window_ev_t));
     248        if (wevent == NULL)
     249                return ENOMEM;
     250
     251        wevent->window = ewindow;
     252        wevent->event.etype = wev_pos;
     253        wevent->event.ev.pos = *event;
     254        list_append(&wevent->levents, &client->events);
     255
     256        /* Notify the client */
     257        // TODO Do not send more than once until client drains the queue
     258        if (client->cb != NULL && client->cb->ev_pending != NULL)
     259                client->cb->ev_pending(client->cb_arg);
     260
     261        return EOK;
     262}
     263
    233264/** @}
    234265 */
  • uspace/srv/hid/display/client.h

    r287688f rf7fb2b21  
    3939#include <errno.h>
    4040#include <io/kbd_event.h>
     41#include <io/pos_event.h>
    4142#include "types/display/client.h"
    4243#include "types/display/display.h"
     
    5455extern errno_t ds_client_post_kbd_event(ds_client_t *, ds_window_t *,
    5556    kbd_event_t *);
     57extern errno_t ds_client_post_pos_event(ds_client_t *, ds_window_t *,
     58    pos_event_t *);
    5659
    5760#endif
  • uspace/srv/hid/display/test/client.c

    r287688f rf7fb2b21  
    206206        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    207207        PCUT_ASSERT_EQUALS(wnd, rwindow);
    208         PCUT_ASSERT_EQUALS(event.type, revent.kbd_event.type);
    209         PCUT_ASSERT_EQUALS(event.key, revent.kbd_event.key);
    210         PCUT_ASSERT_EQUALS(event.mods, revent.kbd_event.mods);
    211         PCUT_ASSERT_EQUALS(event.c, revent.kbd_event.c);
     208        PCUT_ASSERT_EQUALS(wev_kbd, revent.etype);
     209        PCUT_ASSERT_EQUALS(event.type, revent.ev.kbd.type);
     210        PCUT_ASSERT_EQUALS(event.key, revent.ev.kbd.key);
     211        PCUT_ASSERT_EQUALS(event.mods, revent.ev.kbd.mods);
     212        PCUT_ASSERT_EQUALS(event.c, revent.ev.kbd.c);
     213
     214        rc = ds_client_get_event(client, &rwindow, &revent);
     215        PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
     216
     217        ds_window_destroy(wnd);
     218        ds_client_destroy(client);
     219        ds_display_destroy(disp);
     220}
     221
     222/** Test ds_client_get_event(), ds_client_post_pos_event(). */
     223PCUT_TEST(client_get_post_pos_event)
     224{
     225        ds_display_t *disp;
     226        ds_client_t *client;
     227        ds_window_t *wnd;
     228        display_wnd_params_t params;
     229        pos_event_t event;
     230        ds_window_t *rwindow;
     231        display_wnd_ev_t revent;
     232        bool called_cb = NULL;
     233        errno_t rc;
     234
     235        rc = ds_display_create(NULL, &disp);
     236        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     237
     238        rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
     239        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     240
     241        display_wnd_params_init(&params);
     242        params.rect.p0.x = params.rect.p0.y = 0;
     243        params.rect.p1.x = params.rect.p1.y = 1;
     244
     245        rc = ds_window_create(client, &params, &wnd);
     246        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     247
     248        event.type = POS_PRESS;
     249        event.hpos = 1;
     250        event.vpos = 2;
     251
     252        PCUT_ASSERT_FALSE(called_cb);
     253
     254        rc = ds_client_get_event(client, &rwindow, &revent);
     255        PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
     256
     257        rc = ds_client_post_pos_event(client, wnd, &event);
     258        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     259        PCUT_ASSERT_TRUE(called_cb);
     260
     261        rc = ds_client_get_event(client, &rwindow, &revent);
     262        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     263        PCUT_ASSERT_EQUALS(wnd, rwindow);
     264        PCUT_ASSERT_EQUALS(wev_pos, revent.etype);
     265        PCUT_ASSERT_EQUALS(event.type, revent.ev.pos.type);
     266        PCUT_ASSERT_EQUALS(event.hpos, revent.ev.pos.hpos);
     267        PCUT_ASSERT_EQUALS(event.vpos, revent.ev.pos.vpos);
    212268
    213269        rc = ds_client_get_event(client, &rwindow, &revent);
  • uspace/srv/hid/display/test/display.c

    r287688f rf7fb2b21  
    377377        w1->dpos.y = 400;
    378378
    379         PCUT_ASSERT_FALSE(called_cb);
    380 
    381379        ds_seat_set_focus(seat, w0);
    382380
     
    386384        rc = ds_display_post_ptd_event(disp, &event);
    387385        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    388         PCUT_ASSERT_FALSE(called_cb);
    389386
    390387        event.type = PTD_PRESS;
     
    392389        rc = ds_display_post_ptd_event(disp, &event);
    393390        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    394         PCUT_ASSERT_FALSE(called_cb);
    395391
    396392        PCUT_ASSERT_EQUALS(w1, seat->focus);
     
    400396        rc = ds_display_post_ptd_event(disp, &event);
    401397        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    402         PCUT_ASSERT_FALSE(called_cb);
    403398
    404399        event.type = PTD_MOVE;
     
    407402        rc = ds_display_post_ptd_event(disp, &event);
    408403        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    409         PCUT_ASSERT_FALSE(called_cb);
    410404
    411405        event.type = PTD_PRESS;
     
    413407        rc = ds_display_post_ptd_event(disp, &event);
    414408        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    415         PCUT_ASSERT_FALSE(called_cb);
    416409
    417410        PCUT_ASSERT_EQUALS(w0, seat->focus);
  • uspace/srv/hid/display/test/seat.c

    r287688f rf7fb2b21  
    232232        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    233233        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);
     234        PCUT_ASSERT_EQUALS(wev_kbd, revent.etype);
     235        PCUT_ASSERT_EQUALS(event.type, revent.ev.kbd.type);
     236        PCUT_ASSERT_EQUALS(event.key, revent.ev.kbd.key);
     237        PCUT_ASSERT_EQUALS(event.mods, revent.ev.kbd.mods);
     238        PCUT_ASSERT_EQUALS(event.c, revent.ev.kbd.c);
    238239
    239240        rc = ds_client_get_event(client, &rwindow, &revent);
  • uspace/srv/hid/display/window.c

    r287688f rf7fb2b21  
    489489errno_t ds_window_post_pos_event(ds_window_t *wnd, pos_event_t *event)
    490490{
     491        pos_event_t tevent;
     492
    491493        log_msg(LOG_DEFAULT, LVL_DEBUG,
    492494            "ds_window_post_pos_event type=%d pos=%d,%d\n", event->type,
     
    508510        }
    509511
    510         return EOK;
     512        /* Transform event coordinates to window-local */
     513        tevent = *event;
     514        tevent.hpos -= wnd->dpos.x;
     515        tevent.vpos -= wnd->dpos.y;
     516
     517        return ds_client_post_pos_event(wnd->client, wnd, &tevent);
    511518}
    512519
Note: See TracChangeset for help on using the changeset viewer.