Changeset b3c185b6 in mainline for uspace/lib/display/src/display.c
- Timestamp:
- 2019-11-04T14:05:35Z (4 years ago)
- 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)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/display/src/display.c
r22faaf2 rb3c185b6 30 30 #include <display.h> 31 31 #include <errno.h> 32 #include <fibril_synch.h> 32 33 #include <ipc/display.h> 33 34 #include <ipc/services.h> … … 36 37 #include <stdlib.h> 37 38 39 static errno_t display_callback_create(display_t *); 40 static void display_cb_conn(ipc_call_t *, void *); 41 static errno_t display_get_window(display_t *, sysarg_t, display_window_t **); 42 38 43 /** Open display service. 39 44 * … … 51 56 if (display == NULL) 52 57 return ENOMEM; 58 59 list_initialize(&display->windows); 53 60 54 61 if (dsname == NULL) … … 68 75 } 69 76 77 rc = display_callback_create(display); 78 if (rc != EOK) { 79 async_hangup(display->sess); 80 free(display); 81 return EIO; 82 } 83 70 84 *rdisplay = display; 71 85 return EOK; 72 86 } 73 87 88 /** Create callback connection from display service. 89 * 90 * @param display Display session 91 * @return EOK on success or an error code 92 */ 93 static 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 74 114 /** Close display service. 75 115 * … … 79 119 { 80 120 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 81 129 free(display); 82 130 } … … 85 133 * 86 134 * @param display Display 135 * @param cb Callback functions 136 * @param cb_arg Argument to callback functions 87 137 * @param rwindow Place to store pointer to new window 88 138 * @return EOK on success or an error code 89 139 */ 90 errno_t display_window_create(display_t *display, display_window_t **rwindow) 140 errno_t display_window_create(display_t *display, display_wnd_cb_t *cb, 141 void *cb_arg, display_window_t **rwindow) 91 142 { 92 143 display_window_t *window; … … 111 162 window->display = display; 112 163 window->id = wnd_id; 164 window->cb = cb; 165 window->cb_arg = cb_arg; 166 167 list_append(&window->lwindows, &display->windows); 113 168 *rwindow = window; 114 169 return EOK; … … 166 221 } 167 222 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 */ 230 static 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 */ 268 static 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 */ 291 static 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 315 out: 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 */ 329 static 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 168 349 /** @} 169 350 */
Note:
See TracChangeset
for help on using the changeset viewer.