Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/console/console.c

    r103ae7f8 rffa2c8ef  
    4141#include <ipc/ns.h>
    4242#include <errno.h>
    43 #include <str_error.h>
    4443#include <ipc/console.h>
    4544#include <unistd.h>
     
    6564#define NAME       "console"
    6665#define NAMESPACE  "term"
    67 /** Interval for checking for new keyboard (1/4s). */
    68 #define HOTPLUG_WATCH_INTERVAL (1000 * 250)
    6966
    7067/** Phone to the keyboard driver. */
     
    320317static void change_console(console_t *cons)
    321318{
    322         if (cons == active_console) {
     319        if (cons == active_console)
    323320                return;
    324         }
    325321       
    326322        fb_pending_flush();
     
    462458                        if (IPC_GET_ARG1(call) == 1) {
    463459                                int newcon = gcons_mouse_btn((bool) IPC_GET_ARG2(call));
    464                                 if (newcon != -1) {
     460                                if (newcon != -1)
    465461                                        change_console(&consoles[newcon]);
    466                                 }
    467462                        }
    468463                        retval = 0;
     
    715710}
    716711
    717 static int connect_keyboard_or_mouse(const char *devname,
    718     async_client_conn_t handler, const char *path)
    719 {
    720         int fd = open(path, O_RDONLY);
    721         if (fd < 0) {
    722                 return fd;
    723         }
    724        
    725         int phone = fd_phone(fd);
    726         if (phone < 0) {
     712static 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);
     718                return false;
     719        }
     720       
     721        kbd_phone = fd_phone(input_fd);
     722        if (kbd_phone < 0) {
    727723                printf(NAME ": Failed to connect to input device\n");
    728                 return phone;
    729         }
    730        
    731         int rc = async_connect_to_me(phone, SERVICE_CONSOLE, 0, 0, handler);
    732         if (rc != EOK) {
    733                 printf(NAME ": " \
    734                     "Failed to create callback from input device: %s.\n",
    735                     str_error(rc));
    736                 return rc;
    737         }
    738        
    739         printf(NAME ": found %s \"%s\".\n", devname, path);
    740 
    741         return phone;
    742 }
    743 
    744 static int connect_keyboard(const char *path)
    745 {
    746         return connect_keyboard_or_mouse("keyboard", keyboard_events, path);
    747 }
    748 
    749 static int connect_mouse(const char *path)
    750 {
    751         return connect_keyboard_or_mouse("mouse", mouse_events, path);
    752 }
    753 
    754 struct hid_class_info {
    755         char *classname;
    756         int (*connection_func)(const char *);
    757 };
    758 
    759 /** Periodically check for new keyboards in /dev/class/.
    760  *
    761  * @param arg Class name.
    762  * @return This function should never exit.
    763  */
    764 static int check_new_device_fibril(void *arg)
    765 {
    766         struct hid_class_info *dev_info = arg;
    767 
    768         size_t index = 1;
    769 
    770         while (true) {
    771                 async_usleep(HOTPLUG_WATCH_INTERVAL);
    772                 char *path;
    773                 int rc = asprintf(&path, "/dev/class/%s\\%zu",
    774                     dev_info->classname, index);
    775                 if (rc < 0) {
    776                         continue;
    777                 }
    778                 rc = 0;
    779                 rc = dev_info->connection_func(path);
    780                 if (rc > 0) {
    781                         /* We do not allow unplug. */
    782                         index++;
    783                 }
    784 
    785                 free(path);
    786         }
    787 
    788         return EOK;
    789 }
    790 
    791 
    792 /** Start a fibril monitoring hot-plugged keyboards.
    793  */
    794 static void check_new_devices_in_background(int (*connection_func)(const char *),
    795     const char *classname)
    796 {
    797         struct hid_class_info *dev_info = malloc(sizeof(struct hid_class_info));
    798         if (dev_info == NULL) {
    799                 printf(NAME ": " \
    800                     "out of memory, will not start hot-plug-watch fibril.\n");
    801                 return;
    802         }
    803         int rc;
    804 
    805         rc = asprintf(&dev_info->classname, "%s", classname);
    806         if (rc < 0) {
    807                 printf(NAME ": failed to format classname: %s.\n",
    808                     str_error(rc));
    809                 return;
    810         }
    811         dev_info->connection_func = connection_func;
    812 
    813         fid_t fid = fibril_create(check_new_device_fibril, (void *)dev_info);
    814         if (!fid) {
    815                 printf(NAME
    816                     ": failed to create hot-plug-watch fibril for %s.\n",
    817                     classname);
    818                 return;
    819         }
    820         fibril_add_ready(fid);
    821 }
    822 
    823 static bool console_init(char *input)
    824 {
    825         /* Connect to input device */
    826         kbd_phone = connect_keyboard(input);
    827         if (kbd_phone < 0) {
    828724                return false;
    829725        }
    830 
    831         mouse_phone = connect_mouse("/dev/hid_in/mouse");
     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);
    832744        if (mouse_phone < 0) {
    833                 printf(NAME ": Failed to connect to mouse device: %s.\n",
    834                     str_error(mouse_phone));
    835         }
     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       
     756skip_mouse:
    836757       
    837758        /* Connect to framebuffer driver */
     
    916837                printf(NAME ": Error registering kconsole notifications\n");
    917838       
    918         /* Start fibril for checking on hot-plugged keyboards. */
    919         check_new_devices_in_background(connect_keyboard, "keyboard");
    920         check_new_devices_in_background(connect_mouse, "mouse");
    921 
    922839        return true;
    923840}
     
    939856        if (!console_init(argv[1]))
    940857                return -1;
    941 
     858       
    942859        printf(NAME ": Accepting connections\n");
    943860        async_manager();
Note: See TracChangeset for help on using the changeset viewer.