Changeset b3c185b6 in mainline for uspace/srv/hid/display


Ignore:
Timestamp:
2019-11-04T14:05:35Z (6 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
be15256
Parents:
22faaf2
git-author:
Jiri Svoboda <jiri@…> (2019-10-03 18:05:09)
git-committer:
Jiri Svoboda <jiri@…> (2019-11-04 14:05:35)
Message:

Window event delivery mechanism

Location:
uspace/srv/hid/display
Files:
4 added
12 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/display/display.c

    r22faaf2 rb3c185b6  
    3939#include <io/log.h>
    4040#include <stdlib.h>
     41#include "client.h"
     42#include "window.h"
    4143#include "display.h"
    42 #include "window.h"
    4344
    4445static errno_t disp_window_create(void *, sysarg_t *);
    4546static errno_t disp_window_destroy(void *, sysarg_t);
     47static errno_t disp_get_event(void *, sysarg_t *, display_wnd_ev_t *);
    4648
    4749display_ops_t display_srv_ops = {
    4850        .window_create = disp_window_create,
    49         .window_destroy = disp_window_destroy
     51        .window_destroy = disp_window_destroy,
     52        .get_event = disp_get_event
    5053};
    5154
     
    5356{
    5457        errno_t rc;
    55         ds_display_t *disp = (ds_display_t *) arg;
     58        ds_client_t *client = (ds_client_t *) arg;
    5659        ds_window_t *wnd;
    5760
    5861        log_msg(LOG_DEFAULT, LVL_DEBUG, "disp_window_create()");
    5962
    60         rc = ds_window_create(disp, &wnd);
     63        rc = ds_window_create(client, &wnd);
    6164        log_msg(LOG_DEFAULT, LVL_DEBUG, "disp_window_create() - ds_window_create -> %d", rc);
    6265        if (rc != EOK)
     
    7578static errno_t disp_window_destroy(void *arg, sysarg_t wnd_id)
    7679{
    77         ds_display_t *disp = (ds_display_t *) arg;
    78         ds_window_t *wnd;
    79 
    80         wnd = ds_display_find_window(disp, wnd_id);
     80        ds_client_t *client = (ds_client_t *) arg;
     81        ds_window_t *wnd;
     82
     83        wnd = ds_client_find_window(client, wnd_id);
    8184        if (wnd == NULL)
    8285                return ENOENT;
    8386
    8487        log_msg(LOG_DEFAULT, LVL_DEBUG, "disp_window_destroy()");
    85         ds_display_remove_window(wnd);
     88        ds_client_remove_window(wnd);
    8689        ds_window_delete(wnd);
     90        return EOK;
     91}
     92
     93static errno_t disp_get_event(void *arg, sysarg_t *wnd_id,
     94    display_wnd_ev_t *event)
     95{
     96        ds_client_t *client = (ds_client_t *) arg;
     97        ds_window_t *wnd;
     98        errno_t rc;
     99
     100        log_msg(LOG_DEFAULT, LVL_DEBUG, "disp_window_get_event()");
     101
     102        rc = ds_client_get_event(client, &wnd, event);
     103        if (rc != EOK)
     104                return rc;
     105
     106        *wnd_id = wnd->id;
    87107        return EOK;
    88108}
     
    102122                return ENOMEM;
    103123
    104         list_initialize(&disp->windows);
     124        list_initialize(&disp->clients);
     125        disp->gc = gc;
    105126        disp->next_wnd_id = 1;
    106         disp->gc = gc;
    107127        *rdisp = disp;
    108128        return EOK;
     
    115135void ds_display_destroy(ds_display_t *disp)
    116136{
    117         assert(list_empty(&disp->windows));
     137        assert(list_empty(&disp->clients));
    118138        free(disp);
    119139}
    120140
    121 /** Add window to display.
     141/** Add client to display.
    122142 *
    123143 * @param disp Display
    124  * @param wnd Window
    125  * @return EOK on success, ENOMEM if there are no free window identifiers
    126  */
    127 errno_t ds_display_add_window(ds_display_t *disp, ds_window_t *wnd)
    128 {
    129         assert(wnd->display == NULL);
    130         assert(!link_used(&wnd->lwindows));
    131 
    132         wnd->display = disp;
    133         wnd->id = disp->next_wnd_id++;
    134         list_append(&wnd->lwindows, &disp->windows);
    135 
    136         return EOK;
    137 }
    138 
    139 /** Remove window from display.
    140  *
    141  * @param wnd Window
    142  */
    143 void ds_display_remove_window(ds_window_t *wnd)
    144 {
    145         list_remove(&wnd->lwindows);
    146         wnd->display = NULL;
    147 }
    148 
    149 /** Find window by ID.
     144 * @param client client
     145 */
     146void ds_display_add_client(ds_display_t *disp, ds_client_t *client)
     147{
     148        assert(client->display == NULL);
     149        assert(!link_used(&client->lclients));
     150
     151        client->display = disp;
     152        list_append(&client->lclients, &disp->clients);
     153}
     154
     155/** Remove client from display.
     156 *
     157 * @param client client
     158 */
     159void ds_display_remove_client(ds_client_t *client)
     160{
     161        list_remove(&client->lclients);
     162        client->display = NULL;
     163}
     164
     165/** Get first client in display.
    150166 *
    151167 * @param disp Display
    152  * @param id Window ID
    153  */
    154 ds_window_t *ds_display_find_window(ds_display_t *disp, ds_wnd_id_t id)
    155 {
    156         ds_window_t *wnd;
    157 
    158         // TODO Make this faster
    159         wnd = ds_display_first_window(disp);
    160         while (wnd != NULL) {
    161                 if (wnd->id == id)
    162                         return wnd;
    163                 wnd = ds_display_next_window(wnd);
    164         }
    165 
    166         return NULL;
    167 }
    168 
    169 /** Get first window in display.
    170  *
    171  * @param disp Display
    172  * @return First window or @c NULL if there is none
    173  */
    174 ds_window_t *ds_display_first_window(ds_display_t *disp)
    175 {
    176         link_t *link = list_first(&disp->windows);
     168 * @return First client or @c NULL if there is none
     169 */
     170ds_client_t *ds_display_first_client(ds_display_t *disp)
     171{
     172        link_t *link = list_first(&disp->clients);
    177173
    178174        if (link == NULL)
    179175                return NULL;
    180176
    181         return list_get_instance(link, ds_window_t, lwindows);
    182 }
    183 
    184 /** Get next window in display.
    185  *
    186  * @param wnd Current window
    187  * @return Next window or @c NULL if there is none
    188  */
    189 ds_window_t *ds_display_next_window(ds_window_t *wnd)
    190 {
    191         link_t *link = list_next(&wnd->lwindows, &wnd->display->windows);
     177        return list_get_instance(link, ds_client_t, lclients);
     178}
     179
     180/** Get next client in display.
     181 *
     182 * @param client Current client
     183 * @return Next client or @c NULL if there is none
     184 */
     185ds_client_t *ds_display_next_client(ds_client_t *client)
     186{
     187        link_t *link = list_next(&client->lclients, &client->display->clients);
    192188
    193189        if (link == NULL)
    194190                return NULL;
    195191
    196         return list_get_instance(link, ds_window_t, lwindows);
     192        return list_get_instance(link, ds_client_t, lclients);
     193}
     194
     195/** Find window in all clients by ID.
     196 *
     197 * XXX This is just a hack needed to match GC connection to a window,
     198 * as we don't have a good safe way to pass the GC endpoint to our client
     199 * on demand.
     200 *
     201 * @param display Display
     202 * @param id Window ID
     203 */
     204#include <stdio.h>
     205ds_window_t *ds_display_find_window(ds_display_t *display, ds_wnd_id_t id)
     206{
     207        ds_client_t *client;
     208        ds_window_t *wnd;
     209
     210        printf("ds_display_find_window: id=0x%lx\n", id);
     211
     212        client = ds_display_first_client(display);
     213        while (client != NULL) {
     214                printf("ds_display_find_window: client=%p\n", client);
     215                wnd = ds_client_find_window(client, id);
     216                if (wnd != NULL) {
     217                        printf("ds_display_find_window: found wnd=%p id=0x%lx\n",
     218                            wnd, wnd->id);
     219                        return wnd;
     220                }
     221                client = ds_display_next_client(client);
     222        }
     223
     224        printf("ds_display_find_window: not found\n");
     225        return NULL;
     226}
     227
     228errno_t ds_display_post_kbd_event(ds_display_t *display, kbd_event_t *event)
     229{
     230        ds_client_t *client;
     231        ds_window_t *wnd;
     232
     233        // XXX Correctly determine destination window
     234
     235        client = ds_display_first_client(display);
     236        if (client == NULL)
     237                return EOK;
     238
     239        wnd = ds_client_first_window(client);
     240        if (wnd == NULL)
     241                return EOK;
     242
     243        return ds_client_post_kbd_event(client, wnd, event);
    197244}
    198245
  • uspace/srv/hid/display/display.h

    r22faaf2 rb3c185b6  
    4141#include <errno.h>
    4242#include <gfx/context.h>
     43#include <io/kbd_event.h>
     44#include "types/display/client.h"
    4345#include "types/display/display.h"
    44 #include "types/display/window.h"
    4546
    4647extern display_ops_t display_srv_ops;
     
    4849extern errno_t ds_display_create(gfx_context_t *, ds_display_t **);
    4950extern void ds_display_destroy(ds_display_t *);
    50 extern errno_t ds_display_add_window(ds_display_t *, ds_window_t *);
    51 extern void ds_display_remove_window(ds_window_t *);
     51extern void ds_display_add_client(ds_display_t *, ds_client_t *);
     52extern void ds_display_remove_client(ds_client_t *);
     53extern ds_client_t *ds_display_first_client(ds_display_t *);
     54extern ds_client_t *ds_display_next_client(ds_client_t *);
    5255extern ds_window_t *ds_display_find_window(ds_display_t *, ds_wnd_id_t);
    53 extern ds_window_t *ds_display_first_window(ds_display_t *);
    54 extern ds_window_t *ds_display_next_window(ds_window_t *);
     56extern errno_t ds_display_post_kbd_event(ds_display_t *, kbd_event_t *);
    5557
    5658#endif
  • uspace/srv/hid/display/main.c

    r22faaf2 rb3c185b6  
    4545#include <stdio.h>
    4646#include <task.h>
     47#include "client.h"
    4748#include "display.h"
     49#include "main.h"
    4850#include "output.h"
    4951#include "window.h"
    5052
    51 #define NAME  "display"
     53static void display_client_conn(ipc_call_t *, void *);
    5254
    53 static void display_client_conn(ipc_call_t *, void *);
     55static void display_kbd_event(void *arg, kbd_event_t *event)
     56{
     57        ds_display_t *disp = (ds_display_t *) arg;
     58
     59        printf("display_kbd_event\n");
     60        ds_display_post_kbd_event(disp, event);
     61}
    5462
    5563/** Initialize display server */
     
    6068        errno_t rc;
    6169
    62         rc = output_init(&gc);
     70        log_msg(LOG_DEFAULT, LVL_DEBUG, "display_srv_init()");
     71
     72        rc = ds_display_create(NULL, &disp);
    6373        if (rc != EOK)
    6474                goto error;
    6575
    66         rc = ds_display_create(gc, &disp);
     76        rc = output_init(display_kbd_event, (void *) disp, &gc);
    6777        if (rc != EOK)
    6878                goto error;
    6979
    70         log_msg(LOG_DEFAULT, LVL_DEBUG, "display_srv_init()");
    71 
     80        disp->gc = gc;
     81#if 0
     82        rc = ds_input_open(disp);
     83        if (rc != EOK)
     84                goto error;
     85#endif
    7286        async_set_fallback_port_handler(display_client_conn, disp);
    7387
     
    88102        return EOK;
    89103error:
     104#if 0
     105        if (disp->input != NULL)
     106                ds_input_close(disp);
     107#endif
    90108        if (gc != NULL)
    91109                gfx_context_delete(gc);
     
    101119        sysarg_t wnd_id;
    102120        sysarg_t svc_id;
     121        ds_client_t *client = NULL;
    103122        ds_window_t *wnd;
    104123        ds_display_t *disp = (ds_display_t *) arg;
    105124        gfx_context_t *gc;
     125        errno_t rc;
    106126
    107127        log_msg(LOG_DEFAULT, LVL_NOTE, "display_client_conn arg1=%zu arg2=%zu arg3=%zu arg4=%zu.",
     
    116136
    117137        if (svc_id != 0) {
    118                 /* Display management */
     138                /* Create client object */
     139                rc = ds_client_create(disp, &srv, &client);
     140                if (rc != EOK) {
     141                        async_answer_0(icall, ENOMEM);
     142                        return;
     143                }
     144
     145                /* Set up protocol structure */
    119146                srv.ops = &display_srv_ops;
    120                 srv.arg = disp;
     147                srv.arg = client;
    121148
     149                /* Handle connection */
    122150                display_conn(icall, &srv);
     151
     152                ds_client_destroy(client);
    123153        } else {
    124                 /* Window GC */
     154                /* Window GC connection */
     155
    125156                wnd = ds_display_find_window(disp, wnd_id);
    126157                if (wnd == NULL) {
     
    132163                gc_conn(icall, gc);
    133164        }
     165
    134166}
    135167
  • uspace/srv/hid/display/meson.build

    r22faaf2 rb3c185b6  
    3030
    3131src = files(
     32        'client.c',
    3233        'display.c',
    3334        'main.c',
     
    3738
    3839test_src = files(
     40        'client.c',
    3941        'display.c',
    4042        'window.c',
  • uspace/srv/hid/display/output.c

    r22faaf2 rb3c185b6  
    4242#include "output.h"
    4343
    44 errno_t output_init(gfx_context_t **rgc)
     44static void (*kbd_ev_handler)(void *, kbd_event_t *);
     45static void *kbd_ev_arg;
     46
     47static void on_keyboard_event(widget_t *widget, void *data)
     48{
     49        printf("Keyboard event\n");
     50        kbd_ev_handler(kbd_ev_arg, (kbd_event_t *) data);
     51}
     52
     53errno_t output_init(void (*kbd_event_handler)(void *, kbd_event_t *),
     54    void *arg, gfx_context_t **rgc)
    4555{
    4656        canvas_gc_t *cgc = NULL;
     
    5363
    5464        printf("Init canvas..\n");
     65        kbd_ev_handler = kbd_event_handler;
     66        kbd_ev_arg = arg;
    5567
    5668        window = window_open("comp:0/winreg", NULL,
     
    8395        }
    8496
     97        sig_connect(&canvas->keyboard_event, NULL, on_keyboard_event);
     98
    8599        window_resize(window, 0, 0, vw + 10, vh + 30, WINDOW_PLACEMENT_ANY);
    86100        window_exec(window);
  • uspace/srv/hid/display/output.h

    r22faaf2 rb3c185b6  
    3939#include <gfx/context.h>
    4040
    41 extern errno_t output_init(gfx_context_t **);
     41extern errno_t output_init(void (*)(void *, kbd_event_t *), void *,
     42    gfx_context_t **);
    4243
    4344#endif
  • uspace/srv/hid/display/test/display.c

    r22faaf2 rb3c185b6  
    3232#include <str.h>
    3333
     34#include "../client.h"
    3435#include "../display.h"
    35 #include "../window.h"
    3636
    3737PCUT_INIT;
     
    5151}
    5252
    53 /** Basic window operation. */
    54 PCUT_TEST(display_window)
     53/** Basic client operation. */
     54PCUT_TEST(display_client)
    5555{
    5656        ds_display_t *disp;
    57         ds_window_t *wnd;
    58         ds_window_t *w0, *w1, *w2;
     57        ds_client_t *client;
     58        ds_client_t *c0, *c1;
    5959        errno_t rc;
    6060
     
    6262        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    6363
    64         rc = ds_window_create(disp, &wnd);
     64        rc = ds_client_create(disp, NULL, &client);
    6565        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    6666
    67         w0 = ds_display_first_window(disp);
    68         PCUT_ASSERT_EQUALS(w0, wnd);
     67        c0 = ds_display_first_client(disp);
     68        PCUT_ASSERT_EQUALS(c0, client);
    6969
    70         w1 = ds_display_next_window(w0);
    71         PCUT_ASSERT_NULL(w1);
     70        c1 = ds_display_next_client(c0);
     71        PCUT_ASSERT_NULL(c1);
    7272
    73         w2 = ds_display_find_window(disp, wnd->id);
    74         PCUT_ASSERT_EQUALS(w2, wnd);
    75 
    76         ds_window_delete(wnd);
     73        ds_client_destroy(client);
    7774        ds_display_destroy(disp);
    7875}
  • uspace/srv/hid/display/test/window.c

    r22faaf2 rb3c185b6  
    3232#include <str.h>
    3333
    34 #include "../display.h"
     34#include "../client.h"
    3535#include "../window.h"
    3636
     
    4242PCUT_TEST(window_get_ctx)
    4343{
    44         ds_display_t *disp;
     44        ds_client_t *client;
    4545        ds_window_t *wnd;
    4646        gfx_context_t *gc;
    4747        errno_t rc;
    4848
    49         rc = ds_display_create(NULL, &disp);
     49        rc = ds_client_create(NULL, NULL, &client);
    5050        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    5151
    52         rc = ds_window_create(disp, &wnd);
     52        rc = ds_window_create(client, &wnd);
    5353        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    5454
     
    5757
    5858        ds_window_delete(wnd);
    59         ds_display_destroy(disp);
     59        ds_client_destroy(client);
    6060}
    6161
  • uspace/srv/hid/display/types/display/display.h

    r22faaf2 rb3c185b6  
    2727 */
    2828
    29 /** @addtogroup libipcgfx
     29/** @addtogroup display
    3030 * @{
    3131 */
     
    3939#include <adt/list.h>
    4040#include <gfx/context.h>
     41#include <io/input.h>
    4142#include "window.h"
    4243
     44/** Display server display */
    4345typedef struct ds_display {
    44         /** Windows (of ds_window_t) */
    45         list_t windows;
    46         /** Next ID to assign to a window */
    47         ds_wnd_id_t next_wnd_id;
     46        /** Clients (of ds_client_t) */
     47        list_t clients;
    4848        /** Output GC */
    4949        gfx_context_t *gc;
     50
     51        /** Next ID to assign to a window.
     52         *
     53         * XXX Window IDs need to be unique per display just because
     54         * we don't have a way to match GC connection to the proper
     55         * client. Really this should be in ds_client_t and the ID
     56         * space should be per client.
     57         */
     58        ds_wnd_id_t next_wnd_id;
     59        /** Input service */
     60        input_t *input;
    5061} ds_display_t;
    5162
  • uspace/srv/hid/display/types/display/window.h

    r22faaf2 rb3c185b6  
    2727 */
    2828
    29 /** @addtogroup libipcgfx
     29/** @addtogroup display
    3030 * @{
    3131 */
     
    3838
    3939#include <adt/list.h>
     40#include <display/event.h>
    4041#include <gfx/context.h>
    4142#include <gfx/coord.h>
     
    4546/** Display server window */
    4647typedef struct ds_window {
    47         /** Parent display */
    48         struct ds_display *display;
    49         /** Link to @c display->windows */
     48        /** Parent client */
     49        struct ds_client *client;
     50        /** Link to @c client->windows */
    5051        link_t lwindows;
    5152        /** Display position */
     
    5657        gfx_context_t *gc;
    5758} ds_window_t;
     59
     60/** Window event queue entry */
     61typedef struct {
     62        /** Link to event queue */
     63        link_t levents;
     64        /** Window to which the event is delivered */
     65        ds_window_t *window;
     66        /** Event */
     67        display_wnd_ev_t event;
     68} ds_window_ev_t;
    5869
    5970/** Bitmap in display server window GC */
  • uspace/srv/hid/display/window.c

    r22faaf2 rb3c185b6  
    4343#include <io/log.h>
    4444#include <stdlib.h>
     45#include "client.h"
    4546#include "display.h"
    4647#include "window.h"
     
    7677        ds_window_t *wnd = (ds_window_t *) arg;
    7778
    78         log_msg(LOG_DEFAULT, LVL_NOTE, "gc_set_color");
    79         return gfx_set_color(wnd->display->gc, color);
     79        log_msg(LOG_DEFAULT, LVL_NOTE, "gc_set_color gc=%p", wnd->client->display->gc);
     80        return gfx_set_color(wnd->client->display->gc, color);
    8081}
    8182
     
    9495        log_msg(LOG_DEFAULT, LVL_NOTE, "gc_fill_rect");
    9596        gfx_rect_translate(&wnd->dpos, rect, &drect);
    96         return gfx_fill_rect(wnd->display->gc, &drect);
     97        return gfx_fill_rect(wnd->client->display->gc, &drect);
    9798}
    9899
     
    116117                return ENOMEM;
    117118
    118         rc = gfx_bitmap_create(wnd->display->gc, params, alloc, &cbm->bitmap);
     119        rc = gfx_bitmap_create(wnd->client->display->gc, params, alloc,
     120            &cbm->bitmap);
    119121        if (rc != EOK)
    120122                goto error;
     
    181183 * Create graphics context for rendering into a window.
    182184 *
    183  * @param disp Display to create window on
     185 * @param client Client owning the window
    184186 * @param rgc Place to store pointer to new GC.
    185187 *
    186188 * @return EOK on success or an error code
    187189 */
    188 errno_t ds_window_create(ds_display_t *disp, ds_window_t **rgc)
     190errno_t ds_window_create(ds_client_t *client, ds_window_t **rgc)
    189191{
    190192        ds_window_t *wnd = NULL;
     
    202204                goto error;
    203205
    204         ds_display_add_window(disp, wnd);
     206        ds_client_add_window(client, wnd);
    205207
    206208        wnd->gc = gc;
     
    222224        errno_t rc;
    223225
    224         ds_display_remove_window(wnd);
     226        ds_client_remove_window(wnd);
    225227
    226228        rc = gfx_context_delete(wnd->gc);
  • uspace/srv/hid/display/window.h

    r22faaf2 rb3c185b6  
    3737#define WINDOW_H
    3838
     39#include <display/event.h>
    3940#include <errno.h>
    4041#include <types/gfx/context.h>
     
    4546extern gfx_context_ops_t window_gc_ops;
    4647
    47 extern errno_t ds_window_create(ds_display_t *, ds_window_t **);
     48extern errno_t ds_window_create(ds_client_t *, ds_window_t **);
    4849extern errno_t ds_window_delete(ds_window_t *);
    4950extern gfx_context_t *ds_window_get_ctx(ds_window_t *);
Note: See TracChangeset for help on using the changeset viewer.