Ignore:
File:
1 edited

Legend:

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

    rffa2c8ef r30db06c  
    4141#include <ipc/ns.h>
    4242#include <errno.h>
     43#include <str_error.h>
    4344#include <ipc/console.h>
    4445#include <unistd.h>
     
    6465#define NAME       "console"
    6566#define NAMESPACE  "term"
     67/** Interval for checking for new keyboard (1/4s). */
     68#define HOTPLUG_WATCH_INTERVAL (1000 * 250)
    6669
    6770/** Phone to the keyboard driver. */
     
    317320static void change_console(console_t *cons)
    318321{
    319         if (cons == active_console)
     322        if (cons == active_console) {
    320323                return;
     324        }
    321325       
    322326        fb_pending_flush();
     
    458462                        if (IPC_GET_ARG1(call) == 1) {
    459463                                int newcon = gcons_mouse_btn((bool) IPC_GET_ARG2(call));
    460                                 if (newcon != -1)
     464                                if (newcon != -1) {
    461465                                        change_console(&consoles[newcon]);
     466                                }
    462467                        }
    463468                        retval = 0;
     
    710715}
    711716
     717static int connect_keyboard(char *path)
     718{
     719        int fd = open(path, O_RDONLY);
     720        if (fd < 0) {
     721                return fd;
     722        }
     723       
     724        int phone = fd_phone(fd);
     725        if (phone < 0) {
     726                printf(NAME ": Failed to connect to input device\n");
     727                return phone;
     728        }
     729       
     730        int rc = async_connect_to_me(phone, SERVICE_CONSOLE, 0, 0,
     731            keyboard_events);
     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 keyboard \"%s\".\n", path);
     740
     741        return phone;
     742}
     743
     744
     745/** Periodically check for new keyboards in /dev/class/.
     746 *
     747 * @param arg Class name.
     748 * @return This function should never exit.
     749 */
     750static int check_new_keyboards(void *arg)
     751{
     752        char *class_name = (char *) arg;
     753
     754        size_t index = 1;
     755
     756        while (true) {
     757                async_usleep(HOTPLUG_WATCH_INTERVAL);
     758                char *path;
     759                int rc = asprintf(&path, "/dev/class/%s\\%zu",
     760                    class_name, index);
     761                if (rc < 0) {
     762                        continue;
     763                }
     764                rc = 0;
     765                rc = connect_keyboard(path);
     766                if (rc > 0) {
     767                        /* We do not allow unplug. */
     768                        index++;
     769                }
     770
     771                free(path);
     772        }
     773
     774        return EOK;
     775}
     776
     777
     778/** Start a fibril monitoring hot-plugged keyboards.
     779 */
     780static void check_new_keyboards_in_background()
     781{
     782        fid_t fid = fibril_create(check_new_keyboards, (void *)"keyboard");
     783        if (!fid) {
     784                printf(NAME ": failed to create hot-plug-watch fibril.\n");
     785                return;
     786        }
     787        fibril_add_ready(fid);
     788}
     789
    712790static bool console_init(char *input)
    713791{
    714792        /* 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);
     793        kbd_phone = connect_keyboard(input);
     794        if (kbd_phone < 0) {
    718795                return false;
    719796        }
    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        
     797
    734798        /* Connect to mouse device */
    735799        mouse_phone = -1;
     
    837901                printf(NAME ": Error registering kconsole notifications\n");
    838902       
     903        /* Start fibril for checking on hot-plugged keyboards. */
     904        check_new_keyboards_in_background();
     905
    839906        return true;
    840907}
     
    856923        if (!console_init(argv[1]))
    857924                return -1;
    858        
     925
    859926        printf(NAME ": Accepting connections\n");
    860927        async_manager();
Note: See TracChangeset for help on using the changeset viewer.