Changes in uspace/srv/hid/console/console.c [854eddd6:79ae36dd] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/console/console.c
r854eddd6 r79ae36dd 1 1 /* 2 2 * Copyright (c) 2006 Josef Cejka 3 * Copyright (c) 2011 Jiri Svoboda4 3 * All rights reserved. 5 4 * … … 35 34 36 35 #include <libc.h> 37 #include <ipc/ input.h>36 #include <ipc/kbd.h> 38 37 #include <io/keycode.h> 38 #include <ipc/mouse.h> 39 39 #include <ipc/fb.h> 40 40 #include <ipc/services.h> … … 60 60 #include <io/style.h> 61 61 #include <io/screenbuffer.h> 62 #include <inttypes.h> 62 63 63 64 #include "console.h" … … 65 66 #include "keybuffer.h" 66 67 68 // FIXME: remove this header 69 #include <kernel/ipc/ipc_methods.h> 70 67 71 #define NAME "console" 68 72 #define NAMESPACE "term" 69 73 70 /** Phone to the input server. */ 71 static int input_phone; 74 /** Interval for checking for new keyboard (1/4s). */ 75 #define HOTPLUG_WATCH_INTERVAL (1000 * 250) 76 77 /* Kernel defines 32 but does not export it. */ 78 #define MAX_IPC_OUTGOING_PHONES 128 79 80 /** To allow proper phone closing. */ 81 static ipc_callid_t driver_phones[MAX_IPC_OUTGOING_PHONES] = { 0 }; 82 83 /** Phone to the keyboard driver. */ 84 static int kbd_phone; 85 86 /** Phone to the mouse driver. */ 87 static int mouse_phone; 72 88 73 89 /** Information about framebuffer */ … … 139 155 } 140 156 141 static void input_yield(void)142 { 143 async_obsolete_req_0_0( input_phone, INPUT_YIELD);144 } 145 146 static void input_reclaim(void)147 { 148 async_obsolete_req_0_0( input_phone, INPUT_RECLAIM);157 static void kbd_yield(void) 158 { 159 async_obsolete_req_0_0(kbd_phone, KBD_YIELD); 160 } 161 162 static void kbd_reclaim(void) 163 { 164 async_obsolete_req_0_0(kbd_phone, KBD_RECLAIM); 149 165 } 150 166 … … 327 343 gcons_in_kernel(); 328 344 screen_yield(); 329 input_yield();345 kbd_yield(); 330 346 async_obsolete_serialize_end(); 331 347 … … 342 358 if (active_console == kernel_console) { 343 359 screen_reclaim(); 344 input_reclaim();360 kbd_reclaim(); 345 361 gcons_redraw_console(); 346 362 } … … 397 413 } 398 414 399 /** Handler for input events */ 400 static void input_events(ipc_callid_t iid, ipc_call_t *icall, void *arg) 415 static void close_driver_phone(ipc_callid_t hash) 416 { 417 int i; 418 for (i = 0; i < MAX_IPC_OUTGOING_PHONES; i++) { 419 if (driver_phones[i] == hash) { 420 printf("Device %" PRIxn " gone.\n", hash); 421 driver_phones[i] = 0; 422 async_obsolete_hangup(i); 423 return; 424 } 425 } 426 } 427 428 /** Handler for keyboard */ 429 static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall) 401 430 { 402 431 /* Ignore parameters, the connection is already opened */ … … 410 439 if (!IPC_GET_IMETHOD(call)) { 411 440 /* TODO: Handle hangup */ 412 async_obsolete_hangup(input_phone);441 close_driver_phone(iid); 413 442 return; 414 443 } 415 444 416 445 switch (IPC_GET_IMETHOD(call)) { 417 case INPUT_EVENT_KEY:418 /* Got key press/release event*/446 case KBD_EVENT: 447 /* Got event from keyboard driver. */ 419 448 retval = 0; 420 449 ev.type = IPC_GET_ARG1(call); … … 437 466 fibril_mutex_unlock(&input_mutex); 438 467 break; 439 case INPUT_EVENT_MOVE: 440 /* Got pointer move event */ 441 gcons_mouse_move((int) IPC_GET_ARG1(call), 442 (int) IPC_GET_ARG2(call)); 443 retval = 0; 444 break; 445 case INPUT_EVENT_BUTTON: 446 /* Got pointer button press/release event */ 468 default: 469 retval = ENOENT; 470 } 471 async_answer_0(callid, retval); 472 } 473 } 474 475 /** Handler for mouse events */ 476 static void mouse_events(ipc_callid_t iid, ipc_call_t *icall) 477 { 478 /* Ignore parameters, the connection is already opened */ 479 while (true) { 480 ipc_call_t call; 481 ipc_callid_t callid = async_get_call(&call); 482 483 int retval; 484 485 if (!IPC_GET_IMETHOD(call)) { 486 /* TODO: Handle hangup */ 487 close_driver_phone(iid); 488 return; 489 } 490 491 switch (IPC_GET_IMETHOD(call)) { 492 case MEVENT_BUTTON: 447 493 if (IPC_GET_ARG1(call) == 1) { 448 494 int newcon = gcons_mouse_btn((bool) IPC_GET_ARG2(call)); … … 452 498 retval = 0; 453 499 break; 500 case MEVENT_MOVE: 501 gcons_mouse_move((int) IPC_GET_ARG1(call), 502 (int) IPC_GET_ARG2(call)); 503 retval = 0; 504 break; 454 505 default: 455 506 retval = ENOENT; 456 507 } 508 457 509 async_answer_0(callid, retval); 458 510 } … … 545 597 546 598 /** Default thread for new connections */ 547 static void client_connection(ipc_callid_t iid, ipc_call_t *icall , void *arg)599 static void client_connection(ipc_callid_t iid, ipc_call_t *icall) 548 600 { 549 601 console_t *cons = NULL; … … 695 747 } 696 748 697 static int connect_input(const char *dev_path) 749 static int async_connect_to_me_hack(int phone, sysarg_t arg1, sysarg_t arg2, 750 sysarg_t arg3, async_client_conn_t client_receiver, ipc_callid_t *hash) 751 { 752 sysarg_t task_hash; 753 sysarg_t phone_hash; 754 int rc = async_obsolete_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, 755 NULL, NULL, NULL, &task_hash, &phone_hash); 756 if (rc != EOK) 757 return rc; 758 759 if (client_receiver != NULL) 760 async_new_connection(task_hash, phone_hash, phone_hash, NULL, 761 client_receiver); 762 763 if (hash != NULL) 764 *hash = phone_hash; 765 766 return EOK; 767 } 768 769 static int connect_keyboard_or_mouse(const char *devname, 770 async_client_conn_t handler, const char *dev) 698 771 { 699 772 int phone; 700 773 devmap_handle_t handle; 701 774 702 int rc = devmap_device_get_handle(dev _path, &handle, 0);775 int rc = devmap_device_get_handle(dev, &handle, 0); 703 776 if (rc == EOK) { 704 777 phone = devmap_obsolete_device_connect(handle, 0); … … 707 780 return phone; 708 781 } 709 } else {782 } else 710 783 return rc; 711 }712 784 713 785 /* NB: The callback connection is slotted for removal */ 714 rc = async_obsolete_connect_to_me(phone, SERVICE_CONSOLE, 0, 0,715 input_events, NULL);716 786 ipc_callid_t hash; 787 rc = async_connect_to_me_hack(phone, SERVICE_CONSOLE, 0, phone, 788 handler, &hash); 717 789 if (rc != EOK) { 718 790 async_obsolete_hangup(phone); … … 722 794 } 723 795 796 driver_phones[phone] = hash; 797 printf("%s: found %s \"%s\" (%" PRIxn ").\n", NAME, devname, dev, hash); 724 798 return phone; 725 799 } 726 800 727 static bool console_srv_init(char *input_dev) 728 { 729 /* Connect to input server */ 730 input_phone = connect_input(input_dev); 731 if (input_phone < 0) 801 static int connect_keyboard(const char *dev) 802 { 803 return connect_keyboard_or_mouse("keyboard", keyboard_events, dev); 804 } 805 806 static int connect_mouse(const char *dev) 807 { 808 return connect_keyboard_or_mouse("mouse", mouse_events, dev); 809 } 810 811 struct hid_class_info { 812 char *classname; 813 int (*connection_func)(const char *); 814 }; 815 816 /** Periodically check for new keyboards in /dev/class/. 817 * 818 * @param arg Class name. 819 * 820 * @return This function should never exit. 821 * 822 */ 823 static int check_new_device_fibril(void *arg) 824 { 825 struct hid_class_info *dev_info = (struct hid_class_info *) arg; 826 827 size_t index = 1; 828 829 while (true) { 830 async_usleep(HOTPLUG_WATCH_INTERVAL); 831 832 char *dev; 833 int rc = asprintf(&dev, "class/%s\\%zu", 834 dev_info->classname, index); 835 if (rc < 0) 836 continue; 837 838 rc = dev_info->connection_func(dev); 839 if (rc > 0) { 840 /* We do not allow unplug. */ 841 index++; 842 } 843 844 free(dev); 845 } 846 847 return EOK; 848 } 849 850 /** Start a fibril monitoring hot-plugged keyboards. 851 */ 852 static void check_new_devices_in_background(int (*connection_func)(const char *), 853 const char *classname) 854 { 855 struct hid_class_info *dev_info = malloc(sizeof(struct hid_class_info)); 856 if (dev_info == NULL) { 857 printf("%s: Out of memory, no hot-plug support.\n", NAME); 858 return; 859 } 860 861 int rc = asprintf(&dev_info->classname, "%s", classname); 862 if (rc < 0) { 863 printf("%s: Failed to format classname: %s.\n", NAME, 864 str_error(rc)); 865 return; 866 } 867 868 dev_info->connection_func = connection_func; 869 870 fid_t fid = fibril_create(check_new_device_fibril, (void *) dev_info); 871 if (!fid) { 872 printf("%s: Failed to create hot-plug fibril for %s.\n", NAME, 873 classname); 874 return; 875 } 876 877 fibril_add_ready(fid); 878 } 879 880 static bool console_srv_init(char *kdev) 881 { 882 /* Connect to input device */ 883 kbd_phone = connect_keyboard(kdev); 884 if (kbd_phone < 0) 732 885 return false; 886 887 mouse_phone = connect_mouse("hid_in/mouse"); 888 if (mouse_phone < 0) { 889 printf("%s: Failed to connect to mouse device %s\n", NAME, 890 str_error(mouse_phone)); 891 } 733 892 734 893 /* Connect to framebuffer driver */ … … 813 972 printf("%s: Error registering kconsole notifications\n", NAME); 814 973 974 /* Start fibril for checking on hot-plugged keyboards. */ 975 check_new_devices_in_background(connect_keyboard, "keyboard"); 976 check_new_devices_in_background(connect_mouse, "mouse"); 977 815 978 return true; 816 979 } … … 818 981 static void usage(void) 819 982 { 820 printf("Usage: console <input _dev>\n");983 printf("Usage: console <input>\n"); 821 984 } 822 985
Note:
See TracChangeset
for help on using the changeset viewer.