Changes in uspace/srv/hid/console/console.c [ffa2c8ef:8c74d15] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/console/console.c
rffa2c8ef r8c74d15 41 41 #include <ipc/ns.h> 42 42 #include <errno.h> 43 #include <str_error.h> 43 44 #include <ipc/console.h> 44 45 #include <unistd.h> … … 56 57 #include <io/style.h> 57 58 #include <io/screenbuffer.h> 59 #include <inttypes.h> 58 60 59 61 #include "console.h" … … 64 66 #define NAME "console" 65 67 #define NAMESPACE "term" 68 /** Interval for checking for new keyboard (1/4s). */ 69 #define HOTPLUG_WATCH_INTERVAL (1000 * 250) 70 71 /* Kernel defines 32 but does not export it. */ 72 #define MAX_IPC_OUTGOING_PHONES 128 73 /** To allow proper phone closing. */ 74 static ipc_callid_t driver_phones[MAX_IPC_OUTGOING_PHONES] = { 0 }; 66 75 67 76 /** Phone to the keyboard driver. */ … … 88 97 } console_t; 89 98 99 100 90 101 /** Array of data for virtual consoles */ 91 102 static console_t consoles[CONSOLE_COUNT]; … … 317 328 static void change_console(console_t *cons) 318 329 { 319 if (cons == active_console) 330 if (cons == active_console) { 320 331 return; 332 } 321 333 322 334 fb_pending_flush(); … … 397 409 } 398 410 411 static void close_driver_phone(ipc_callid_t hash) 412 { 413 int i; 414 for (i = 0; i < MAX_IPC_OUTGOING_PHONES; i++) { 415 if (driver_phones[i] == hash) { 416 printf("Device %" PRIxn " gone.\n", hash); 417 driver_phones[i] = 0; 418 async_hangup(i); 419 return; 420 } 421 } 422 } 423 399 424 /** Handler for keyboard */ 400 425 static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall) … … 411 436 case IPC_M_PHONE_HUNGUP: 412 437 /* TODO: Handle hangup */ 438 close_driver_phone(iid); 413 439 return; 414 440 case KBD_EVENT: … … 454 480 case IPC_M_PHONE_HUNGUP: 455 481 /* TODO: Handle hangup */ 482 close_driver_phone(iid); 456 483 return; 457 484 case MEVENT_BUTTON: 458 485 if (IPC_GET_ARG1(call) == 1) { 459 486 int newcon = gcons_mouse_btn((bool) IPC_GET_ARG2(call)); 460 if (newcon != -1) 487 if (newcon != -1) { 461 488 change_console(&consoles[newcon]); 489 } 462 490 } 463 491 retval = 0; … … 710 738 } 711 739 740 static int async_connect_to_me_hack(int phone, sysarg_t arg1, sysarg_t arg2, 741 sysarg_t arg3, async_client_conn_t client_receiver, ipc_callid_t *hash) 742 { 743 sysarg_t task_hash; 744 sysarg_t phone_hash; 745 int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, 746 NULL, NULL, NULL, &task_hash, &phone_hash); 747 if (rc != EOK) 748 return rc; 749 750 if (client_receiver != NULL) 751 async_new_connection(task_hash, phone_hash, phone_hash, NULL, 752 client_receiver); 753 754 if (hash != NULL) { 755 *hash = phone_hash; 756 } 757 758 return EOK; 759 } 760 761 static int connect_keyboard_or_mouse(const char *devname, 762 async_client_conn_t handler, const char *path) 763 { 764 int fd = open(path, O_RDONLY); 765 if (fd < 0) { 766 return fd; 767 } 768 769 int phone = fd_phone(fd); 770 close(fd); 771 if (phone < 0) { 772 printf(NAME ": Failed to connect to input device\n"); 773 return phone; 774 } 775 776 ipc_callid_t hash; 777 int rc = async_connect_to_me_hack(phone, SERVICE_CONSOLE, 0, phone, 778 handler, &hash); 779 if (rc != EOK) { 780 async_hangup(phone); 781 printf(NAME ": " \ 782 "Failed to create callback from input device: %s.\n", 783 str_error(rc)); 784 return rc; 785 } 786 787 driver_phones[phone] = hash; 788 789 printf(NAME ": found %s \"%s\" (%" PRIxn ").\n", devname, path, hash); 790 791 return phone; 792 } 793 794 static int connect_keyboard(const char *path) 795 { 796 return connect_keyboard_or_mouse("keyboard", keyboard_events, path); 797 } 798 799 static int connect_mouse(const char *path) 800 { 801 return connect_keyboard_or_mouse("mouse", mouse_events, path); 802 } 803 804 struct hid_class_info { 805 char *classname; 806 int (*connection_func)(const char *); 807 }; 808 809 /** Periodically check for new keyboards in /dev/class/. 810 * 811 * @param arg Class name. 812 * @return This function should never exit. 813 */ 814 static int check_new_device_fibril(void *arg) 815 { 816 struct hid_class_info *dev_info = arg; 817 818 size_t index = 1; 819 820 while (true) { 821 async_usleep(HOTPLUG_WATCH_INTERVAL); 822 char *path; 823 int rc = asprintf(&path, "/dev/class/%s\\%zu", 824 dev_info->classname, index); 825 if (rc < 0) { 826 continue; 827 } 828 rc = 0; 829 rc = dev_info->connection_func(path); 830 if (rc > 0) { 831 /* We do not allow unplug. */ 832 index++; 833 } 834 835 free(path); 836 } 837 838 return EOK; 839 } 840 841 842 /** Start a fibril monitoring hot-plugged keyboards. 843 */ 844 static void check_new_devices_in_background(int (*connection_func)(const char *), 845 const char *classname) 846 { 847 struct hid_class_info *dev_info = malloc(sizeof(struct hid_class_info)); 848 if (dev_info == NULL) { 849 printf(NAME ": " \ 850 "out of memory, will not start hot-plug-watch fibril.\n"); 851 return; 852 } 853 int rc; 854 855 rc = asprintf(&dev_info->classname, "%s", classname); 856 if (rc < 0) { 857 printf(NAME ": failed to format classname: %s.\n", 858 str_error(rc)); 859 return; 860 } 861 dev_info->connection_func = connection_func; 862 863 fid_t fid = fibril_create(check_new_device_fibril, (void *)dev_info); 864 if (!fid) { 865 printf(NAME 866 ": failed to create hot-plug-watch fibril for %s.\n", 867 classname); 868 return; 869 } 870 fibril_add_ready(fid); 871 } 872 712 873 static bool console_init(char *input) 713 874 { 714 875 /* 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); 876 kbd_phone = connect_keyboard(input); 877 if (kbd_phone < 0) { 718 878 return false; 719 879 } 720 721 kbd_phone = fd_phone(input_fd); 722 if (kbd_phone < 0) { 723 printf(NAME ": Failed to connect to input device\n"); 724 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); 880 881 mouse_phone = connect_mouse("/dev/hid_in/mouse"); 744 882 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: 883 printf(NAME ": Failed to connect to mouse device: %s.\n", 884 str_error(mouse_phone)); 885 } 757 886 758 887 /* Connect to framebuffer driver */ … … 837 966 printf(NAME ": Error registering kconsole notifications\n"); 838 967 968 /* Start fibril for checking on hot-plugged keyboards. */ 969 check_new_devices_in_background(connect_keyboard, "keyboard"); 970 check_new_devices_in_background(connect_mouse, "mouse"); 971 839 972 return true; 840 973 } … … 856 989 if (!console_init(argv[1])) 857 990 return -1; 858 991 859 992 printf(NAME ": Accepting connections\n"); 860 993 async_manager();
Note:
See TracChangeset
for help on using the changeset viewer.