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

Changeset b0a94854 in mainline


Ignore:
Timestamp:
2020-02-19T13:28:34Z (14 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master
Children:
0a052b0
Parents:
e1f2079
git-author:
Jiri Svoboda <jiri@…> (2020-01-18 18:28:21)
git-committer:
Jiri Svoboda <jiri@…> (2020-02-19 13:28:34)
Message:

Deliver window focus and unfocus events

Location:
uspace
Files:
11 edited

Legend:

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

    re1f2079 rb0a94854  
    5858/** Display window callbacks */
    5959typedef struct {
     60        /** Focus event */
     61        void (*focus_event)(void *);
     62        /** Keyboard event callback */
    6063        void (*kbd_event)(void *, kbd_event_t *);
     64        /** Position event callback */
    6165        void (*pos_event)(void *, pos_event_t *);
     66        /** Unfocus event */
     67        void (*unfocus_event)(void *);
    6268} display_wnd_cb_t;
    6369
  • uspace/lib/display/include/types/display/event.h

    re1f2079 rb0a94854  
    3939#include <io/pos_event.h>
    4040
     41/** Display window event type */
    4142typedef enum {
     43        /** Window gained focus */
     44        wev_focus,
     45        /** Keyboard event */
    4246        wev_kbd,
    43         wev_pos
     47        /** Position event */
     48        wev_pos,
     49        /** Window lost focus */
     50        wev_unfocus
    4451} display_wnd_ev_type_t;
    4552
     53/** Display window event */
    4654typedef struct {
     55        /** Event type */
    4756        display_wnd_ev_type_t etype;
    4857        union {
     58                /** Keyboard event data */
    4959                kbd_event_t kbd;
     60                /** Position event data */
    5061                pos_event_t pos;
    5162        } ev;
  • uspace/lib/display/src/display.c

    re1f2079 rb0a94854  
    296296
    297297                switch (event.etype) {
     298                case wev_focus:
     299                        if (window->cb != NULL && window->cb->focus_event != NULL) {
     300                                window->cb->focus_event(window->cb_arg);
     301                        }
     302                        break;
    298303                case wev_kbd:
    299304                        if (window->cb != NULL && window->cb->kbd_event != NULL) {
     
    306311                                window->cb->pos_event(window->cb_arg,
    307312                                    &event.ev.pos);
     313                        }
     314                        break;
     315                case wev_unfocus:
     316                        if (window->cb != NULL && window->cb->unfocus_event != NULL) {
     317                                window->cb->unfocus_event(window->cb_arg);
    308318                        }
    309319                        break;
  • uspace/lib/display/test/display.c

    re1f2079 rb0a94854  
    4747
    4848static void test_display_conn(ipc_call_t *, void *);
     49
     50static void test_focus_event(void *);
    4951static void test_kbd_event(void *, kbd_event_t *);
    5052static void test_pos_event(void *, pos_event_t *);
     53static void test_unfocus_event(void *);
    5154
    5255static errno_t test_window_create(void *, display_wnd_params_t *, sysarg_t *);
     
    6366
    6467static display_wnd_cb_t test_display_wnd_cb = {
     68        .focus_event = test_focus_event,
    6569        .kbd_event = test_kbd_event,
    66         .pos_event = test_pos_event
     70        .pos_event = test_pos_event,
     71        .unfocus_event = test_unfocus_event
    6772};
    6873
     
    8590        bool get_event_called;
    8691        bool set_color_called;
     92        bool focus_event_called;
    8793        bool kbd_event_called;
    8894        bool pos_event_called;
     95        bool unfocus_event_called;
    8996        fibril_condvar_t event_cv;
    9097        fibril_mutex_t event_lock;
     
    382389
    383390        display_close(disp);
     391        rc = loc_service_unregister(sid);
     392        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     393}
     394
     395/** Focus event can be delivered from server to client callback function */
     396PCUT_TEST(focus_event_deliver)
     397{
     398        errno_t rc;
     399        service_id_t sid;
     400        display_t *disp = NULL;
     401        display_wnd_params_t params;
     402        display_window_t *wnd;
     403        test_response_t resp;
     404
     405        async_set_fallback_port_handler(test_display_conn, &resp);
     406
     407        // FIXME This causes this test to be non-reentrant!
     408        rc = loc_server_register(test_display_server);
     409        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     410
     411        rc = loc_service_register(test_display_svc, &sid);
     412        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     413
     414        rc = display_open(test_display_svc, &disp);
     415        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     416        PCUT_ASSERT_NOT_NULL(disp);
     417        PCUT_ASSERT_NOT_NULL(resp.srv);
     418
     419        wnd = NULL;
     420        resp.rc = EOK;
     421        display_wnd_params_init(&params);
     422        params.rect.p0.x = 0;
     423        params.rect.p0.y = 0;
     424        params.rect.p0.x = 100;
     425        params.rect.p0.y = 100;
     426
     427        rc = display_window_create(disp, &params, &test_display_wnd_cb,
     428            (void *) &resp, &wnd);
     429        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     430        PCUT_ASSERT_NOT_NULL(wnd);
     431
     432        resp.event_cnt = 1;
     433        resp.event.etype = wev_focus;
     434        resp.wnd_id = wnd->id;
     435        resp.focus_event_called = false;
     436        fibril_mutex_initialize(&resp.event_lock);
     437        fibril_condvar_initialize(&resp.event_cv);
     438        display_srv_ev_pending(resp.srv);
     439
     440        /* Wait for the event handler to be called. */
     441        fibril_mutex_lock(&resp.event_lock);
     442        while (!resp.focus_event_called) {
     443                fibril_condvar_wait(&resp.event_cv, &resp.event_lock);
     444        }
     445        fibril_mutex_unlock(&resp.event_lock);
     446
     447        /* Verify that the event was delivered correctly */
     448        PCUT_ASSERT_EQUALS(resp.event.etype,
     449            resp.revent.etype);
     450
     451        rc = display_window_destroy(wnd);
     452        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     453
     454        display_close(disp);
     455
    384456        rc = loc_service_unregister(sid);
    385457        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     
    540612}
    541613
     614/** Unfocus event can be delivered from server to client callback function */
     615PCUT_TEST(unfocus_event_deliver)
     616{
     617        errno_t rc;
     618        service_id_t sid;
     619        display_t *disp = NULL;
     620        display_wnd_params_t params;
     621        display_window_t *wnd;
     622        test_response_t resp;
     623
     624        async_set_fallback_port_handler(test_display_conn, &resp);
     625
     626        // FIXME This causes this test to be non-reentrant!
     627        rc = loc_server_register(test_display_server);
     628        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     629
     630        rc = loc_service_register(test_display_svc, &sid);
     631        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     632
     633        rc = display_open(test_display_svc, &disp);
     634        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     635        PCUT_ASSERT_NOT_NULL(disp);
     636        PCUT_ASSERT_NOT_NULL(resp.srv);
     637
     638        wnd = NULL;
     639        resp.rc = EOK;
     640        display_wnd_params_init(&params);
     641        params.rect.p0.x = 0;
     642        params.rect.p0.y = 0;
     643        params.rect.p0.x = 100;
     644        params.rect.p0.y = 100;
     645
     646        rc = display_window_create(disp, &params, &test_display_wnd_cb,
     647            (void *) &resp, &wnd);
     648        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     649        PCUT_ASSERT_NOT_NULL(wnd);
     650
     651        resp.event_cnt = 1;
     652        resp.event.etype = wev_unfocus;
     653        resp.wnd_id = wnd->id;
     654        resp.focus_event_called = false;
     655        fibril_mutex_initialize(&resp.event_lock);
     656        fibril_condvar_initialize(&resp.event_cv);
     657        display_srv_ev_pending(resp.srv);
     658
     659        /* Wait for the event handler to be called. */
     660        fibril_mutex_lock(&resp.event_lock);
     661        while (!resp.unfocus_event_called) {
     662                fibril_condvar_wait(&resp.event_cv, &resp.event_lock);
     663        }
     664        fibril_mutex_unlock(&resp.event_lock);
     665
     666        /* Verify that the event was delivered correctly */
     667        PCUT_ASSERT_EQUALS(resp.event.etype,
     668            resp.revent.etype);
     669
     670        rc = display_window_destroy(wnd);
     671        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     672
     673        display_close(disp);
     674
     675        rc = loc_service_unregister(sid);
     676        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     677}
     678
    542679/** Test display service connection.
    543680 *
     
    587724}
    588725
     726static void test_focus_event(void *arg)
     727{
     728        test_response_t *resp = (test_response_t *) arg;
     729
     730        resp->revent.etype = wev_focus;
     731
     732        fibril_mutex_lock(&resp->event_lock);
     733        resp->focus_event_called = true;
     734        fibril_condvar_broadcast(&resp->event_cv);
     735        fibril_mutex_unlock(&resp->event_lock);
     736}
     737
    589738static void test_kbd_event(void *arg, kbd_event_t *event)
    590739{
     
    609758        fibril_mutex_lock(&resp->event_lock);
    610759        resp->pos_event_called = true;
     760        fibril_condvar_broadcast(&resp->event_cv);
     761        fibril_mutex_unlock(&resp->event_lock);
     762}
     763
     764static void test_unfocus_event(void *arg)
     765{
     766        test_response_t *resp = (test_response_t *) arg;
     767
     768        resp->revent.etype = wev_unfocus;
     769
     770        fibril_mutex_lock(&resp->event_lock);
     771        resp->unfocus_event_called = true;
    611772        fibril_condvar_broadcast(&resp->event_cv);
    612773        fibril_mutex_unlock(&resp->event_lock);
  • uspace/lib/gui/window.c

    re1f2079 rb0a94854  
    8383static pixel_t color_caption_unfocus = PIXEL(255, 207, 207, 207);
    8484
     85static void window_focus_event(void *);
    8586static void window_kbd_event(void *, kbd_event_t *);
    8687static void window_pos_event(void *, pos_event_t *);
     88static void window_unfocus_event(void *);
    8789
    8890static display_wnd_cb_t window_cb = {
     91        .focus_event = window_focus_event,
    8992        .kbd_event = window_kbd_event,
    90         .pos_event = window_pos_event
     93        .pos_event = window_pos_event,
     94        .unfocus_event = window_unfocus_event
    9195};
    9296
     
    587591                        break;
    588592                case ET_POSITION_EVENT:
    589                         if (!win->is_focused) {
    590                                 win->is_focused = true;
    591                                 handle_refresh(win);
    592                         }
    593593                        deliver_position_event(win, event->data.pos);
    594594                        break;
     
    766766}
    767767
     768static void window_focus_event(void *arg)
     769{
     770        window_t *win = (window_t *) arg;
     771        window_event_t *event;
     772
     773        event = (window_event_t *) calloc(1, sizeof(window_event_t));
     774        if (event == NULL)
     775                return;
     776
     777        link_initialize(&event->link);
     778        event->type = ET_WINDOW_FOCUS;
     779        prodcons_produce(&win->events, &event->link);
     780}
     781
    768782static void window_kbd_event(void *arg, kbd_event_t *kevent)
    769783{
     
    796810}
    797811
     812static void window_unfocus_event(void *arg)
     813{
     814        window_t *win = (window_t *) arg;
     815        window_event_t *event;
     816
     817        event = (window_event_t *) calloc(1, sizeof(window_event_t));
     818        if (event == NULL)
     819                return;
     820
     821        link_initialize(&event->link);
     822        event->type = ET_WINDOW_UNFOCUS;
     823        prodcons_produce(&win->events, &event->link);
     824}
     825
    798826/** @}
    799827 */
  • uspace/srv/hid/display/client.c

    re1f2079 rb0a94854  
    203203}
    204204
     205/** Post focus event to the client's message queue.
     206 *
     207 * @param client Client
     208 * @param ewindow Window that the message is targetted to
     209 *
     210 * @return EOK on success or an error code
     211 */
     212errno_t ds_client_post_focus_event(ds_client_t *client, ds_window_t *ewindow)
     213{
     214        ds_window_ev_t *wevent;
     215
     216        wevent = calloc(1, sizeof(ds_window_ev_t));
     217        if (wevent == NULL)
     218                return ENOMEM;
     219
     220        wevent->window = ewindow;
     221        wevent->event.etype = wev_focus;
     222        list_append(&wevent->levents, &client->events);
     223
     224        /* Notify the client */
     225        // TODO Do not send more than once until client drains the queue
     226        if (client->cb != NULL && client->cb->ev_pending != NULL)
     227                client->cb->ev_pending(client->cb_arg);
     228
     229        return EOK;
     230}
     231
    205232/** Post keyboard event to the client's message queue.
    206233 *
     
    262289}
    263290
     291/** Post unfocus event to the client's message queue.
     292 *
     293 * @param client Client
     294 * @param ewindow Window that the message is targetted to
     295 *
     296 * @return EOK on success or an error code
     297 */
     298errno_t ds_client_post_unfocus_event(ds_client_t *client, ds_window_t *ewindow)
     299{
     300        ds_window_ev_t *wevent;
     301
     302        wevent = calloc(1, sizeof(ds_window_ev_t));
     303        if (wevent == NULL)
     304                return ENOMEM;
     305
     306        wevent->window = ewindow;
     307        wevent->event.etype = wev_unfocus;
     308        list_append(&wevent->levents, &client->events);
     309
     310        /* Notify the client */
     311        // TODO Do not send more than once until client drains the queue
     312        if (client->cb != NULL && client->cb->ev_pending != NULL)
     313                client->cb->ev_pending(client->cb_arg);
     314
     315        return EOK;
     316}
     317
    264318/** @}
    265319 */
  • uspace/srv/hid/display/client.h

    re1f2079 rb0a94854  
    5353extern errno_t ds_client_get_event(ds_client_t *, ds_window_t **,
    5454    display_wnd_ev_t *);
     55extern errno_t ds_client_post_focus_event(ds_client_t *, ds_window_t *);
    5556extern errno_t ds_client_post_kbd_event(ds_client_t *, ds_window_t *,
    5657    kbd_event_t *);
    5758extern errno_t ds_client_post_pos_event(ds_client_t *, ds_window_t *,
    5859    pos_event_t *);
     60extern errno_t ds_client_post_unfocus_event(ds_client_t *, ds_window_t *);
    5961
    6062#endif
  • uspace/srv/hid/display/seat.c

    re1f2079 rb0a94854  
    8383void ds_seat_set_focus(ds_seat_t *seat, ds_window_t *wnd)
    8484{
     85        if (seat->focus != NULL)
     86                ds_window_post_unfocus_event(seat->focus);
     87
    8588        seat->focus = wnd;
     89
     90        if (wnd != NULL)
     91                ds_window_post_focus_event(wnd);
    8692}
    8793
  • uspace/srv/hid/display/test/client.c

    re1f2079 rb0a94854  
    163163}
    164164
     165/** Test ds_client_get_event(), ds_client_post_focus_event(). */
     166PCUT_TEST(client_get_post_focus_event)
     167{
     168        ds_display_t *disp;
     169        ds_client_t *client;
     170        ds_window_t *wnd;
     171        display_wnd_params_t params;
     172        ds_window_t *rwindow;
     173        display_wnd_ev_t revent;
     174        bool called_cb = NULL;
     175        errno_t rc;
     176
     177        rc = ds_display_create(NULL, &disp);
     178        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     179
     180        rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
     181        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     182
     183        display_wnd_params_init(&params);
     184        params.rect.p0.x = params.rect.p0.y = 0;
     185        params.rect.p1.x = params.rect.p1.y = 1;
     186
     187        rc = ds_window_create(client, &params, &wnd);
     188        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     189
     190        PCUT_ASSERT_FALSE(called_cb);
     191
     192        rc = ds_client_get_event(client, &rwindow, &revent);
     193        PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
     194
     195        rc = ds_client_post_focus_event(client, wnd);
     196        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     197        PCUT_ASSERT_TRUE(called_cb);
     198
     199        rc = ds_client_get_event(client, &rwindow, &revent);
     200        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     201        PCUT_ASSERT_EQUALS(wnd, rwindow);
     202        PCUT_ASSERT_EQUALS(wev_focus, revent.etype);
     203
     204        rc = ds_client_get_event(client, &rwindow, &revent);
     205        PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
     206
     207        ds_window_destroy(wnd);
     208        ds_client_destroy(client);
     209        ds_display_destroy(disp);
     210}
     211
    165212/** Test ds_client_get_event(), ds_client_post_kbd_event(). */
    166213PCUT_TEST(client_get_post_kbd_event)
     
    275322}
    276323
     324/** Test ds_client_get_event(), ds_client_post_unfocus_event(). */
     325PCUT_TEST(client_get_post_unfocus_event)
     326{
     327        ds_display_t *disp;
     328        ds_client_t *client;
     329        ds_window_t *wnd;
     330        display_wnd_params_t params;
     331        ds_window_t *rwindow;
     332        display_wnd_ev_t revent;
     333        bool called_cb = NULL;
     334        errno_t rc;
     335
     336        rc = ds_display_create(NULL, &disp);
     337        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     338
     339        rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
     340        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     341
     342        display_wnd_params_init(&params);
     343        params.rect.p0.x = params.rect.p0.y = 0;
     344        params.rect.p1.x = params.rect.p1.y = 1;
     345
     346        rc = ds_window_create(client, &params, &wnd);
     347        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     348
     349        PCUT_ASSERT_FALSE(called_cb);
     350
     351        rc = ds_client_get_event(client, &rwindow, &revent);
     352        PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
     353
     354        rc = ds_client_post_unfocus_event(client, wnd);
     355        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     356        PCUT_ASSERT_TRUE(called_cb);
     357
     358        rc = ds_client_get_event(client, &rwindow, &revent);
     359        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     360        PCUT_ASSERT_EQUALS(wnd, rwindow);
     361        PCUT_ASSERT_EQUALS(wev_unfocus, revent.etype);
     362
     363        rc = ds_client_get_event(client, &rwindow, &revent);
     364        PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
     365
     366        ds_window_destroy(wnd);
     367        ds_client_destroy(client);
     368        ds_display_destroy(disp);
     369}
     370
    277371/** Test client being destroyed while still having a window.
    278372 *
  • uspace/srv/hid/display/window.c

    re1f2079 rb0a94854  
    518518}
    519519
     520/** Post focus event to window.
     521 *
     522 * @param wnd Window
     523 */
     524errno_t ds_window_post_focus_event(ds_window_t *wnd)
     525{
     526        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_focus_event\n");
     527
     528        return ds_client_post_focus_event(wnd->client, wnd);
     529}
     530
     531/** Post unfocus event to window.
     532 *
     533 * @param wnd Window
     534 */
     535errno_t ds_window_post_unfocus_event(ds_window_t *wnd)
     536{
     537        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_unfocus_event\n");
     538
     539        return ds_client_post_unfocus_event(wnd->client, wnd);
     540}
     541
    520542/** @}
    521543 */
  • uspace/srv/hid/display/window.h

    re1f2079 rb0a94854  
    5454extern errno_t ds_window_paint(ds_window_t *, gfx_rect_t *);
    5555extern errno_t ds_window_post_pos_event(ds_window_t *, pos_event_t *);
     56extern errno_t ds_window_post_focus_event(ds_window_t *);
     57extern errno_t ds_window_post_unfocus_event(ds_window_t *);
    5658
    5759#endif
Note: See TracChangeset for help on using the changeset viewer.