Changes in uspace/srv/hid/console/console.c [6d5e378:5d94b16c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/console/console.c
r6d5e378 r5d94b16c 36 36 #include <stdio.h> 37 37 #include <adt/prodcons.h> 38 #include <ipc/input.h> 39 #include <ipc/console.h> 38 #include <io/input.h> 40 39 #include <ipc/vfs.h> 41 40 #include <errno.h> … … 43 42 #include <loc.h> 44 43 #include <event.h> 44 #include <io/con_srv.h> 45 #include <io/kbd_event.h> 45 46 #include <io/keycode.h> 46 47 #include <io/chargrid.h> 47 #include <io/console.h>48 48 #include <io/output.h> 49 49 #include <align.h> … … 79 79 chargrid_t *frontbuf; /**< Front buffer */ 80 80 frontbuf_handle_t fbid; /**< Front buffer handle */ 81 con_srvs_t srvs; /**< Console service setup */ 81 82 } console_t; 82 83 83 /** Session to the input server*/84 static async_sess_t *input_sess;84 /** Input server proxy */ 85 static input_t *input; 85 86 86 87 /** Session to the output server */ … … 101 102 static console_t *kernel_console = &consoles[KERNEL_CONSOLE]; 102 103 104 static int input_ev_key(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t); 105 static int input_ev_move(input_t *, int, int); 106 static int input_ev_abs_move(input_t *, unsigned, unsigned, unsigned, unsigned); 107 static int input_ev_button(input_t *, int, int); 108 109 static input_ev_ops_t input_ev_ops = { 110 .key = input_ev_key, 111 .move = input_ev_move, 112 .abs_move = input_ev_abs_move, 113 .button = input_ev_button 114 }; 115 116 static int cons_open(con_srvs_t *, con_srv_t *); 117 static int cons_close(con_srv_t *); 118 static int cons_read(con_srv_t *, void *, size_t); 119 static int cons_write(con_srv_t *, void *, size_t); 120 static void cons_sync(con_srv_t *); 121 static void cons_clear(con_srv_t *); 122 static void cons_set_pos(con_srv_t *, sysarg_t col, sysarg_t row); 123 static int cons_get_pos(con_srv_t *, sysarg_t *, sysarg_t *); 124 static int cons_get_size(con_srv_t *, sysarg_t *, sysarg_t *); 125 static int cons_get_color_cap(con_srv_t *, console_caps_t *); 126 static void cons_set_style(con_srv_t *, console_style_t); 127 static void cons_set_color(con_srv_t *, console_color_t, console_color_t, 128 console_color_attr_t); 129 static void cons_set_rgb_color(con_srv_t *, pixel_t, pixel_t); 130 static void cons_set_cursor_visibility(con_srv_t *, bool); 131 static int cons_get_event(con_srv_t *, kbd_event_t *); 132 133 static con_ops_t con_ops = { 134 .open = cons_open, 135 .close = cons_close, 136 .read = cons_read, 137 .write = cons_write, 138 .sync = cons_sync, 139 .clear = cons_clear, 140 .set_pos = cons_set_pos, 141 .get_pos = cons_get_pos, 142 .get_size = cons_get_size, 143 .get_color_cap = cons_get_color_cap, 144 .set_style = cons_set_style, 145 .set_color = cons_set_color, 146 .set_rgb_color = cons_set_rgb_color, 147 .set_cursor_visibility = cons_set_cursor_visibility, 148 .get_event = cons_get_event 149 }; 150 151 static console_t *srv_to_console(con_srv_t *srv) 152 { 153 return srv->srvs->sarg; 154 } 155 103 156 static void cons_update(console_t *cons) 104 157 { … … 125 178 fibril_mutex_unlock(&cons->mtx); 126 179 fibril_mutex_unlock(&switch_mtx); 127 }128 129 static void cons_clear(console_t *cons)130 {131 fibril_mutex_lock(&cons->mtx);132 chargrid_clear(cons->frontbuf);133 fibril_mutex_unlock(&cons->mtx);134 135 cons_update(cons);136 180 } 137 181 … … 195 239 } 196 240 197 static void input_events(ipc_callid_t iid, ipc_call_t *icall, void *arg) 198 { 199 /* Ignore parameters, the connection is already opened */ 200 while (true) { 201 ipc_call_t call; 202 ipc_callid_t callid = async_get_call(&call); 203 204 if (!IPC_GET_IMETHOD(call)) { 205 /* TODO: Handle hangup */ 206 async_hangup(input_sess); 207 return; 208 } 209 210 kbd_event_type_t type; 211 keycode_t key; 212 keymod_t mods; 213 wchar_t c; 214 215 switch (IPC_GET_IMETHOD(call)) { 216 case INPUT_EVENT_KEY: 217 type = IPC_GET_ARG1(call); 218 key = IPC_GET_ARG2(call); 219 mods = IPC_GET_ARG3(call); 220 c = IPC_GET_ARG4(call); 221 222 if ((key >= KC_F1) && (key < KC_F1 + CONSOLE_COUNT) && 223 ((mods & KM_CTRL) == 0)) 224 cons_switch(&consoles[key - KC_F1]); 225 else { 226 /* Got key press/release event */ 227 kbd_event_t *event = 228 (kbd_event_t *) malloc(sizeof(kbd_event_t)); 229 if (event == NULL) { 230 async_answer_0(callid, ENOMEM); 231 break; 232 } 233 234 link_initialize(&event->link); 235 event->type = type; 236 event->key = key; 237 event->mods = mods; 238 event->c = c; 239 240 /* 241 * Kernel console does not read events 242 * from us, so we will redirect them 243 * to the (last) active userspace console 244 * if necessary. 245 */ 246 console_t *target_console = cons_get_active_uspace(); 247 248 prodcons_produce(&target_console->input_pc, 249 &event->link); 250 } 251 252 async_answer_0(callid, EOK); 253 break; 254 case INPUT_EVENT_MOVE: 255 async_answer_0(callid, EOK); 256 break; 257 case INPUT_EVENT_BUTTON: 258 async_answer_0(callid, EOK); 259 break; 260 default: 261 async_answer_0(callid, EINVAL); 262 } 263 } 241 static int input_ev_key(input_t *input, kbd_event_type_t type, keycode_t key, 242 keymod_t mods, wchar_t c) 243 { 244 if ((key >= KC_F1) && (key < KC_F1 + CONSOLE_COUNT) && 245 ((mods & KM_CTRL) == 0)) { 246 cons_switch(&consoles[key - KC_F1]); 247 } else { 248 /* Got key press/release event */ 249 kbd_event_t *event = 250 (kbd_event_t *) malloc(sizeof(kbd_event_t)); 251 if (event == NULL) { 252 return ENOMEM; 253 } 254 255 link_initialize(&event->link); 256 event->type = type; 257 event->key = key; 258 event->mods = mods; 259 event->c = c; 260 261 /* 262 * Kernel console does not read events 263 * from us, so we will redirect them 264 * to the (last) active userspace console 265 * if necessary. 266 */ 267 console_t *target_console = cons_get_active_uspace(); 268 269 prodcons_produce(&target_console->input_pc, 270 &event->link); 271 } 272 273 return EOK; 274 } 275 276 static int input_ev_move(input_t *input, int dx, int dy) 277 { 278 return EOK; 279 } 280 281 static int input_ev_abs_move(input_t *input, unsigned x , unsigned y, 282 unsigned max_x, unsigned max_y) 283 { 284 return EOK; 285 } 286 287 static int input_ev_button(input_t *input, int bnum, int bpress) 288 { 289 return EOK; 264 290 } 265 291 … … 293 319 } 294 320 295 static void cons_set_cursor (console_t *cons, sysarg_t col, sysarg_t row)296 { 297 fibril_mutex_lock(&cons->mtx); 298 chargrid_set_cursor (cons->frontbuf, col, row);321 static void cons_set_cursor_vis(console_t *cons, bool visible) 322 { 323 fibril_mutex_lock(&cons->mtx); 324 chargrid_set_cursor_visibility(cons->frontbuf, visible); 299 325 fibril_mutex_unlock(&cons->mtx); 300 326 … … 302 328 } 303 329 304 static void cons_set_cursor_visibility(console_t *cons, bool visible) 305 { 306 fibril_mutex_lock(&cons->mtx); 307 chargrid_set_cursor_visibility(cons->frontbuf, visible); 308 fibril_mutex_unlock(&cons->mtx); 309 310 cons_update_cursor(cons); 311 } 312 313 static void cons_get_cursor(console_t *cons, ipc_callid_t iid, ipc_call_t *icall) 314 { 315 sysarg_t col; 316 sysarg_t row; 317 318 fibril_mutex_lock(&cons->mtx); 319 chargrid_get_cursor(cons->frontbuf, &col, &row); 320 fibril_mutex_unlock(&cons->mtx); 321 322 async_answer_2(iid, EOK, col, row); 323 } 324 325 static void cons_write(console_t *cons, ipc_callid_t iid, ipc_call_t *icall) 326 { 327 void *buf; 328 size_t size; 329 int rc = async_data_write_accept(&buf, false, 0, 0, 0, &size); 330 331 if (rc != EOK) { 332 async_answer_0(iid, rc); 333 return; 334 } 335 336 size_t off = 0; 337 while (off < size) 338 cons_write_char(cons, str_decode(buf, &off, size)); 339 340 async_answer_1(iid, EOK, size); 341 free(buf); 342 } 343 344 static void cons_read(console_t *cons, ipc_callid_t iid, ipc_call_t *icall) 345 { 346 ipc_callid_t callid; 347 size_t size; 348 if (!async_data_read_receive(&callid, &size)) { 349 async_answer_0(callid, EINVAL); 350 async_answer_0(iid, EINVAL); 351 return; 352 } 353 354 char *buf = (char *) malloc(size); 355 if (buf == NULL) { 356 async_answer_0(callid, ENOMEM); 357 async_answer_0(iid, ENOMEM); 358 return; 359 } 360 330 static int cons_open(con_srvs_t *srvs, con_srv_t *srv) 331 { 332 return EOK; 333 } 334 335 static int cons_close(con_srv_t *srv) 336 { 337 return EOK; 338 } 339 340 static int cons_read(con_srv_t *srv, void *buf, size_t size) 341 { 342 uint8_t *bbuf = buf; 343 console_t *cons = srv_to_console(srv); 361 344 size_t pos = 0; 362 345 … … 369 352 /* Copy to the buffer remaining characters. */ 370 353 while ((pos < size) && (cons->char_remains_len > 0)) { 371 b uf[pos] = cons->char_remains[0];354 bbuf[pos] = cons->char_remains[0]; 372 355 pos++; 373 356 … … 394 377 } 395 378 } 396 397 (void) async_data_read_finalize(callid, buf, size); 398 async_answer_1(iid, EOK, size); 399 free(buf); 400 } 401 402 static void cons_set_style(console_t *cons, console_style_t style) 403 { 379 380 return size; 381 } 382 383 static int cons_write(con_srv_t *srv, void *data, size_t size) 384 { 385 console_t *cons = srv_to_console(srv); 386 387 size_t off = 0; 388 while (off < size) 389 cons_write_char(cons, str_decode(data, &off, size)); 390 return size; 391 } 392 393 static void cons_sync(con_srv_t *srv) 394 { 395 console_t *cons = srv_to_console(srv); 396 397 cons_update(cons); 398 } 399 400 static void cons_clear(con_srv_t *srv) 401 { 402 console_t *cons = srv_to_console(srv); 403 404 fibril_mutex_lock(&cons->mtx); 405 chargrid_clear(cons->frontbuf); 406 fibril_mutex_unlock(&cons->mtx); 407 408 cons_update(cons); 409 } 410 411 static void cons_set_pos(con_srv_t *srv, sysarg_t col, sysarg_t row) 412 { 413 console_t *cons = srv_to_console(srv); 414 415 fibril_mutex_lock(&cons->mtx); 416 chargrid_set_cursor(cons->frontbuf, col, row); 417 fibril_mutex_unlock(&cons->mtx); 418 419 cons_update_cursor(cons); 420 } 421 422 static int cons_get_pos(con_srv_t *srv, sysarg_t *col, sysarg_t *row) 423 { 424 console_t *cons = srv_to_console(srv); 425 426 fibril_mutex_lock(&cons->mtx); 427 chargrid_get_cursor(cons->frontbuf, col, row); 428 fibril_mutex_unlock(&cons->mtx); 429 430 return EOK; 431 } 432 433 static int cons_get_size(con_srv_t *srv, sysarg_t *cols, sysarg_t *rows) 434 { 435 console_t *cons = srv_to_console(srv); 436 437 fibril_mutex_lock(&cons->mtx); 438 *cols = cons->cols; 439 *rows = cons->rows; 440 fibril_mutex_unlock(&cons->mtx); 441 442 return EOK; 443 } 444 445 static int cons_get_color_cap(con_srv_t *srv, console_caps_t *ccaps) 446 { 447 console_t *cons = srv_to_console(srv); 448 449 fibril_mutex_lock(&cons->mtx); 450 *ccaps = cons->ccaps; 451 fibril_mutex_unlock(&cons->mtx); 452 453 return EOK; 454 } 455 456 static void cons_set_style(con_srv_t *srv, console_style_t style) 457 { 458 console_t *cons = srv_to_console(srv); 459 404 460 fibril_mutex_lock(&cons->mtx); 405 461 chargrid_set_style(cons->frontbuf, style); … … 407 463 } 408 464 409 static void cons_set_color(con sole_t *cons, console_color_t bgcolor,465 static void cons_set_color(con_srv_t *srv, console_color_t bgcolor, 410 466 console_color_t fgcolor, console_color_attr_t attr) 411 467 { 468 console_t *cons = srv_to_console(srv); 469 412 470 fibril_mutex_lock(&cons->mtx); 413 471 chargrid_set_color(cons->frontbuf, bgcolor, fgcolor, attr); … … 415 473 } 416 474 417 static void cons_set_rgb_color(con sole_t *cons, pixel_t bgcolor,475 static void cons_set_rgb_color(con_srv_t *srv, pixel_t bgcolor, 418 476 pixel_t fgcolor) 419 477 { 478 console_t *cons = srv_to_console(srv); 479 420 480 fibril_mutex_lock(&cons->mtx); 421 481 chargrid_set_rgb_color(cons->frontbuf, bgcolor, fgcolor); … … 423 483 } 424 484 425 static void cons_get_event(console_t *cons, ipc_callid_t iid, ipc_call_t *icall) 426 { 485 static void cons_set_cursor_visibility(con_srv_t *srv, bool visible) 486 { 487 console_t *cons = srv_to_console(srv); 488 489 cons_set_cursor_vis(cons, visible); 490 } 491 492 static int cons_get_event(con_srv_t *srv, kbd_event_t *event) 493 { 494 console_t *cons = srv_to_console(srv); 427 495 link_t *link = prodcons_consume(&cons->input_pc); 428 kbd_event_t *event = list_get_instance(link, kbd_event_t, link); 429 430 async_answer_4(iid, EOK, event->type, event->key, event->mods, event->c); 431 free(event); 496 kbd_event_t *kevent = list_get_instance(link, kbd_event_t, link); 497 498 *event = *kevent; 499 free(kevent); 500 return EOK; 432 501 } 433 502 … … 452 521 453 522 if (atomic_postinc(&cons->refcnt) == 0) 454 cons_set_cursor_visibility(cons, true); 455 456 /* Accept the connection */ 457 async_answer_0(iid, EOK); 458 459 while (true) { 460 ipc_call_t call; 461 ipc_callid_t callid = async_get_call(&call); 462 463 if (!IPC_GET_IMETHOD(call)) 464 return; 465 466 switch (IPC_GET_IMETHOD(call)) { 467 case VFS_OUT_READ: 468 cons_read(cons, callid, &call); 469 break; 470 case VFS_OUT_WRITE: 471 cons_write(cons, callid, &call); 472 break; 473 case VFS_OUT_SYNC: 474 cons_update(cons); 475 async_answer_0(callid, EOK); 476 break; 477 case CONSOLE_CLEAR: 478 cons_clear(cons); 479 async_answer_0(callid, EOK); 480 break; 481 case CONSOLE_GOTO: 482 cons_set_cursor(cons, IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 483 async_answer_0(callid, EOK); 484 break; 485 case CONSOLE_GET_POS: 486 cons_get_cursor(cons, callid, &call); 487 break; 488 case CONSOLE_GET_SIZE: 489 async_answer_2(callid, EOK, cons->cols, cons->rows); 490 break; 491 case CONSOLE_GET_COLOR_CAP: 492 async_answer_1(callid, EOK, cons->ccaps); 493 break; 494 case CONSOLE_SET_STYLE: 495 cons_set_style(cons, IPC_GET_ARG1(call)); 496 async_answer_0(callid, EOK); 497 break; 498 case CONSOLE_SET_COLOR: 499 cons_set_color(cons, IPC_GET_ARG1(call), IPC_GET_ARG2(call), 500 IPC_GET_ARG3(call)); 501 async_answer_0(callid, EOK); 502 break; 503 case CONSOLE_SET_RGB_COLOR: 504 cons_set_rgb_color(cons, IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 505 async_answer_0(callid, EOK); 506 break; 507 case CONSOLE_CURSOR_VISIBILITY: 508 cons_set_cursor_visibility(cons, IPC_GET_ARG1(call)); 509 async_answer_0(callid, EOK); 510 break; 511 case CONSOLE_GET_EVENT: 512 cons_get_event(cons, callid, &call); 513 break; 514 default: 515 async_answer_0(callid, EINVAL); 516 } 517 } 518 } 519 520 static async_sess_t *input_connect(const char *svc) 523 cons_set_cursor_vis(cons, true); 524 525 con_conn(iid, icall, &cons->srvs); 526 } 527 528 529 static int input_connect(const char *svc) 521 530 { 522 531 async_sess_t *sess; … … 524 533 525 534 int rc = loc_service_get_id(svc, &dsid, 0); 526 if (rc == EOK) { 527 sess = loc_service_connect(EXCHANGE_ATOMIC, dsid, 0); 528 if (sess == NULL) { 529 printf("%s: Unable to connect to input service %s\n", NAME, 530 svc); 531 return NULL; 532 } 533 } else 534 return NULL; 535 536 async_exch_t *exch = async_exchange_begin(sess); 537 rc = async_connect_to_me(exch, 0, 0, 0, input_events, NULL); 538 async_exchange_end(exch); 539 535 if (rc != EOK) { 536 printf("%s: Input service %s not found\n", NAME, svc); 537 return rc; 538 } 539 540 sess = loc_service_connect(EXCHANGE_ATOMIC, dsid, 0); 541 if (sess == NULL) { 542 printf("%s: Unable to connect to input service %s\n", NAME, 543 svc); 544 return EIO; 545 } 546 547 rc = input_open(sess, &input_ev_ops, NULL, &input); 540 548 if (rc != EOK) { 541 549 async_hangup(sess); 542 printf("%s: Unable to c reate callback connection toservice %s (%s)\n",550 printf("%s: Unable to communicate with service %s (%s)\n", 543 551 NAME, svc, str_error(rc)); 544 return NULL;545 } 546 547 return sess;552 return rc; 553 } 554 555 return EOK; 548 556 } 549 557 … … 574 582 static bool console_srv_init(char *input_svc, char *output_svc) 575 583 { 584 int rc; 585 576 586 /* Connect to input service */ 577 input_sess= input_connect(input_svc);578 if ( input_sess == NULL)587 rc = input_connect(input_svc); 588 if (rc != EOK) 579 589 return false; 580 590 … … 586 596 /* Register server */ 587 597 async_set_client_connection(client_connection); 588 intrc = loc_server_register(NAME);598 rc = loc_server_register(NAME); 589 599 if (rc != EOK) { 590 600 printf("%s: Unable to register server (%s)\n", NAME, … … 628 638 } 629 639 640 con_srvs_init(&consoles[i].srvs); 641 consoles[i].srvs.ops = &con_ops; 642 consoles[i].srvs.sarg = &consoles[i]; 643 630 644 char vc[LOC_NAME_MAXLEN + 1]; 631 645 snprintf(vc, LOC_NAME_MAXLEN, "%s/vc%zu", NAMESPACE, i);
Note:
See TracChangeset
for help on using the changeset viewer.