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

Changeset b3c185b6 in mainline


Ignore:
Timestamp:
2019-11-04T14:05:35Z (16 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
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

Files:
6 added
20 edited

Legend:

Unmodified
Added
Removed
  • abi/include/abi/ipc/interfaces.h

    r22faaf2 rb3c185b6  
    190190        INTERFACE_DISPLAY =
    191191            FOURCC_COMPACT('d', 's', 'p', 'l') | IFACE_EXCHANGE_SERIALIZE,
     192        INTERFACE_DISPLAY_CB =
     193            FOURCC_COMPACT('d', 's', 'p', 'l') | IFACE_EXCHANGE_SERIALIZE | IFACE_MOD_CALLBACK,
    192194        INTERFACE_GC =
    193195            FOURCC_COMPACT('g', 'f', 'x', 'c') | IFACE_EXCHANGE_SERIALIZE,
  • uspace/app/gfxdemo/gfxdemo.c

    r22faaf2 rb3c185b6  
    4444#include <io/console.h>
    4545#include <io/pixelmap.h>
     46#include <stdbool.h>
    4647#include <stdlib.h>
    4748#include <str.h>
    4849#include <window.h>
     50
     51static void wnd_kbd_event(void *, kbd_event_t *);
     52
     53static display_wnd_cb_t wnd_cb = {
     54        .kbd_event = wnd_kbd_event
     55};
     56
     57static bool quit = false;
    4958
    5059/** Clear screen.
     
    126135
    127136                fibril_usleep(500 * 1000);
     137
     138                if (quit)
     139                        break;
    128140        }
    129141
     
    245257                                goto error;
    246258                        fibril_usleep(250 * 1000);
     259
     260                        if (quit)
     261                                break;
    247262                }
    248263        }
     
    298313
    299314                fibril_usleep(500 * 1000);
     315
     316                if (quit)
     317                        break;
    300318        }
    301319
     
    318336        errno_t rc;
    319337
    320         while (true) {
     338        while (!quit) {
    321339                rc = demo_rects(gc, w, h);
    322340                if (rc != EOK)
     
    331349                        return rc;
    332350        }
     351
     352        return EOK;
    333353}
    334354
     
    444464        }
    445465
    446         rc = display_window_create(display, &window);
     466        rc = display_window_create(display, &wnd_cb, NULL, &window);
    447467        if (rc != EOK) {
    448468                printf("Error creating window.\n");
     
    464484
    465485        return EOK;
     486}
     487
     488static void wnd_kbd_event(void *arg, kbd_event_t *event)
     489{
     490        printf("Keyboard event type=%d key=%d\n", event->type, event->key);
     491        quit = true;
    466492}
    467493
  • uspace/lib/display/include/disp_srv.h

    r22faaf2 rb3c185b6  
    3838#include <async.h>
    3939#include <errno.h>
     40#include <types/display/event.h>
    4041
    4142typedef struct display_ops display_ops_t;
     
    5152        errno_t (*window_create)(void *, sysarg_t *);
    5253        errno_t (*window_destroy)(void *, sysarg_t);
     54        errno_t (*get_event)(void *, sysarg_t *, display_wnd_ev_t *);
    5355};
    5456
    5557extern void display_conn(ipc_call_t *, display_srv_t *);
     58extern void display_srv_ev_pending(display_srv_t *);
    5659
    5760#endif
  • uspace/lib/display/include/display.h

    r22faaf2 rb3c185b6  
    4343extern errno_t display_open(const char *, display_t **);
    4444extern void display_close(display_t *);
    45 extern errno_t display_window_create(display_t *, display_window_t **);
     45extern errno_t display_window_create(display_t *, display_wnd_cb_t *,
     46    void *, display_window_t **);
    4647extern errno_t display_window_destroy(display_window_t *);
    4748extern errno_t display_window_get_gc(display_window_t *, gfx_context_t **);
  • uspace/lib/display/include/ipc/display.h

    r22faaf2 rb3c185b6  
    3939
    4040typedef enum {
    41         DISPLAY_WINDOW_CREATE = IPC_FIRST_USER_METHOD,
     41        DISPLAY_CALLBACK_CREATE = IPC_FIRST_USER_METHOD,
     42        DISPLAY_WINDOW_CREATE,
    4243        DISPLAY_WINDOW_DESTROY,
    43         DISPLAY_WINDOW_GC
     44        DISPLAY_GET_EVENT
    4445} display_request_t;
     46
     47typedef enum {
     48        DISPLAY_EV_PENDING = IPC_FIRST_USER_METHOD
     49} display_event_t;
    4550
    4651#endif
  • uspace/lib/display/include/types/display.h

    r22faaf2 rb3c185b6  
    3737
    3838#include <async.h>
     39#include <fibril_synch.h>
     40#include <io/kbd_event.h>
    3941#include <ipc/devman.h>
    4042#include <stdint.h>
     
    4446        /** Session with display server */
    4547        async_sess_t *sess;
     48        /** Synchronize access to display object */
     49        fibril_mutex_t lock;
     50        /** @c true if callback handler terminated */
     51        bool cb_done;
     52        /** Signalled when cb_done or ev_pending is changed */
     53        fibril_condvar_t cv;
     54        /** Windows (of display_window_t) */
     55        list_t windows;
    4656} display_t;
     57
     58/** Display window callbacks */
     59typedef struct {
     60        void (*kbd_event)(void *, kbd_event_t *);
     61} display_wnd_cb_t;
     62
     63typedef struct {
     64        kbd_event_t kbd_event;
     65} display_wnd_ev_t;
    4766
    4867/** Display window */
     
    5069        /** Display associated with the window */
    5170        display_t *display;
     71        /** Link to @c display->windows */
     72        link_t lwindows;
    5273        /** Window ID */
    5374        sysarg_t id;
     75        /** Callback functions */
     76        display_wnd_cb_t *cb;
     77        /** Argument to callback functions */
     78        void *cb_arg;
    5479} display_window_t;
    5580
  • uspace/lib/display/src/disp_srv.c

    r22faaf2 rb3c185b6  
    3636
    3737#include <disp_srv.h>
     38#include <display/event.h>
    3839#include <errno.h>
     40#include <io/log.h>
    3941#include <ipc/display.h>
    4042#include <stdlib.h>
    4143#include <stddef.h>
     44
     45#include <stdio.h>
     46static void display_callback_create_srv(display_srv_t *srv, ipc_call_t *call)
     47{
     48        printf("display_callback_create_srv\n");
     49
     50        async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
     51        if (sess == NULL) {
     52                async_answer_0(call, ENOMEM);
     53                return;
     54        }
     55
     56        srv->client_sess = sess;
     57        async_answer_0(call, EOK);
     58}
    4259
    4360static void display_window_create_srv(display_srv_t *srv, ipc_call_t *icall)
     
    4562        sysarg_t wnd_id;
    4663        errno_t rc;
     64
     65        printf("display_window_create_srv\n");
    4766
    4867        if (srv->ops->window_create == NULL) {
     
    6079        errno_t rc;
    6180
     81        printf("display_window_destroy_srv\n");
     82
    6283        wnd_id = ipc_get_arg1(icall);
    6384
     
    7192}
    7293
     94static void display_get_event_srv(display_srv_t *srv, ipc_call_t *icall)
     95{
     96        sysarg_t wnd_id;
     97        display_wnd_ev_t event;
     98        ipc_call_t call;
     99        size_t size;
     100        errno_t rc;
     101
     102        printf("display_get_event_srv\n");
     103
     104        if (srv->ops->get_event == NULL) {
     105                async_answer_0(icall, ENOTSUP);
     106                return;
     107        }
     108
     109        rc = srv->ops->get_event(srv->arg, &wnd_id, &event);
     110        if (rc != EOK)
     111                async_answer_0(icall, rc);
     112
     113        /* Transfer event data */
     114        if (!async_data_read_receive(&call, &size)) {
     115                async_answer_0(icall, EREFUSED);
     116                return;
     117        }
     118
     119        if (size != sizeof(event)) {
     120                async_answer_0(icall, EREFUSED);
     121                async_answer_0(&call, EREFUSED);
     122                return;
     123        }
     124
     125        rc = async_data_read_finalize(&call, &event, sizeof(event));
     126        if (rc != EOK) {
     127                async_answer_0(icall, rc);
     128                async_answer_0(&call, rc);
     129                return;
     130        }
     131
     132        async_answer_1(icall, EOK, wnd_id);
     133}
     134
    73135void display_conn(ipc_call_t *icall, display_srv_t *srv)
    74136{
    75137        /* Accept the connection */
    76138        async_accept_0(icall);
     139        printf("display_conn\n");
    77140
    78141        while (true) {
     
    88151                }
    89152
     153                printf("display_conn method=%lu\n", method);
    90154                switch (method) {
     155                case DISPLAY_CALLBACK_CREATE:
     156                        display_callback_create_srv(srv, &call);
     157                        break;
    91158                case DISPLAY_WINDOW_CREATE:
    92159                        display_window_create_srv(srv, &call);
     
    94161                case DISPLAY_WINDOW_DESTROY:
    95162                        display_window_destroy_srv(srv, &call);
     163                        break;
     164                case DISPLAY_GET_EVENT:
     165                        display_get_event_srv(srv, &call);
    96166                        break;
    97167                default:
     
    101171}
    102172
     173/** Send 'pending' event to client.
     174 *
     175 * @param srv Display server structure
     176 */
     177void display_srv_ev_pending(display_srv_t *srv)
     178{
     179        async_exch_t *exch;
     180
     181        printf("display_srv_ev_pending()\n");
     182
     183        exch = async_exchange_begin(srv->client_sess);
     184        async_msg_0(exch, DISPLAY_EV_PENDING);
     185        async_exchange_end(exch);
     186}
     187
    103188/** @}
    104189 */
  • uspace/lib/display/src/display.c

    r22faaf2 rb3c185b6  
    3030#include <display.h>
    3131#include <errno.h>
     32#include <fibril_synch.h>
    3233#include <ipc/display.h>
    3334#include <ipc/services.h>
     
    3637#include <stdlib.h>
    3738
     39static errno_t display_callback_create(display_t *);
     40static void display_cb_conn(ipc_call_t *, void *);
     41static errno_t display_get_window(display_t *, sysarg_t, display_window_t **);
     42
    3843/** Open display service.
    3944 *
     
    5156        if (display == NULL)
    5257                return ENOMEM;
     58
     59        list_initialize(&display->windows);
    5360
    5461        if (dsname == NULL)
     
    6875        }
    6976
     77        rc = display_callback_create(display);
     78        if (rc != EOK) {
     79                async_hangup(display->sess);
     80                free(display);
     81                return EIO;
     82        }
     83
    7084        *rdisplay = display;
    7185        return EOK;
    7286}
    7387
     88/** Create callback connection from display service.
     89 *
     90 * @param display Display session
     91 * @return EOK on success or an error code
     92 */
     93static errno_t display_callback_create(display_t *display)
     94{
     95        async_exch_t *exch = async_exchange_begin(display->sess);
     96
     97        aid_t req = async_send_0(exch, DISPLAY_CALLBACK_CREATE, NULL);
     98
     99        port_id_t port;
     100        errno_t rc = async_create_callback_port(exch, INTERFACE_DISPLAY_CB, 0, 0,
     101            display_cb_conn, display, &port);
     102
     103        async_exchange_end(exch);
     104
     105        if (rc != EOK)
     106                return rc;
     107
     108        errno_t retval;
     109        async_wait_for(req, &retval);
     110
     111        return retval;
     112}
     113
    74114/** Close display service.
    75115 *
     
    79119{
    80120        async_hangup(display->sess);
     121
     122        /* Wait for callback handler to terminate */
     123
     124        fibril_mutex_lock(&display->lock);
     125        while (!display->cb_done)
     126                fibril_condvar_wait(&display->cv, &display->lock);
     127        fibril_mutex_unlock(&display->lock);
     128
    81129        free(display);
    82130}
     
    85133 *
    86134 * @param display Display
     135 * @param cb Callback functions
     136 * @param cb_arg Argument to callback functions
    87137 * @param rwindow Place to store pointer to new window
    88138 * @return EOK on success or an error code
    89139 */
    90 errno_t display_window_create(display_t *display, display_window_t **rwindow)
     140errno_t display_window_create(display_t *display, display_wnd_cb_t *cb,
     141    void *cb_arg, display_window_t **rwindow)
    91142{
    92143        display_window_t *window;
     
    111162        window->display = display;
    112163        window->id = wnd_id;
     164        window->cb = cb;
     165        window->cb_arg = cb_arg;
     166
     167        list_append(&window->lwindows, &display->windows);
    113168        *rwindow = window;
    114169        return EOK;
     
    166221}
    167222
     223/** Get display event.
     224 *
     225 * @param display Display
     226 * @param rwindow Place to store pointe to window that received event
     227 * @param event Place to store event
     228 * @return EOK on success or an error code
     229 */
     230static errno_t display_get_event(display_t *display, display_window_t **rwindow,
     231    display_wnd_ev_t *event)
     232{
     233        async_exch_t *exch;
     234        ipc_call_t answer;
     235        aid_t req;
     236        errno_t rc;
     237        sysarg_t wnd_id;
     238        display_window_t *window;
     239
     240        exch = async_exchange_begin(display->sess);
     241        req = async_send_0(exch, DISPLAY_GET_EVENT, &answer);
     242        rc = async_data_read_start(exch, event, sizeof(*event));
     243        if (rc != EOK) {
     244                async_forget(req);
     245                return rc;
     246        }
     247
     248        async_exchange_end(exch);
     249
     250        async_wait_for(req, &rc);
     251        if (rc != EOK)
     252                return rc;
     253
     254        wnd_id = ipc_get_arg1(&answer);
     255        rc = display_get_window(display, wnd_id, &window);
     256        if (rc != EOK)
     257                return EIO;
     258
     259        *rwindow = window;
     260        return EOK;
     261}
     262
     263/** Display events are pending.
     264 *
     265 * @param display Display
     266 * @param icall Call data
     267 */
     268static void display_ev_pending(display_t *display, ipc_call_t *icall)
     269{
     270        errno_t rc;
     271        display_window_t *window = NULL;
     272        display_wnd_ev_t event;
     273
     274        while (true) {
     275                rc = display_get_event(display, &window, &event);
     276                if (rc != EOK)
     277                        break;
     278
     279                if (window->cb->kbd_event != NULL)
     280                        window->cb->kbd_event(window->cb_arg, &event.kbd_event);
     281        }
     282
     283        async_answer_0(icall, EOK);
     284}
     285
     286/** Callback connection handler.
     287 *
     288 * @param icall Connect call data
     289 * @param arg   Argument, display_t *
     290 */
     291static void display_cb_conn(ipc_call_t *icall, void *arg)
     292{
     293        display_t *display = (display_t *) arg;
     294
     295        while (true) {
     296                ipc_call_t call;
     297                async_get_call(&call);
     298
     299                if (!ipc_get_imethod(&call)) {
     300                        /* Hangup */
     301                        async_answer_0(&call, EOK);
     302                        goto out;
     303                }
     304
     305                switch (ipc_get_imethod(&call)) {
     306                case DISPLAY_EV_PENDING:
     307                        display_ev_pending(display, &call);
     308                        break;
     309                default:
     310                        async_answer_0(&call, ENOTSUP);
     311                        break;
     312                }
     313        }
     314
     315out:
     316        fibril_mutex_lock(&display->lock);
     317        display->cb_done = true;
     318        fibril_mutex_unlock(&display->lock);
     319        fibril_condvar_broadcast(&display->cv);
     320}
     321
     322/** Find window by ID.
     323 *
     324 * @param display Display
     325 * @param wnd_id Window ID
     326 * @param rwindow Place to store pointer to window
     327 * @return EOK on success, ENOENT if not found
     328 */
     329static errno_t display_get_window(display_t *display, sysarg_t wnd_id,
     330    display_window_t **rwindow)
     331{
     332        link_t *link;
     333        display_window_t *window;
     334
     335        link = list_first(&display->windows);
     336        while (link != NULL) {
     337                window = list_get_instance(link, display_window_t, lwindows);
     338                if (window->id == wnd_id) {
     339                        *rwindow = window;
     340                        return EOK;
     341                }
     342
     343                link = list_next(link, &display->windows);
     344        }
     345
     346        return ENOENT;
     347}
     348
    168349/** @}
    169350 */
  • 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.