Changeset 6a44ee4 in mainline for uspace/srv/hid/console/console.c
- Timestamp:
- 2011-07-20T15:26:21Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- efcebe1
- Parents:
- 25bef0ff (diff), a701812 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/console/console.c
r25bef0ff r6a44ee4 1 1 /* 2 2 * Copyright (c) 2006 Josef Cejka 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 34 35 35 36 #include <libc.h> 36 #include <ipc/ kbd.h>37 #include <ipc/input.h> 37 38 #include <io/keycode.h> 38 #include <ipc/mouse.h>39 39 #include <ipc/fb.h> 40 40 #include <ipc/services.h> 41 #include <ipc/ns.h> 41 #include <ns.h> 42 #include <ns_obsolete.h> 42 43 #include <errno.h> 44 #include <str_error.h> 43 45 #include <ipc/console.h> 44 46 #include <unistd.h> 45 47 #include <async.h> 48 #include <async_obsolete.h> 46 49 #include <adt/fifo.h> 47 50 #include <sys/mman.h> … … 61 64 #include "keybuffer.h" 62 65 63 64 66 #define NAME "console" 65 67 #define NAMESPACE "term" 66 68 67 /** Phone to the keyboard driver. */ 68 static int kbd_phone; 69 70 /** Phone to the mouse driver. */ 71 static int mouse_phone; 69 /** Session with the input server. */ 70 static async_sess_t *input_sess; 72 71 73 72 /** Information about framebuffer */ … … 109 108 static FIBRIL_CONDVAR_INITIALIZE(input_cv); 110 109 110 static FIBRIL_MUTEX_INITIALIZE(big_console_lock); 111 112 static void console_serialize_start(void) 113 { 114 fibril_mutex_lock(&big_console_lock); 115 } 116 117 static void console_serialize_end(void) 118 { 119 fibril_mutex_unlock(&big_console_lock); 120 } 121 111 122 static void curs_visibility(bool visible) 112 123 { 113 async_ msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible);124 async_obsolete_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible); 114 125 } 115 126 116 127 static void curs_hide_sync(void) 117 128 { 118 async_ req_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false);129 async_obsolete_req_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false); 119 130 } 120 131 121 132 static void curs_goto(sysarg_t x, sysarg_t y) 122 133 { 123 async_ msg_2(fb_info.phone, FB_CURSOR_GOTO, x, y);134 async_obsolete_msg_2(fb_info.phone, FB_CURSOR_GOTO, x, y); 124 135 } 125 136 126 137 static void screen_clear(void) 127 138 { 128 async_ msg_0(fb_info.phone, FB_CLEAR);139 async_obsolete_msg_0(fb_info.phone, FB_CLEAR); 129 140 } 130 141 131 142 static void screen_yield(void) 132 143 { 133 async_ req_0_0(fb_info.phone, FB_SCREEN_YIELD);144 async_obsolete_req_0_0(fb_info.phone, FB_SCREEN_YIELD); 134 145 } 135 146 136 147 static void screen_reclaim(void) 137 148 { 138 async_req_0_0(fb_info.phone, FB_SCREEN_RECLAIM); 139 } 140 141 static void kbd_yield(void) 142 { 143 async_req_0_0(kbd_phone, KBD_YIELD); 144 } 145 146 static void kbd_reclaim(void) 147 { 148 async_req_0_0(kbd_phone, KBD_RECLAIM); 149 async_obsolete_req_0_0(fb_info.phone, FB_SCREEN_RECLAIM); 150 } 151 152 static void input_yield(void) 153 { 154 async_exch_t *exch = async_exchange_begin(input_sess); 155 if (exch == NULL) { 156 printf("%s: Failed starting exchange with input device.\n", 157 NAME); 158 return; 159 } 160 161 async_req_0_0(exch, INPUT_YIELD); 162 async_exchange_end(exch); 163 } 164 165 static void input_reclaim(void) 166 { 167 async_exch_t *exch = async_exchange_begin(input_sess); 168 if (exch == NULL) { 169 printf("%s: Failed starting exchange with input device.\n", 170 NAME); 171 return; 172 } 173 174 async_req_0_0(exch, INPUT_RECLAIM); 175 async_exchange_end(exch); 149 176 } 150 177 151 178 static void set_style(uint8_t style) 152 179 { 153 async_ msg_1(fb_info.phone, FB_SET_STYLE, style);180 async_obsolete_msg_1(fb_info.phone, FB_SET_STYLE, style); 154 181 } 155 182 156 183 static void set_color(uint8_t fgcolor, uint8_t bgcolor, uint8_t flags) 157 184 { 158 async_ msg_3(fb_info.phone, FB_SET_COLOR, fgcolor, bgcolor, flags);185 async_obsolete_msg_3(fb_info.phone, FB_SET_COLOR, fgcolor, bgcolor, flags); 159 186 } 160 187 161 188 static void set_rgb_color(uint32_t fgcolor, uint32_t bgcolor) 162 189 { 163 async_ msg_2(fb_info.phone, FB_SET_RGB_COLOR, fgcolor, bgcolor);190 async_obsolete_msg_2(fb_info.phone, FB_SET_RGB_COLOR, fgcolor, bgcolor); 164 191 } 165 192 … … 216 243 } 217 244 218 async_ req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,245 async_obsolete_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA, 219 246 x0, y0, width, height); 220 247 } … … 257 284 static void fb_putchar(wchar_t c, sysarg_t col, sysarg_t row) 258 285 { 259 async_ msg_3(fb_info.phone, FB_PUTCHAR, c, col, row);286 async_obsolete_msg_3(fb_info.phone, FB_PUTCHAR, c, col, row); 260 287 } 261 288 … … 306 333 307 334 if (cons == active_console) 308 async_ msg_1(fb_info.phone, FB_SCROLL, 1);335 async_obsolete_msg_1(fb_info.phone, FB_SCROLL, 1); 309 336 } 310 337 … … 323 350 324 351 if (cons == kernel_console) { 325 async_serialize_start();352 console_serialize_start(); 326 353 curs_hide_sync(); 327 354 gcons_in_kernel(); 328 355 screen_yield(); 329 kbd_yield();330 async_serialize_end();331 332 if ( __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) {356 input_yield(); 357 console_serialize_end(); 358 359 if (console_kcon()) { 333 360 prev_console = active_console; 334 361 active_console = kernel_console; … … 338 365 339 366 if (cons != kernel_console) { 340 async_serialize_start();367 console_serialize_start(); 341 368 342 369 if (active_console == kernel_console) { 343 370 screen_reclaim(); 344 kbd_reclaim();371 input_reclaim(); 345 372 gcons_redraw_console(); 346 373 } … … 365 392 366 393 /* This call can preempt, but we are already at the end */ 367 rc = async_ req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,394 rc = async_obsolete_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA, 368 395 0, 0, cons->scr.size_x, 369 396 cons->scr.size_y); … … 393 420 curs_visibility(cons->scr.is_cursor_visible); 394 421 395 async_serialize_end();396 } 397 } 398 399 /** Handler for keyboard*/400 static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall)422 console_serialize_end(); 423 } 424 } 425 426 /** Handler for input events */ 427 static void input_events(ipc_callid_t iid, ipc_call_t *icall, void *arg) 401 428 { 402 429 /* Ignore parameters, the connection is already opened */ … … 406 433 407 434 int retval; 408 console_event_t ev; 435 kbd_event_t ev; 436 437 if (!IPC_GET_IMETHOD(call)) { 438 /* TODO: Handle hangup */ 439 async_hangup(input_sess); 440 return; 441 } 409 442 410 443 switch (IPC_GET_IMETHOD(call)) { 411 case IPC_M_PHONE_HUNGUP: 412 /* TODO: Handle hangup */ 413 return; 414 case KBD_EVENT: 415 /* Got event from keyboard driver. */ 444 case INPUT_EVENT_KEY: 445 /* Got key press/release event */ 416 446 retval = 0; 417 447 ev.type = IPC_GET_ARG1(call); … … 434 464 fibril_mutex_unlock(&input_mutex); 435 465 break; 436 default: 437 retval = ENOENT; 438 } 439 async_answer_0(callid, retval); 440 } 441 } 442 443 /** Handler for mouse events */ 444 static void mouse_events(ipc_callid_t iid, ipc_call_t *icall) 445 { 446 /* Ignore parameters, the connection is already opened */ 447 while (true) { 448 ipc_call_t call; 449 ipc_callid_t callid = async_get_call(&call); 450 451 int retval; 452 453 switch (IPC_GET_IMETHOD(call)) { 454 case IPC_M_PHONE_HUNGUP: 455 /* TODO: Handle hangup */ 456 return; 457 case MEVENT_BUTTON: 466 case INPUT_EVENT_MOVE: 467 /* Got pointer move event */ 468 gcons_mouse_move((int) IPC_GET_ARG1(call), 469 (int) IPC_GET_ARG2(call)); 470 retval = 0; 471 break; 472 case INPUT_EVENT_BUTTON: 473 /* Got pointer button press/release event */ 458 474 if (IPC_GET_ARG1(call) == 1) { 459 475 int newcon = gcons_mouse_btn((bool) IPC_GET_ARG2(call)); … … 463 479 retval = 0; 464 480 break; 465 case MEVENT_MOVE:466 gcons_mouse_move((int) IPC_GET_ARG1(call),467 (int) IPC_GET_ARG2(call));468 retval = 0;469 break;470 481 default: 471 482 retval = ENOENT; … … 487 498 } 488 499 489 async_serialize_start();500 console_serialize_start(); 490 501 491 502 size_t off = 0; … … 495 506 } 496 507 497 async_serialize_end();508 console_serialize_end(); 498 509 499 510 gcons_notify_char(cons->index); … … 521 532 522 533 size_t pos = 0; 523 console_event_t ev;534 kbd_event_t ev; 524 535 fibril_mutex_lock(&input_mutex); 525 536 … … 546 557 static void cons_get_event(console_t *cons, ipc_callid_t rid, ipc_call_t *request) 547 558 { 548 console_event_t ev;559 kbd_event_t ev; 549 560 550 561 fibril_mutex_lock(&input_mutex); … … 562 573 563 574 /** Default thread for new connections */ 564 static void client_connection(ipc_callid_t iid, ipc_call_t *icall )575 static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 565 576 { 566 577 console_t *cons = NULL; … … 590 601 int rc; 591 602 592 async_serialize_start();603 console_serialize_start(); 593 604 if (cons->refcount == 0) 594 605 gcons_notify_connect(cons->index); … … 600 611 601 612 while (true) { 602 async_serialize_end();613 console_serialize_end(); 603 614 callid = async_get_call(&call); 604 async_serialize_start();615 console_serialize_start(); 605 616 606 617 arg1 = 0; … … 608 619 arg3 = 0; 609 620 610 switch (IPC_GET_IMETHOD(call)) { 611 case IPC_M_PHONE_HUNGUP: 621 if (!IPC_GET_IMETHOD(call)) { 612 622 cons->refcount--; 613 623 if (cons->refcount == 0) 614 624 gcons_notify_disconnect(cons->index); 625 console_serialize_end(); 615 626 return; 627 } 628 629 switch (IPC_GET_IMETHOD(call)) { 616 630 case VFS_OUT_READ: 617 async_serialize_end();631 console_serialize_end(); 618 632 cons_read(cons, callid, &call); 619 async_serialize_start();633 console_serialize_start(); 620 634 continue; 621 635 case VFS_OUT_WRITE: 622 async_serialize_end();636 console_serialize_end(); 623 637 cons_write(cons, callid, &call); 624 async_serialize_start();638 console_serialize_start(); 625 639 continue; 626 640 case VFS_OUT_SYNC: 627 641 fb_pending_flush(); 628 642 if (cons == active_console) { 629 async_ req_0_0(fb_info.phone, FB_FLUSH);643 async_obsolete_req_0_0(fb_info.phone, FB_FLUSH); 630 644 curs_goto(cons->scr.position_x, cons->scr.position_y); 631 645 } … … 634 648 /* Send message to fb */ 635 649 if (cons == active_console) 636 async_ msg_0(fb_info.phone, FB_CLEAR);650 async_obsolete_msg_0(fb_info.phone, FB_CLEAR); 637 651 638 652 screenbuffer_clear(&cons->scr); … … 693 707 break; 694 708 case CONSOLE_GET_EVENT: 695 async_serialize_end();709 console_serialize_end(); 696 710 cons_get_event(cons, callid, &call); 697 async_serialize_start();711 console_serialize_start(); 698 712 continue; 699 case CONSOLE_KCON_ENABLE:700 change_console(kernel_console);701 break;702 713 } 703 714 async_answer_3(callid, EOK, arg1, arg2, arg3); … … 710 721 } 711 722 712 static bool console_init(char *input) 713 { 714 /* Connect to input device */ 715 int input_fd = open(input, O_RDONLY); 716 if (input_fd < 0) { 717 printf(NAME ": Failed opening %s\n", input); 723 static async_sess_t *connect_input(const char *dev_path) 724 { 725 async_sess_t *sess; 726 async_exch_t *exch; 727 devmap_handle_t handle; 728 729 int rc = devmap_device_get_handle(dev_path, &handle, 0); 730 if (rc == EOK) { 731 sess = devmap_device_connect(EXCHANGE_ATOMIC, handle, 0); 732 if (sess == NULL) { 733 printf("%s: Failed to connect to input server\n", NAME); 734 return NULL; 735 } 736 } else { 737 return NULL; 738 } 739 740 exch = async_exchange_begin(sess); 741 if (exch == NULL) { 742 printf("%s: Failed to create callback from input server.\n", NAME); 743 return NULL; 744 } 745 746 /* NB: The callback connection is slotted for removal */ 747 rc = async_connect_to_me(exch, 0, 0, 0, input_events, NULL); 748 749 async_exchange_end(exch); 750 751 if (rc != EOK) { 752 async_hangup(sess); 753 printf("%s: Failed to create callback from input server (%s).\n", 754 NAME, str_error(rc)); 755 return NULL; 756 } 757 758 return sess; 759 } 760 761 static bool console_srv_init(char *input_dev) 762 { 763 /* Connect to input server */ 764 input_sess = connect_input(input_dev); 765 if (input_sess == NULL) 718 766 return false; 719 }720 721 kbd_phone = fd_phone(input_fd);722 if ( kbd_phone < 0) {723 printf( NAME ": Failed to connect to input device\n");767 768 /* Connect to framebuffer driver */ 769 fb_info.phone = service_obsolete_connect_blocking(SERVICE_VIDEO, 0, 0); 770 if (fb_info.phone < 0) { 771 printf("%s: Failed to connect to video service\n", NAME); 724 772 return false; 725 }726 727 /* NB: The callback connection is slotted for removal */728 if (async_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, keyboard_events)729 != 0) {730 printf(NAME ": Failed to create callback from input device\n");731 return false;732 }733 734 /* Connect to mouse device */735 mouse_phone = -1;736 int mouse_fd = open("/dev/hid_in/mouse", O_RDONLY);737 738 if (mouse_fd < 0) {739 printf(NAME ": Notice - failed opening %s\n", "/dev/hid_in/mouse");740 goto skip_mouse;741 }742 743 mouse_phone = fd_phone(mouse_fd);744 if (mouse_phone < 0) {745 printf(NAME ": Failed to connect to mouse device\n");746 goto skip_mouse;747 }748 749 if (async_connect_to_me(mouse_phone, SERVICE_CONSOLE, 0, 0, mouse_events)750 != 0) {751 printf(NAME ": Failed to create callback from mouse device\n");752 mouse_phone = -1;753 goto skip_mouse;754 }755 756 skip_mouse:757 758 /* Connect to framebuffer driver */759 fb_info.phone = service_connect_blocking(SERVICE_VIDEO, 0, 0);760 if (fb_info.phone < 0) {761 printf(NAME ": Failed to connect to video service\n");762 return -1;763 773 } 764 774 … … 766 776 int rc = devmap_driver_register(NAME, client_connection); 767 777 if (rc < 0) { 768 printf( NAME ": Unable to register driver (%d)\n", rc);778 printf("%s: Unable to register driver (%d)\n", NAME, rc); 769 779 return false; 770 780 } … … 774 784 775 785 /* Synchronize, the gcons could put something in queue */ 776 async_ req_0_0(fb_info.phone, FB_FLUSH);777 async_ req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows);778 async_ req_0_1(fb_info.phone, FB_GET_COLOR_CAP, &fb_info.color_cap);786 async_obsolete_req_0_0(fb_info.phone, FB_FLUSH); 787 async_obsolete_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows); 788 async_obsolete_req_0_1(fb_info.phone, FB_GET_COLOR_CAP, &fb_info.color_cap); 779 789 780 790 /* Set up shared memory buffer. */ … … 787 797 788 798 if (interbuffer) { 789 if (async_ share_out_start(fb_info.phone, interbuffer,799 if (async_obsolete_share_out_start(fb_info.phone, interbuffer, 790 800 AS_AREA_READ) != EOK) { 791 801 as_area_destroy(interbuffer); … … 802 812 if (screenbuffer_init(&consoles[i].scr, 803 813 fb_info.cols, fb_info.rows) == NULL) { 804 printf( NAME ": Unable to allocate screen buffer %zu\n", i);814 printf("%s: Unable to allocate screen buffer %zu\n", NAME, i); 805 815 return false; 806 816 } … … 814 824 815 825 if (devmap_device_register(vc, &consoles[i].devmap_handle) != EOK) { 816 printf( NAME ": Unable to register device %s\n", vc);826 printf("%s: Unable to register device %s\n", NAME, vc); 817 827 return false; 818 828 } … … 820 830 } 821 831 822 /* Disable kernel output to the console */823 __SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE);824 825 832 /* Initialize the screen */ 826 async_serialize_start();833 console_serialize_start(); 827 834 gcons_redraw_console(); 828 835 set_style(STYLE_NORMAL); … … 830 837 curs_goto(0, 0); 831 838 curs_visibility(active_console->scr.is_cursor_visible); 832 async_serialize_end();839 console_serialize_end(); 833 840 834 841 /* Receive kernel notifications */ 835 842 async_set_interrupt_received(interrupt_received); 836 843 if (event_subscribe(EVENT_KCONSOLE, 0) != EOK) 837 printf( NAME ": Error registering kconsole notifications\n");844 printf("%s: Error registering kconsole notifications\n", NAME); 838 845 839 846 return true; … … 842 849 static void usage(void) 843 850 { 844 printf("Usage: console <input >\n");851 printf("Usage: console <input_dev>\n"); 845 852 } 846 853 … … 854 861 printf(NAME ": HelenOS Console service\n"); 855 862 856 if (!console_ init(argv[1]))863 if (!console_srv_init(argv[1])) 857 864 return -1; 858 865
Note:
See TracChangeset
for help on using the changeset viewer.