Changes in uspace/srv/hid/console/console.c [2f6ad06:902f0906] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/console/console.c
r2f6ad06 r902f0906 41 41 #include <str_error.h> 42 42 #include <loc.h> 43 #include <event.h> 43 44 #include <io/con_srv.h> 44 45 #include <io/kbd_event.h> … … 49 50 #include <malloc.h> 50 51 #include <as.h> 51 #include <task.h>52 52 #include <fibril_synch.h> 53 53 #include "console.h" … … 84 84 /** Input server proxy */ 85 85 static input_t *input; 86 static bool active = false;87 86 88 87 /** Session to the output server */ … … 99 98 static FIBRIL_MUTEX_INITIALIZE(switch_mtx); 100 99 100 static console_t *prev_console = &consoles[0]; 101 101 static console_t *active_console = &consoles[0]; 102 103 static int input_ev_active(input_t *); 104 static int input_ev_deactive(input_t *); 102 static console_t *kernel_console = &consoles[KERNEL_CONSOLE]; 103 105 104 static int input_ev_key(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t); 106 105 static int input_ev_move(input_t *, int, int); … … 109 108 110 109 static input_ev_ops_t input_ev_ops = { 111 .active = input_ev_active,112 .deactive = input_ev_deactive,113 110 .key = input_ev_key, 114 111 .move = input_ev_move, … … 162 159 fibril_mutex_lock(&cons->mtx); 163 160 164 if (( active) && (cons == active_console)) {161 if ((cons == active_console) && (active_console != kernel_console)) { 165 162 output_update(output_sess, cons->fbid); 166 163 output_cursor_update(output_sess, cons->fbid); … … 176 173 fibril_mutex_lock(&cons->mtx); 177 174 178 if (( active) && (cons == active_console))175 if ((cons == active_console) && (active_console != kernel_console)) 179 176 output_cursor_update(output_sess, cons->fbid); 180 177 … … 188 185 fibril_mutex_lock(&cons->mtx); 189 186 190 if (( active) && (cons == active_console)) {187 if ((cons == active_console) && (active_console != kernel_console)) { 191 188 output_damage(output_sess, cons->fbid, 0, 0, cons->cols, 192 189 cons->rows); … … 198 195 } 199 196 200 static void cons_switch(unsigned int index) 201 { 202 /* 203 * The first undefined index is reserved 204 * for switching to the kernel console. 205 */ 206 if (index == CONSOLE_COUNT) { 207 if (console_kcon()) 208 active = false; 209 210 return; 211 } 212 213 if (index > CONSOLE_COUNT) 214 return; 215 216 console_t *cons = &consoles[index]; 217 197 static void cons_switch(console_t *cons) 198 { 218 199 fibril_mutex_lock(&switch_mtx); 219 200 … … 223 204 } 224 205 206 if (cons == kernel_console) { 207 output_yield(output_sess); 208 if (!console_kcon()) { 209 output_claim(output_sess); 210 fibril_mutex_unlock(&switch_mtx); 211 return; 212 } 213 } 214 215 if (active_console == kernel_console) 216 output_claim(output_sess); 217 218 prev_console = active_console; 225 219 active_console = cons; 226 220 … … 230 224 } 231 225 232 static int input_ev_active(input_t *input) 233 { 234 active = true; 235 output_claim(output_sess); 236 cons_damage(active_console); 237 238 return EOK; 239 } 240 241 static int input_ev_deactive(input_t *input) 242 { 243 active = false; 244 output_yield(output_sess); 245 246 return EOK; 226 static console_t *cons_get_active_uspace(void) 227 { 228 fibril_mutex_lock(&switch_mtx); 229 230 console_t *active_uspace = active_console; 231 if (active_uspace == kernel_console) 232 active_uspace = prev_console; 233 234 assert(active_uspace != kernel_console); 235 236 fibril_mutex_unlock(&switch_mtx); 237 238 return active_uspace; 247 239 } 248 240 … … 250 242 keymod_t mods, wchar_t c) 251 243 { 252 if ((key >= KC_F1) && (key < =KC_F1 + CONSOLE_COUNT) &&244 if ((key >= KC_F1) && (key < KC_F1 + CONSOLE_COUNT) && 253 245 ((mods & KM_CTRL) == 0)) { 254 cons_switch( key - KC_F1);246 cons_switch(&consoles[key - KC_F1]); 255 247 } else { 256 248 /* Got key press/release event */ … … 267 259 event->c = c; 268 260 269 prodcons_produce(&active_console->input_pc, 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 270 &event->link); 271 271 } … … 377 377 } 378 378 } 379 379 380 380 return size; 381 381 } … … 388 388 while (off < size) 389 389 cons_write_char(cons, str_decode(data, &off, size)); 390 391 390 return size; 392 391 } … … 499 498 event->type = CEV_KEY; 500 499 event->ev.key = *kevent; 501 502 500 free(kevent); 503 501 return EOK; … … 509 507 510 508 for (size_t i = 0; i < CONSOLE_COUNT; i++) { 511 if (consoles[i].dsid == (service_id_t) IPC_GET_ARG2(*icall)) { 509 if (i == KERNEL_CONSOLE) 510 continue; 511 512 if (consoles[i].dsid == (service_id_t) IPC_GET_ARG1(*icall)) { 512 513 cons = &consoles[i]; 513 514 break; … … 525 526 con_conn(iid, icall, &cons->srvs); 526 527 } 528 527 529 528 530 static int input_connect(const char *svc) … … 537 539 } 538 540 539 sess = loc_service_connect( dsid, INTERFACE_INPUT, 0);541 sess = loc_service_connect(EXCHANGE_ATOMIC, dsid, 0); 540 542 if (sess == NULL) { 541 543 printf("%s: Unable to connect to input service %s\n", NAME, … … 555 557 } 556 558 559 static void interrupt_received(ipc_callid_t callid, ipc_call_t *call) 560 { 561 cons_switch(prev_console); 562 } 563 557 564 static async_sess_t *output_connect(const char *svc) 558 565 { … … 562 569 int rc = loc_service_get_id(svc, &dsid, 0); 563 570 if (rc == EOK) { 564 sess = loc_service_connect( dsid, INTERFACE_OUTPUT, 0);571 sess = loc_service_connect(EXCHANGE_SERIALIZE, dsid, 0); 565 572 if (sess == NULL) { 566 573 printf("%s: Unable to connect to output service %s\n", … … 576 583 static bool console_srv_init(char *input_svc, char *output_svc) 577 584 { 585 int rc; 586 578 587 /* Connect to input service */ 579 intrc = input_connect(input_svc);588 rc = input_connect(input_svc); 580 589 if (rc != EOK) 581 590 return false; … … 587 596 588 597 /* Register server */ 589 async_set_ fallback_port_handler(client_connection, NULL);598 async_set_client_connection(client_connection); 590 599 rc = loc_server_register(NAME); 591 600 if (rc != EOK) { … … 601 610 output_get_caps(output_sess, &ccaps); 602 611 603 /* 604 * Inititalize consoles only if there are 605 * actually some output devices. 606 */ 607 if (ccaps != 0) { 608 for (size_t i = 0; i < CONSOLE_COUNT; i++) { 609 consoles[i].index = i; 610 atomic_set(&consoles[i].refcnt, 0); 611 fibril_mutex_initialize(&consoles[i].mtx); 612 prodcons_initialize(&consoles[i].input_pc); 613 consoles[i].char_remains_len = 0; 614 615 consoles[i].cols = cols; 616 consoles[i].rows = rows; 617 consoles[i].ccaps = ccaps; 618 consoles[i].frontbuf = 619 chargrid_create(cols, rows, CHARGRID_FLAG_SHARED); 620 621 if (consoles[i].frontbuf == NULL) { 622 printf("%s: Unable to allocate frontbuffer %zu\n", NAME, i); 623 return false; 624 } 625 626 consoles[i].fbid = output_frontbuf_create(output_sess, 627 consoles[i].frontbuf); 628 if (consoles[i].fbid == 0) { 629 printf("%s: Unable to create frontbuffer %zu\n", NAME, i); 630 return false; 631 } 632 633 con_srvs_init(&consoles[i].srvs); 634 consoles[i].srvs.ops = &con_ops; 635 consoles[i].srvs.sarg = &consoles[i]; 636 637 char vc[LOC_NAME_MAXLEN + 1]; 638 snprintf(vc, LOC_NAME_MAXLEN, "%s/vc%zu", NAMESPACE, i); 639 640 if (loc_service_register(vc, &consoles[i].dsid) != EOK) { 641 printf("%s: Unable to register device %s\n", NAME, vc); 642 return false; 643 } 644 } 645 646 input_activate(input); 647 } 612 /* Inititalize consoles */ 613 for (size_t i = 0; i < CONSOLE_COUNT; i++) { 614 consoles[i].index = i; 615 atomic_set(&consoles[i].refcnt, 0); 616 fibril_mutex_initialize(&consoles[i].mtx); 617 prodcons_initialize(&consoles[i].input_pc); 618 consoles[i].char_remains_len = 0; 619 620 if (i == KERNEL_CONSOLE) 621 continue; 622 623 consoles[i].cols = cols; 624 consoles[i].rows = rows; 625 consoles[i].ccaps = ccaps; 626 consoles[i].frontbuf = 627 chargrid_create(cols, rows, CHARGRID_FLAG_SHARED); 628 629 if (consoles[i].frontbuf == NULL) { 630 printf("%s: Unable to allocate frontbuffer %zu\n", NAME, i); 631 return false; 632 } 633 634 consoles[i].fbid = output_frontbuf_create(output_sess, 635 consoles[i].frontbuf); 636 if (consoles[i].fbid == 0) { 637 printf("%s: Unable to create frontbuffer %zu\n", NAME, i); 638 return false; 639 } 640 641 con_srvs_init(&consoles[i].srvs); 642 consoles[i].srvs.ops = &con_ops; 643 consoles[i].srvs.sarg = &consoles[i]; 644 645 char vc[LOC_NAME_MAXLEN + 1]; 646 snprintf(vc, LOC_NAME_MAXLEN, "%s/vc%zu", NAMESPACE, i); 647 648 if (loc_service_register(vc, &consoles[i].dsid) != EOK) { 649 printf("%s: Unable to register device %s\n", NAME, vc); 650 return false; 651 } 652 } 653 654 cons_damage(active_console); 655 656 /* Receive kernel notifications */ 657 async_set_interrupt_received(interrupt_received); 658 rc = event_subscribe(EVENT_KCONSOLE, 0); 659 if (rc != EOK) 660 printf("%s: Failed to register kconsole notifications (%s)\n", 661 NAME, str_error(rc)); 648 662 649 663 return true;
Note:
See TracChangeset
for help on using the changeset viewer.