Changeset b3c185b6 in mainline for uspace/lib/display/src


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/lib/display/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • 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 */
Note: See TracChangeset for help on using the changeset viewer.