Changes in uspace/srv/hid/console/console.c [e273e9e:68a552f] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/console/console.c
re273e9e r68a552f 1 1 /* 2 * Copyright (c) 202 4Jiri Svoboda2 * Copyright (c) 2021 Jiri Svoboda 3 3 * Copyright (c) 2011 Martin Decky 4 4 * All rights reserved. … … 37 37 #include <stdio.h> 38 38 #include <adt/prodcons.h> 39 #include <io/console.h>40 39 #include <io/input.h> 41 40 #include <ipc/vfs.h> … … 64 63 typedef struct { 65 64 atomic_flag refcnt; /**< Connection reference count */ 66 prodcons_t input_pc; /**< Incoming consoleevents */65 prodcons_t input_pc; /**< Incoming keyboard events */ 67 66 68 67 /** … … 90 89 } console_t; 91 90 92 static loc_srv_t *console_srv;93 94 91 /** Input server proxy */ 95 92 static input_t *input; … … 103 100 static sysarg_t rows; 104 101 105 /** Mouse pointer X coordinate */106 static int pointer_x;107 /** Mouse pointer Y coordinate */108 static int pointer_y;109 /** Character under mouse cursor */110 static charfield_t pointer_bg;111 112 static int mouse_scale_x = 4;113 static int mouse_scale_y = 8;114 115 102 /** Array of data for virtual consoles */ 116 103 static console_t consoles[CONSOLE_COUNT]; … … 123 110 static errno_t input_ev_active(input_t *); 124 111 static errno_t input_ev_deactive(input_t *); 125 static errno_t input_ev_key(input_t *, unsigned, kbd_event_type_t, keycode_t, 126 keymod_t, char32_t); 127 static errno_t input_ev_move(input_t *, unsigned, int, int); 128 static errno_t input_ev_abs_move(input_t *, unsigned, unsigned, unsigned, 129 unsigned, unsigned); 130 static errno_t input_ev_button(input_t *, unsigned, int, int); 131 static errno_t input_ev_dclick(input_t *, unsigned, int); 112 static errno_t input_ev_key(input_t *, kbd_event_type_t, keycode_t, keymod_t, char32_t); 113 static errno_t input_ev_move(input_t *, int, int); 114 static errno_t input_ev_abs_move(input_t *, unsigned, unsigned, unsigned, unsigned); 115 static errno_t input_ev_button(input_t *, int, int); 132 116 133 117 static input_ev_ops_t input_ev_ops = { … … 137 121 .move = input_ev_move, 138 122 .abs_move = input_ev_abs_move, 139 .button = input_ev_button, 140 .dclick = input_ev_dclick 123 .button = input_ev_button 141 124 }; 142 125 … … 156 139 static void cons_set_rgb_color(con_srv_t *, pixel_t, pixel_t); 157 140 static void cons_set_cursor_visibility(con_srv_t *, bool); 158 static errno_t cons_set_caption(con_srv_t *, const char *);159 141 static errno_t cons_get_event(con_srv_t *, cons_event_t *); 160 142 static errno_t cons_map(con_srv_t *, sysarg_t, sysarg_t, charfield_t **); … … 178 160 .set_rgb_color = cons_set_rgb_color, 179 161 .set_cursor_visibility = cons_set_cursor_visibility, 180 .set_caption = cons_set_caption,181 162 .get_event = cons_get_event, 182 163 .map = cons_map, … … 184 165 .update = cons_buf_update 185 166 }; 186 187 static void pointer_draw(void);188 static void pointer_undraw(void);189 167 190 168 static console_t *srv_to_console(con_srv_t *srv) … … 253 231 254 232 fibril_mutex_lock(&switch_mtx); 255 pointer_undraw();256 233 257 234 if (cons == active_console) { … … 262 239 active_console = cons; 263 240 264 pointer_draw();265 241 fibril_mutex_unlock(&switch_mtx); 266 242 267 243 cons_damage(cons); 268 }269 270 /** Draw mouse pointer. */271 static void pointer_draw(void)272 {273 charfield_t *ch;274 int col, row;275 276 /* Downscale coordinates to text resolution */277 col = pointer_x / mouse_scale_x;278 row = pointer_y / mouse_scale_y;279 280 /* Make sure they are in range */281 if (col < 0 || row < 0 || col >= (int)cols || row >= (int)rows)282 return;283 284 ch = chargrid_charfield_at(active_console->frontbuf, col, row);285 286 /*287 * Store background attributes for undrawing the pointer.288 * This is necessary as styles cannot be inverted with289 * round trip (unlike RGB or INDEX)290 */291 pointer_bg = *ch;292 293 /* In general the color should be a one's complement of the background */294 if (ch->attrs.type == CHAR_ATTR_INDEX) {295 ch->attrs.val.index.bgcolor ^= 0xf;296 ch->attrs.val.index.fgcolor ^= 0xf;297 } else if (ch->attrs.type == CHAR_ATTR_RGB) {298 ch->attrs.val.rgb.fgcolor ^= 0xffffff;299 ch->attrs.val.rgb.bgcolor ^= 0xffffff;300 } else if (ch->attrs.type == CHAR_ATTR_STYLE) {301 /* Don't have a proper inverse for each style */302 if (ch->attrs.val.style == STYLE_INVERTED)303 ch->attrs.val.style = STYLE_NORMAL;304 else305 ch->attrs.val.style = STYLE_INVERTED;306 }307 308 /* Make sure the cell gets updated */309 ch->flags |= CHAR_FLAG_DIRTY;310 }311 312 /** Undraw mouse pointer. */313 static void pointer_undraw(void)314 {315 charfield_t *ch;316 int col, row;317 318 col = pointer_x / mouse_scale_x;319 row = pointer_y / mouse_scale_y;320 if (col < 0 || row < 0 || col >= (int)cols || row >= (int)rows)321 return;322 323 ch = chargrid_charfield_at(active_console->frontbuf, col, row);324 *ch = pointer_bg;325 ch->flags |= CHAR_FLAG_DIRTY;326 }327 328 /** Queue console event.329 *330 * @param cons Console331 * @param ev Console event332 */333 static void console_queue_cons_event(console_t *cons, cons_event_t *ev)334 {335 /* Got key press/release event */336 cons_qevent_t *event =337 (cons_qevent_t *) malloc(sizeof(cons_qevent_t));338 if (event == NULL)339 return;340 341 event->ev = *ev;342 link_initialize(&event->link);343 344 prodcons_produce(&cons->input_pc, &event->link);345 244 } 346 245 … … 362 261 } 363 262 364 static errno_t input_ev_key(input_t *input, unsigned kbd_id, 365 kbd_event_type_t type, keycode_t key, keymod_t mods, char32_t c) 366 { 367 cons_event_t event; 368 bool alt; 369 bool shift; 370 371 alt = (mods & KM_ALT) != 0 && (mods & (KM_CTRL | KM_SHIFT)) == 0; 372 shift = (mods & KM_SHIFT) != 0 && (mods & (KM_CTRL | KM_ALT)) == 0; 373 374 /* Switch console on Alt+Fn or Shift+Fn */ 263 static errno_t input_ev_key(input_t *input, kbd_event_type_t type, keycode_t key, 264 keymod_t mods, char32_t c) 265 { 375 266 if ((key >= KC_F1) && (key <= KC_F1 + CONSOLE_COUNT) && 376 ( alt || shift)) {267 ((mods & KM_CTRL) == 0)) { 377 268 cons_switch(key - KC_F1); 378 269 } else { 379 270 /* Got key press/release event */ 380 event.type = CEV_KEY; 381 382 (void)kbd_id; 383 event.ev.key.type = type; 384 event.ev.key.key = key; 385 event.ev.key.mods = mods; 386 event.ev.key.c = c; 387 388 console_queue_cons_event(active_console, &event); 389 } 390 391 return EOK; 392 } 393 394 /** Update pointer position. 395 * 396 * @param new_x New X coordinate (in pixels) 397 * @param new_y New Y coordinate (in pixels) 398 */ 399 static void pointer_update(int new_x, int new_y) 400 { 401 bool upd_pointer; 402 403 /* Make sure coordinates are in range */ 404 405 if (new_x < 0) 406 new_x = 0; 407 if (new_x >= (int)cols * mouse_scale_x) 408 new_x = cols * mouse_scale_x - 1; 409 if (new_y < 0) 410 new_y = 0; 411 if (new_y >= (int)rows * mouse_scale_y) 412 new_y = rows * mouse_scale_y - 1; 413 414 /* Determine if pointer moved to a different character cell */ 415 upd_pointer = (new_x / mouse_scale_x != pointer_x / mouse_scale_x) || 416 (new_y / mouse_scale_y != pointer_y / mouse_scale_y); 417 418 if (upd_pointer) 419 pointer_undraw(); 420 421 /* Store new pointer position */ 422 pointer_x = new_x; 423 pointer_y = new_y; 424 425 if (upd_pointer) { 426 pointer_draw(); 427 cons_update(active_console); 428 } 429 } 430 431 static errno_t input_ev_move(input_t *input, unsigned pos_id, int dx, int dy) 432 { 433 (void) pos_id; 434 pointer_update(pointer_x + dx, pointer_y + dy); 435 return EOK; 436 } 437 438 static errno_t input_ev_abs_move(input_t *input, unsigned pos_id, unsigned x, 439 unsigned y, unsigned max_x, unsigned max_y) 440 { 441 (void)pos_id; 442 pointer_update(mouse_scale_x * cols * x / max_x, mouse_scale_y * rows * y / max_y); 443 return EOK; 444 } 445 446 static errno_t input_ev_button(input_t *input, unsigned pos_id, int bnum, 447 int bpress) 448 { 449 cons_event_t event; 450 451 (void)pos_id; 452 453 event.type = CEV_POS; 454 event.ev.pos.type = bpress ? POS_PRESS : POS_RELEASE; 455 event.ev.pos.btn_num = bnum; 456 event.ev.pos.hpos = pointer_x / mouse_scale_x; 457 event.ev.pos.vpos = pointer_y / mouse_scale_y; 458 459 console_queue_cons_event(active_console, &event); 460 return EOK; 461 } 462 463 static errno_t input_ev_dclick(input_t *input, unsigned pos_id, int bnum) 464 { 465 cons_event_t event; 466 467 (void)pos_id; 468 469 event.type = CEV_POS; 470 event.ev.pos.type = POS_DCLICK; 471 event.ev.pos.btn_num = bnum; 472 event.ev.pos.hpos = pointer_x / mouse_scale_x; 473 event.ev.pos.vpos = pointer_y / mouse_scale_y; 474 475 console_queue_cons_event(active_console, &event); 271 kbd_event_t *event = 272 (kbd_event_t *) malloc(sizeof(kbd_event_t)); 273 if (event == NULL) { 274 return ENOMEM; 275 } 276 277 link_initialize(&event->link); 278 event->type = type; 279 event->key = key; 280 event->mods = mods; 281 event->c = c; 282 283 prodcons_produce(&active_console->input_pc, 284 &event->link); 285 } 286 287 return EOK; 288 } 289 290 static errno_t input_ev_move(input_t *input, int dx, int dy) 291 { 292 return EOK; 293 } 294 295 static errno_t input_ev_abs_move(input_t *input, unsigned x, unsigned y, 296 unsigned max_x, unsigned max_y) 297 { 298 return EOK; 299 } 300 301 static errno_t input_ev_button(input_t *input, int bnum, int bpress) 302 { 476 303 return EOK; 477 304 } … … 483 310 484 311 fibril_mutex_lock(&cons->mtx); 485 pointer_undraw();486 312 487 313 switch (ch) { … … 501 327 } 502 328 503 pointer_draw();504 329 fibril_mutex_unlock(&cons->mtx); 505 330 … … 511 336 { 512 337 fibril_mutex_lock(&cons->mtx); 513 pointer_undraw();514 338 chargrid_set_cursor_visibility(cons->frontbuf, visible); 515 pointer_draw();516 339 fibril_mutex_unlock(&cons->mtx); 517 340 … … 556 379 if (pos < size) { 557 380 link_t *link = prodcons_consume(&cons->input_pc); 558 cons_qevent_t *qevent = list_get_instance(link, 559 cons_qevent_t, link); 560 cons_event_t *event = &qevent->ev; 381 kbd_event_t *event = list_get_instance(link, kbd_event_t, link); 561 382 562 383 /* Accept key presses of printable chars only. */ 563 if (event->type == CEV_KEY && event->ev.key.type == KEY_PRESS && 564 (event->ev.key.c != 0)) { 565 char32_t tmp[2] = { event->ev.key.c, 0 }; 384 if ((event->type == KEY_PRESS) && (event->c != 0)) { 385 char32_t tmp[2] = { event->c, 0 }; 566 386 wstr_to_str(cons->char_remains, UTF8_CHAR_BUFFER_SIZE, tmp); 567 387 cons->char_remains_len = str_size(cons->char_remains); 568 388 } 569 389 570 free( qevent);390 free(event); 571 391 } 572 392 } … … 600 420 601 421 fibril_mutex_lock(&cons->mtx); 602 pointer_undraw();603 422 chargrid_clear(cons->frontbuf); 604 pointer_draw();605 423 fibril_mutex_unlock(&cons->mtx); 606 424 … … 613 431 614 432 fibril_mutex_lock(&cons->mtx); 615 pointer_undraw();616 433 chargrid_set_cursor(cons->frontbuf, col, row); 617 pointer_draw();618 434 fibril_mutex_unlock(&cons->mtx); 619 435 … … 691 507 } 692 508 693 static errno_t cons_set_caption(con_srv_t *srv, const char *caption)694 {695 console_t *cons = srv_to_console(srv);696 697 (void) cons;698 (void) caption;699 return EOK;700 }701 702 509 static errno_t cons_get_event(con_srv_t *srv, cons_event_t *event) 703 510 { 704 511 console_t *cons = srv_to_console(srv); 705 512 link_t *link = prodcons_consume(&cons->input_pc); 706 cons_qevent_t *qevent = list_get_instance(link, cons_qevent_t, link); 707 708 *event = qevent->ev; 709 free(qevent); 513 kbd_event_t *kevent = list_get_instance(link, kbd_event_t, link); 514 515 event->type = CEV_KEY; 516 event->ev.key = *kevent; 517 518 free(kevent); 710 519 return EOK; 711 520 } … … 812 621 /* Update front buffer from user buffer */ 813 622 814 pointer_undraw();815 816 623 for (row = r0; row < r1; row++) { 817 624 for (col = c0; col < c1; col++) { … … 821 628 } 822 629 823 pointer_draw();824 630 fibril_mutex_unlock(&cons->mtx); 825 631 … … 912 718 /* Register server */ 913 719 async_set_fallback_port_handler(client_connection, NULL); 914 rc = loc_server_register(NAME , &console_srv);720 rc = loc_server_register(NAME); 915 721 if (rc != EOK) { 916 722 printf("%s: Unable to register server (%s)\n", NAME, … … 962 768 snprintf(vc, LOC_NAME_MAXLEN, "%s/vc%zu", NAMESPACE, i); 963 769 964 if (loc_service_register(console_srv, vc, 965 &consoles[i].dsid) != EOK) { 770 if (loc_service_register(vc, &consoles[i].dsid) != EOK) { 966 771 printf("%s: Unable to register device %s\n", NAME, vc); 967 772 return false;
Note:
See TracChangeset
for help on using the changeset viewer.