Changes in uspace/lib/ui/src/ui.c [899bdfd:3d10a2f] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified uspace/lib/ui/src/ui.c ¶
r899bdfd r3d10a2f 1 1 /* 2 * Copyright (c) 202 3Jiri Svoboda2 * Copyright (c) 2021 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 39 39 #include <errno.h> 40 40 #include <fibril.h> 41 #include <fibril_synch.h>42 41 #include <gfx/color.h> 43 #include <gfx/cursor.h>44 42 #include <gfx/render.h> 45 43 #include <io/console.h> … … 48 46 #include <str.h> 49 47 #include <task.h> 50 #include <types/common.h>51 #include <ui/clickmatic.h>52 48 #include <ui/ui.h> 53 49 #include <ui/wdecor.h> 54 50 #include <ui/window.h> 55 #include "../private/wdecor.h"56 51 #include "../private/window.h" 57 52 #include "../private/ui.h" … … 66 61 * @param ws Place to store window system type (protocol) 67 62 * @param osvc Place to store pointer to output service name 68 * @param ridev_id Place to store input device ID 69 * @return EOK on success, EINVAL if syntax is invalid, ENOMEM if out of 70 * memory 71 */ 72 static errno_t ui_ospec_parse(const char *ospec, ui_winsys_t *ws, 73 char **osvc, sysarg_t *ridev_id) 63 */ 64 static void ui_ospec_parse(const char *ospec, ui_winsys_t *ws, 65 const char **osvc) 74 66 { 75 67 const char *cp; 76 const char *qm; 77 const char *endptr;78 uint64_t idev_id;79 errno_t rc;80 81 *ridev_id = 0;68 69 if (ospec == UI_DISPLAY_DEFAULT) { 70 *ws = ui_ws_display; 71 *osvc = DISPLAY_DEFAULT; 72 return; 73 } 82 74 83 75 cp = ospec; … … 85 77 ++cp; 86 78 87 /* Window system / protocol */88 79 if (*cp == '@') { 89 80 if (str_lcmp(ospec, "disp@", str_length("disp@")) == 0) { … … 93 84 } else if (str_lcmp(ospec, "null@", str_length("null@")) == 0) { 94 85 *ws = ui_ws_null; 95 } else if (str_lcmp(ospec, "@", str_length("@")) == 0) {96 *ws = ui_ws_any;97 86 } else { 98 87 *ws = ui_ws_unknown; 99 88 } 100 89 101 ++cp; 90 if (cp[1] != '\0') 91 *osvc = cp + 1; 92 else 93 *osvc = NULL; 102 94 } else { 103 95 *ws = ui_ws_display; 104 } 105 106 /* Output service is the part before question mark */ 107 qm = str_chr(cp, '?'); 108 if (qm != NULL) { 109 *osvc = str_ndup(cp, qm - cp); 110 } else { 111 /* No question mark */ 112 *osvc = str_dup(cp); 113 } 114 115 if (*osvc == NULL) 116 return ENOMEM; 117 118 if (qm != NULL) { 119 /* The part after the question mark */ 120 cp = qm + 1; 121 122 /* Input device ID parameter */ 123 if (str_lcmp(cp, "idev=", str_length("idev=")) == 0) { 124 cp += str_length("idev="); 125 126 rc = str_uint64_t(cp, &endptr, 10, false, &idev_id); 127 if (rc != EOK) 128 goto error; 129 130 *ridev_id = idev_id; 131 cp = endptr; 132 } 133 } 134 135 if (*cp != '\0') { 136 rc = EINVAL; 137 goto error; 138 } 139 140 return EOK; 141 error: 142 free(*osvc); 143 *osvc = NULL; 144 return rc; 96 *osvc = ospec; 97 } 145 98 } 146 99 … … 161 114 console_gc_t *cgc; 162 115 ui_winsys_t ws; 163 c har *osvc;116 const char *osvc; 164 117 sysarg_t cols; 165 118 sysarg_t rows; 166 sysarg_t idev_id;167 119 ui_t *ui; 168 120 169 rc = ui_ospec_parse(ospec, &ws, &osvc, &idev_id); 170 if (rc != EOK) 171 return rc; 172 173 if (ws == ui_ws_display || ws == ui_ws_any) { 174 rc = display_open((str_cmp(osvc, "") != 0) ? osvc : 175 DISPLAY_DEFAULT, &display); 121 ui_ospec_parse(ospec, &ws, &osvc); 122 123 if (ws == ui_ws_display) { 124 rc = display_open(osvc, &display); 176 125 if (rc != EOK) 177 goto disp_fail;126 return rc; 178 127 179 128 rc = ui_create_disp(display, &ui); 180 129 if (rc != EOK) { 181 130 display_close(display); 182 goto disp_fail; 183 } 184 185 free(osvc); 186 ui->myoutput = true; 187 ui->idev_id = idev_id; 188 *rui = ui; 189 return EOK; 190 } 191 192 disp_fail: 193 if (ws == ui_ws_console || ws == ui_ws_any) { 131 return rc; 132 } 133 } else if (ws == ui_ws_console) { 194 134 console = console_init(stdin, stdout); 195 135 if (console == NULL) 196 goto cons_fail;136 return EIO; 197 137 198 138 rc = console_get_size(console, &cols, &rows); 199 139 if (rc != EOK) { 200 140 console_done(console); 201 goto cons_fail;141 return rc; 202 142 } 203 143 … … 208 148 if (rc != EOK) { 209 149 console_done(console); 210 goto cons_fail;150 return rc; 211 151 } 212 152 … … 215 155 ui_destroy(ui); 216 156 console_done(console); 217 goto cons_fail; 218 } 219 220 free(osvc); 157 return rc; 158 } 221 159 222 160 ui->cgc = cgc; … … 227 165 228 166 (void) ui_paint(ui); 229 ui->myoutput = true; 230 *rui = ui; 231 return EOK; 232 } 233 234 cons_fail: 235 if (ws == ui_ws_null) { 236 free(osvc); 167 } else if (ws == ui_ws_null) { 237 168 rc = ui_create_disp(NULL, &ui); 238 169 if (rc != EOK) 239 170 return rc; 240 241 ui->myoutput = true; 242 *rui = ui; 243 return EOK; 244 } 245 246 free(osvc); 247 return EINVAL; 171 } else { 172 return EINVAL; 173 } 174 175 ui->myoutput = true; 176 *rui = ui; 177 return EOK; 248 178 } 249 179 … … 256 186 { 257 187 ui_t *ui; 258 errno_t rc;259 188 260 189 ui = calloc(1, sizeof(ui_t)); … … 262 191 return ENOMEM; 263 192 264 rc = ui_clickmatic_create(ui, &ui->clickmatic);265 if (rc != EOK) {266 free(ui);267 return rc;268 }269 270 193 ui->console = console; 271 194 list_initialize(&ui->windows); 272 fibril_mutex_initialize(&ui->lock);273 195 *rui = ui; 274 196 return EOK; … … 284 206 { 285 207 ui_t *ui; 286 errno_t rc;287 208 288 209 ui = calloc(1, sizeof(ui_t)); … … 290 211 return ENOMEM; 291 212 292 rc = ui_clickmatic_create(ui, &ui->clickmatic);293 if (rc != EOK) {294 free(ui);295 return rc;296 }297 298 213 ui->display = disp; 299 214 list_initialize(&ui->windows); 300 fibril_mutex_initialize(&ui->lock);301 215 *rui = ui; 302 216 return EOK; … … 338 252 switch (event->type) { 339 253 case CEV_KEY: 340 ui_lock(ui);341 254 ui_window_send_kbd(awnd, &event->ev.key); 342 ui_unlock(ui);343 255 break; 344 256 case CEV_POS: … … 350 262 claim = ui_wdecor_pos_event(awnd->wdecor, &pos); 351 263 /* Note: If event is claimed, awnd might not be valid anymore */ 352 if (claim == ui_unclaimed) { 353 ui_lock(ui); 264 if (claim == ui_unclaimed) 354 265 ui_window_send_pos(awnd, &pos); 355 ui_unlock(ui); 356 } 357 358 break; 359 case CEV_RESIZE: 360 ui_lock(ui); 361 ui_window_send_resize(awnd); 362 ui_unlock(ui); 266 363 267 break; 364 268 } … … 451 355 } 452 356 453 /** Free up console for other users.454 *455 * Release console resources for another application (that the current456 * task is starting). After the other application finishes, resume457 * operation with ui_resume(). No calls to UI must happen inbetween458 * and no events must be processed (i.e. the calling function must not459 * return control to UI.460 *461 * @param ui UI462 * @return EOK on success or an error code463 */464 errno_t ui_suspend(ui_t *ui)465 {466 errno_t rc;467 468 assert(!ui->suspended);469 470 if (ui->cgc == NULL) {471 ui->suspended = true;472 return EOK;473 }474 475 (void) console_set_caption(ui->console, "");476 rc = console_gc_suspend(ui->cgc);477 if (rc != EOK)478 return rc;479 480 ui->suspended = true;481 return EOK;482 }483 484 /** Resume suspended UI.485 *486 * Reclaim console resources (after child application has finished running)487 * and restore UI operation previously suspended by calling ui_suspend().488 *489 * @param ui UI490 * @return EOK on success or an error code491 */492 errno_t ui_resume(ui_t *ui)493 {494 errno_t rc;495 ui_window_t *awnd;496 sysarg_t col;497 sysarg_t row;498 cons_event_t ev;499 500 assert(ui->suspended);501 502 if (ui->cgc == NULL) {503 ui->suspended = false;504 return EOK;505 }506 507 rc = console_get_pos(ui->console, &col, &row);508 if (rc != EOK)509 return rc;510 511 /*512 * Here's a little heuristic to help determine if we need513 * to pause before returning to the UI. If we are in the514 * top-left corner, chances are the screen is empty and515 * there is no need to pause.516 */517 if (col != 0 || row != 0) {518 printf("Press any key or button to continue...\n");519 520 while (true) {521 rc = console_get_event(ui->console, &ev);522 if (rc != EOK)523 return EIO;524 525 if (ev.type == CEV_KEY && ev.ev.key.type == KEY_PRESS)526 break;527 528 if (ev.type == CEV_POS && ev.ev.pos.type == POS_PRESS)529 break;530 }531 }532 533 rc = console_gc_resume(ui->cgc);534 if (rc != EOK)535 return rc;536 537 ui->suspended = false;538 539 awnd = ui_window_get_active(ui);540 if (awnd != NULL)541 (void) console_set_caption(ui->console, awnd->wdecor->caption);542 543 rc = gfx_cursor_set_visible(console_gc_get_ctx(ui->cgc), false);544 if (rc != EOK)545 return rc;546 547 return EOK;548 }549 550 /** Determine if UI is suspended.551 *552 * @param ui UI553 * @return @c true iff UI is suspended554 */555 bool ui_is_suspended(ui_t *ui)556 {557 return ui->suspended;558 }559 560 /** Lock UI.561 *562 * Block UI from calling window callbacks. @c ui_lock() and @c ui_unlock()563 * must be used when accessing UI resources from a fibril (as opposed to564 * from a window callback).565 *566 * @param ui UI567 */568 void ui_lock(ui_t *ui)569 {570 fibril_mutex_lock(&ui->lock);571 }572 573 /** Unlock UI.574 *575 * Allow UI to call window callbacks. @c ui_lock() and @c ui_unlock()576 * must be used when accessing window resources from a fibril (as opposed to577 * from a window callback).578 *579 * @param ui UI580 */581 void ui_unlock(ui_t *ui)582 {583 fibril_mutex_unlock(&ui->lock);584 }585 586 357 /** Terminate user interface. 587 358 * … … 621 392 } 622 393 623 /** Get UI screen rectangle.624 *625 * @param ui User interface626 * @param rect Place to store bounding rectangle627 */628 errno_t ui_get_rect(ui_t *ui, gfx_rect_t *rect)629 {630 display_info_t info;631 sysarg_t cols, rows;632 errno_t rc;633 634 if (ui->display != NULL) {635 rc = display_get_info(ui->display, &info);636 if (rc != EOK)637 return rc;638 639 *rect = info.rect;640 } else if (ui->console != NULL) {641 rc = console_get_size(ui->console, &cols, &rows);642 if (rc != EOK)643 return rc;644 645 rect->p0.x = 0;646 rect->p0.y = 0;647 rect->p1.x = cols;648 rect->p1.y = rows;649 } else {650 return ENOTSUP;651 }652 653 return EOK;654 }655 656 /** Get clickmatic from UI.657 *658 * @pararm ui UI659 * @return Clickmatic660 */661 ui_clickmatic_t *ui_get_clickmatic(ui_t *ui)662 {663 return ui->clickmatic;664 }665 666 394 /** @} 667 395 */
Note:
See TracChangeset
for help on using the changeset viewer.