Changeset 854eddd6 in mainline for uspace/srv/hid/console/console.c


Ignore:
Timestamp:
2011-06-14T21:40:28Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
662da50, e3a46c2
Parents:
ecb692a2
Message:

Route mouse input through input server. Remove device-handling code from
console server.

File:
1 edited

Legend:

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

    recb692a2 r854eddd6  
    11/*
    22 * Copyright (c) 2006 Josef Cejka
     3 * Copyright (c) 2011 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    3637#include <ipc/input.h>
    3738#include <io/keycode.h>
    38 #include <ipc/mouse.h>
    3939#include <ipc/fb.h>
    4040#include <ipc/services.h>
     
    6060#include <io/style.h>
    6161#include <io/screenbuffer.h>
    62 #include <inttypes.h>
    6362
    6463#include "console.h"
     
    6665#include "keybuffer.h"
    6766
    68 // FIXME: remove this header
    69 #include <kernel/ipc/ipc_methods.h>
    70 
    7167#define NAME       "console"
    7268#define NAMESPACE  "term"
    7369
    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;
     70/** Phone to the input server. */
     71static int input_phone;
    8872
    8973/** Information about framebuffer */
     
    155139}
    156140
    157 static void kbd_yield(void)
    158 {
    159         async_obsolete_req_0_0(kbd_phone, INPUT_YIELD);
    160 }
    161 
    162 static void kbd_reclaim(void)
    163 {
    164         async_obsolete_req_0_0(kbd_phone, INPUT_RECLAIM);
     141static void input_yield(void)
     142{
     143        async_obsolete_req_0_0(input_phone, INPUT_YIELD);
     144}
     145
     146static void input_reclaim(void)
     147{
     148        async_obsolete_req_0_0(input_phone, INPUT_RECLAIM);
    165149}
    166150
     
    343327                gcons_in_kernel();
    344328                screen_yield();
    345                 kbd_yield();
     329                input_yield();
    346330                async_obsolete_serialize_end();
    347331               
     
    358342                if (active_console == kernel_console) {
    359343                        screen_reclaim();
    360                         kbd_reclaim();
     344                        input_reclaim();
    361345                        gcons_redraw_console();
    362346                }
     
    413397}
    414398
    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, void *arg)
     399/** Handler for input events */
     400static void input_events(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    430401{
    431402        /* Ignore parameters, the connection is already opened */
     
    439410                if (!IPC_GET_IMETHOD(call)) {
    440411                        /* TODO: Handle hangup */
    441                         close_driver_phone(iid);
     412                        async_obsolete_hangup(input_phone);
    442413                        return;
    443414                }
    444415               
    445416                switch (IPC_GET_IMETHOD(call)) {
    446                 case INPUT_EVENT:
    447                         /* Got event from keyboard driver. */
     417                case INPUT_EVENT_KEY:
     418                        /* Got key press/release event */
    448419                        retval = 0;
    449420                        ev.type = IPC_GET_ARG1(call);
     
    466437                        fibril_mutex_unlock(&input_mutex);
    467438                        break;
    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, void *arg)
    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:
     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 */
    493447                        if (IPC_GET_ARG1(call) == 1) {
    494448                                int newcon = gcons_mouse_btn((bool) IPC_GET_ARG2(call));
     
    498452                        retval = 0;
    499453                        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;
    505454                default:
    506455                        retval = ENOENT;
    507456                }
    508 
    509457                async_answer_0(callid, retval);
    510458        }
     
    747695}
    748696
    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, NULL);
    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)
     697static int connect_input(const char *dev_path)
    771698{
    772699        int phone;
    773700        devmap_handle_t handle;
    774701       
    775         int rc = devmap_device_get_handle(dev, &handle, 0);
     702        int rc = devmap_device_get_handle(dev_path, &handle, 0);
    776703        if (rc == EOK) {
    777704                phone = devmap_obsolete_device_connect(handle, 0);
     
    780707                        return phone;
    781708                }
    782         } else
     709        } else {
    783710                return rc;
     711        }
    784712       
    785713        /* NB: The callback connection is slotted for removal */
    786         ipc_callid_t hash;
    787         rc = async_connect_to_me_hack(phone, SERVICE_CONSOLE, 0, phone,
    788             handler, &hash);
     714        rc = async_obsolete_connect_to_me(phone, SERVICE_CONSOLE, 0, 0,
     715            input_events, NULL);
     716
    789717        if (rc != EOK) {
    790718                async_obsolete_hangup(phone);
     
    794722        }
    795723       
    796         driver_phones[phone] = hash;
    797         printf("%s: found %s \"%s\" (%" PRIxn ").\n", NAME, devname, dev, hash);
    798724        return phone;
    799725}
    800726
    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)
     727static 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)
    885732                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         }
    892733       
    893734        /* Connect to framebuffer driver */
     
    972813                printf("%s: Error registering kconsole notifications\n", NAME);
    973814       
    974         /* Start fibril for checking on hot-plugged keyboards. */
    975         check_new_devices_in_background(connect_mouse, "mouse");
    976        
    977815        return true;
    978816}
     
    980818static void usage(void)
    981819{
    982         printf("Usage: console <input>\n");
     820        printf("Usage: console <input_dev>\n");
    983821}
    984822
Note: See TracChangeset for help on using the changeset viewer.