Ignore:
File:
1 edited

Legend:

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

    rc928bb7 r73d8600  
    4242#include <ipc/services.h>
    4343#include <ipc/input.h>
    44 #include <sysinfo.h>
     44#include <config.h>
    4545#include <stdio.h>
    4646#include <unistd.h>
    4747#include <stdlib.h>
    48 #include <stdio.h>
    4948#include <ns.h>
    5049#include <async.h>
     
    5453#include <io/keycode.h>
    5554#include <loc.h>
     55#include <str_error.h>
     56#include <char_dev_iface.h>
     57#include <fibril.h>
    5658#include "layout.h"
    5759#include "kbd.h"
     
    6062#include "mouse.h"
    6163#include "mouse_proto.h"
     64#include "serial.h"
    6265#include "input.h"
    6366
     
    7174};
    7275
    73 static void kbd_devs_yield(void);
    74 static void kbd_devs_reclaim(void);
    75 
    76 async_sess_t *client_sess = NULL;
     76typedef struct {
     77        /** Link into the list of clients */
     78        link_t link;
     79       
     80        /** Indicate whether the client is active */
     81        bool active;
     82       
     83        /** Client callback session */
     84        async_sess_t *sess;
     85} client_t;
     86
     87/** List of clients */
     88static list_t clients;
     89static client_t *active_client = NULL;
     90
     91/** Kernel override */
     92static bool active = true;
     93
     94/** Serial console specified by the user */
     95static char *serial_console;
    7796
    7897/** List of keyboard devices */
     
    82101static list_t mouse_devs;
    83102
    84 bool irc_service = false;
    85 async_sess_t *irc_sess = NULL;
     103/** List of serial devices */
     104static list_t serial_devs;
    86105
    87106static FIBRIL_MUTEX_INITIALIZE(discovery_lock);
     107
     108static void *client_data_create(void)
     109{
     110        client_t *client = (client_t *) calloc(1, sizeof(client_t));
     111        if (client == NULL)
     112                return NULL;
     113       
     114        link_initialize(&client->link);
     115        client->active = false;
     116        client->sess = NULL;
     117       
     118        list_append(&client->link, &clients);
     119       
     120        return client;
     121}
     122
     123static void client_data_destroy(void *data)
     124{
     125        client_t *client = (client_t *) data;
     126       
     127        list_remove(&client->link);
     128        free(client);
     129}
    88130
    89131void kbd_push_data(kbd_dev_t *kdev, sysarg_t data)
     
    103145       
    104146        switch (key) {
    105         case KC_LCTRL: mod_mask = KM_LCTRL; break;
    106         case KC_RCTRL: mod_mask = KM_RCTRL; break;
    107         case KC_LSHIFT: mod_mask = KM_LSHIFT; break;
    108         case KC_RSHIFT: mod_mask = KM_RSHIFT; break;
    109         case KC_LALT: mod_mask = KM_LALT; break;
    110         case KC_RALT: mod_mask = KM_RALT; break;
    111         default: mod_mask = 0; break;
     147        case KC_LCTRL:
     148                mod_mask = KM_LCTRL;
     149                break;
     150        case KC_RCTRL:
     151                mod_mask = KM_RCTRL;
     152                break;
     153        case KC_LSHIFT:
     154                mod_mask = KM_LSHIFT;
     155                break;
     156        case KC_RSHIFT:
     157                mod_mask = KM_RSHIFT;
     158                break;
     159        case KC_LALT:
     160                mod_mask = KM_LALT;
     161                break;
     162        case KC_RALT:
     163                mod_mask = KM_RALT;
     164                break;
     165        default:
     166                mod_mask = 0;
    112167        }
    113168       
     
    120175       
    121176        switch (key) {
    122         case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break;
    123         case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break;
    124         case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break;
    125         default: mod_mask = 0; break;
     177        case KC_CAPS_LOCK:
     178                mod_mask = KM_CAPS_LOCK;
     179                break;
     180        case KC_NUM_LOCK:
     181                mod_mask = KM_NUM_LOCK;
     182                break;
     183        case KC_SCROLL_LOCK:
     184                mod_mask = KM_SCROLL_LOCK;
     185                break;
     186        default:
     187                mod_mask = 0;
    126188        }
    127189       
     
    143205        }
    144206       
    145         if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
    146             key == KC_F1) {
     207        // TODO: More elegant layout switching
     208       
     209        if ((type == KEY_PRESS) && (kdev->mods & KM_LCTRL) &&
     210            (key == KC_F1)) {
    147211                layout_destroy(kdev->active_layout);
    148212                kdev->active_layout = layout_create(layout[0]);
     
    150214        }
    151215       
    152         if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
    153             key == KC_F2) {
     216        if ((type == KEY_PRESS) && (kdev->mods & KM_LCTRL) &&
     217            (key == KC_F2)) {
    154218                layout_destroy(kdev->active_layout);
    155219                kdev->active_layout = layout_create(layout[1]);
     
    157221        }
    158222       
    159         if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
    160             key == KC_F3) {
     223        if ((type == KEY_PRESS) && (kdev->mods & KM_LCTRL) &&
     224            (key == KC_F3)) {
    161225                layout_destroy(kdev->active_layout);
    162226                kdev->active_layout = layout_create(layout[2]);
     
    164228        }
    165229       
    166         if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
    167             key == KC_F4) {
     230        if ((type == KEY_PRESS) && (kdev->mods & KM_LCTRL) &&
     231            (key == KC_F4)) {
    168232                layout_destroy(kdev->active_layout);
    169233                kdev->active_layout = layout_create(layout[3]);
     
    177241        ev.c = layout_parse_ev(kdev->active_layout, &ev);
    178242       
    179         async_exch_t *exch = async_exchange_begin(client_sess);
    180         async_msg_4(exch, INPUT_EVENT_KEY, ev.type, ev.key, ev.mods, ev.c);
    181         async_exchange_end(exch);
    182 }
    183 
    184 /** Mouse pointer has moved. */
     243        list_foreach(clients, link, client_t, client) {
     244                if (client->active) {
     245                        async_exch_t *exch = async_exchange_begin(client->sess);
     246                        async_msg_4(exch, INPUT_EVENT_KEY, ev.type, ev.key, ev.mods, ev.c);
     247                        async_exchange_end(exch);
     248                }
     249        }
     250}
     251
     252/** Mouse pointer has moved (relative mode). */
    185253void mouse_push_event_move(mouse_dev_t *mdev, int dx, int dy, int dz)
    186254{
    187         async_exch_t *exch = async_exchange_begin(client_sess);
    188         if (dx || dy)
    189                 async_msg_2(exch, INPUT_EVENT_MOVE, dx, dy);
    190         if (dz) {
    191                 // TODO: Implement proper wheel support
    192                 keycode_t code = dz > 0 ? KC_UP : KC_DOWN;
    193                 for (int i = 0; i < 3; ++i) {
    194                         async_msg_4(exch, INPUT_EVENT_KEY, KEY_PRESS, code, 0, 0);
    195                 }
    196                 async_msg_4(exch, INPUT_EVENT_KEY, KEY_RELEASE, code, 0, 0);
    197         }
    198         async_exchange_end(exch);
    199 }
    200 
    201 /** Mouse pointer has moved in absolute mode. */
     255        list_foreach(clients, link, client_t, client) {
     256                if (client->active) {
     257                        async_exch_t *exch = async_exchange_begin(client->sess);
     258                       
     259                        if ((dx) || (dy))
     260                                async_msg_2(exch, INPUT_EVENT_MOVE, dx, dy);
     261                       
     262                        if (dz) {
     263                                // TODO: Implement proper wheel support
     264                                keycode_t code = dz > 0 ? KC_UP : KC_DOWN;
     265                               
     266                                for (unsigned int i = 0; i < 3; i++)
     267                                        async_msg_4(exch, INPUT_EVENT_KEY, KEY_PRESS, code, 0, 0);
     268                               
     269                                async_msg_4(exch, INPUT_EVENT_KEY, KEY_RELEASE, code, 0, 0);
     270                        }
     271                       
     272                        async_exchange_end(exch);
     273                }
     274        }
     275}
     276
     277/** Mouse pointer has moved (absolute mode). */
    202278void mouse_push_event_abs_move(mouse_dev_t *mdev, unsigned int x, unsigned int y,
    203279    unsigned int max_x, unsigned int max_y)
    204280{
    205         if (max_x && max_y) {
    206                 async_exch_t *exch = async_exchange_begin(client_sess);
    207                 async_msg_4(exch, INPUT_EVENT_ABS_MOVE, x, y, max_x, max_y);
    208                 async_exchange_end(exch);
     281        list_foreach(clients, link, client_t, client) {
     282                if (client->active) {
     283                        if ((max_x) && (max_y)) {
     284                                async_exch_t *exch = async_exchange_begin(client->sess);
     285                                async_msg_4(exch, INPUT_EVENT_ABS_MOVE, x, y, max_x, max_y);
     286                                async_exchange_end(exch);
     287                        }
     288                }
    209289        }
    210290}
     
    213293void mouse_push_event_button(mouse_dev_t *mdev, int bnum, int press)
    214294{
    215         async_exch_t *exch = async_exchange_begin(client_sess);
    216         async_msg_2(exch, INPUT_EVENT_BUTTON, bnum, press);
    217         async_exchange_end(exch);
    218 }
    219 
     295        list_foreach(clients, link, client_t, client) {
     296                if (client->active) {
     297                        async_exch_t *exch = async_exchange_begin(client->sess);
     298                        async_msg_2(exch, INPUT_EVENT_BUTTON, bnum, press);
     299                        async_exchange_end(exch);
     300                }
     301        }
     302}
     303
     304/** Arbitrate client actiovation */
     305static void client_arbitration(void)
     306{
     307        /* Mutual exclusion of active clients */
     308        list_foreach(clients, link, client_t, client)
     309                client->active = ((active) && (client == active_client));
     310       
     311        /* Notify clients about the arbitration */
     312        list_foreach(clients, link, client_t, client) {
     313                async_exch_t *exch = async_exchange_begin(client->sess);
     314                async_msg_0(exch, client->active ?
     315                    INPUT_EVENT_ACTIVE : INPUT_EVENT_DEACTIVE);
     316                async_exchange_end(exch);
     317        }
     318}
     319
     320/** New client connection */
    220321static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    221322{
     323        client_t *client = (client_t *) async_get_client_data();
     324        if (client == NULL) {
     325                async_answer_0(iid, ENOMEM);
     326                return;
     327        }
     328       
    222329        async_answer_0(iid, EOK);
    223330       
     
    227334               
    228335                if (!IPC_GET_IMETHOD(call)) {
    229                         if (client_sess != NULL) {
    230                                 async_hangup(client_sess);
    231                                 client_sess = NULL;
     336                        if (client->sess != NULL) {
     337                                async_hangup(client->sess);
     338                                client->sess = NULL;
    232339                        }
    233340                       
     
    239346                    async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
    240347                if (sess != NULL) {
    241                         if (client_sess == NULL) {
    242                                 client_sess = sess;
     348                        if (client->sess == NULL) {
     349                                client->sess = sess;
    243350                                async_answer_0(callid, EOK);
    244351                        } else
     
    246353                } else {
    247354                        switch (IPC_GET_IMETHOD(call)) {
    248                         case INPUT_YIELD:
    249                                 kbd_devs_yield();
    250                                 async_answer_0(callid, EOK);
    251                                 break;
    252                         case INPUT_RECLAIM:
    253                                 kbd_devs_reclaim();
     355                        case INPUT_ACTIVATE:
     356                                active_client = client;
     357                                client_arbitration();
    254358                                async_answer_0(callid, EOK);
    255359                                break;
     
    261365}
    262366
     367static void kconsole_event_handler(ipc_callid_t callid, ipc_call_t *call,
     368    void *arg)
     369{
     370        if (IPC_GET_ARG1(*call)) {
     371                /* Kernel console activated */
     372                active = false;
     373        } else {
     374                /* Kernel console deactivated */
     375                active = true;
     376        }
     377       
     378        client_arbitration();
     379}
     380
    263381static kbd_dev_t *kbd_dev_new(void)
    264382{
     
    270388        }
    271389       
    272         link_initialize(&kdev->kbd_devs);
     390        link_initialize(&kdev->link);
    273391       
    274392        kdev->mods = KM_NUM_LOCK;
     
    283401        mouse_dev_t *mdev = calloc(1, sizeof(mouse_dev_t));
    284402        if (mdev == NULL) {
    285                 printf("%s: Error allocating keyboard device. "
     403                printf("%s: Error allocating mouse device. "
    286404                    "Out of memory.\n", NAME);
    287405                return NULL;
    288406        }
    289407       
    290         link_initialize(&mdev->mouse_devs);
     408        link_initialize(&mdev->link);
    291409       
    292410        return mdev;
     411}
     412
     413static serial_dev_t *serial_dev_new(void)
     414{
     415        serial_dev_t *sdev = calloc(1, sizeof(serial_dev_t));
     416        if (sdev == NULL) {
     417                printf("%s: Error allocating serial device. "
     418                    "Out of memory.\n", NAME);
     419                return NULL;
     420        }
     421       
     422        sdev->kdev = kbd_dev_new();
     423        if (sdev->kdev == NULL) {
     424                free(sdev);
     425                return NULL;
     426        }
     427
     428        link_initialize(&sdev->link);
     429       
     430        return sdev;
    293431}
    294432
     
    314452        }
    315453       
    316         list_append(&kdev->kbd_devs, &kbd_devs);
     454        list_append(&kdev->link, &kbd_devs);
    317455        return;
    318456       
     
    342480        }
    343481       
    344         list_append(&mdev->mouse_devs, &mouse_devs);
     482        list_append(&mdev->link, &mouse_devs);
    345483        return;
    346484       
     
    351489/** Add new kbdev device.
    352490 *
    353  * @param service_id    Service ID of the keyboard device
     491 * @param service_id Service ID of the keyboard device
    354492 *
    355493 */
     
    375513        }
    376514       
    377         list_append(&kdev->kbd_devs, &kbd_devs);
     515        list_append(&kdev->link, &kbd_devs);
    378516        *kdevp = kdev;
    379517        return EOK;
     
    388526/** Add new mousedev device.
    389527 *
    390  * @param service_id    Service ID of the mouse device
     528 * @param service_id Service ID of the mouse device
    391529 *
    392530 */
     
    412550        }
    413551       
    414         list_append(&mdev->mouse_devs, &mouse_devs);
     552        list_append(&mdev->link, &mouse_devs);
    415553        *mdevp = mdev;
    416554        return EOK;
     
    420558        return -1;
    421559}
     560
     561static int serial_consumer(void *arg)
     562{
     563        serial_dev_t *sdev = (serial_dev_t *) arg;
     564
     565        while (true) {
     566                uint8_t data;
     567
     568                char_dev_read(sdev->sess, &data, sizeof(data));
     569                kbd_push_data(sdev->kdev, data);
     570        }
     571
     572        return EOK;
     573}
     574
     575/** Add new serial console device.
     576 *
     577 * @param service_id Service ID of the chardev device
     578 *
     579 */
     580static int serial_add_srldev(service_id_t service_id, serial_dev_t **sdevp)
     581{
     582        bool match = false;
     583
     584        serial_dev_t *sdev = serial_dev_new();
     585        if (sdev == NULL)
     586                return -1;
     587       
     588        sdev->kdev->svc_id = service_id;
     589       
     590        int rc = loc_service_get_name(service_id, &sdev->kdev->svc_name);
     591        if (rc != EOK)
     592                goto fail;
     593
     594        list_append(&sdev->link, &serial_devs);
     595
     596        /*
     597         * Is this the device the user wants to use as a serial console?
     598         */
     599        match = (serial_console != NULL) &&
     600            !str_cmp(serial_console, sdev->kdev->svc_name);
     601
     602        if (match) {
     603                sdev->kdev->ctl_ops = &stty_ctl;
     604
     605                /* Initialize controller driver. */
     606                if ((*sdev->kdev->ctl_ops->init)(sdev->kdev) != 0) {
     607                        list_remove(&sdev->link);
     608                        goto fail;
     609                }
     610
     611                sdev->sess = loc_service_connect(service_id, INTERFACE_DDF,
     612                    IPC_FLAG_BLOCKING);
     613
     614                fid_t fid = fibril_create(serial_consumer, sdev);
     615                fibril_add_ready(fid);
     616        }
     617       
     618        *sdevp = sdev;
     619        return EOK;
     620       
     621fail:
     622        if (sdev->kdev->svc_name != NULL)
     623                free(sdev->kdev->svc_name);
     624        free(sdev->kdev);
     625        free(sdev);
     626        return -1;
     627}
     628
    422629
    423630/** Add legacy drivers/devices. */
     
    431638        kbd_add_dev(&chardev_port, &stty_ctl);
    432639#endif
    433 #if defined(UARCH_arm32) && defined(MACHINE_integratorcp)
    434         kbd_add_dev(&pl050_port, &pc_ctl);
    435 #endif
    436640#if defined(MACHINE_ski)
    437641        kbd_add_dev(&ski_port, &stty_ctl);
     
    440644        kbd_add_dev(&msim_port, &stty_ctl);
    441645#endif
    442 #if (defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)) && defined(CONFIG_FB)
    443         kbd_add_dev(&gxemul_port, &gxe_fb_ctl);
    444 #endif
    445 #if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul) && !defined(CONFIG_FB)
    446         kbd_add_dev(&gxemul_port, &stty_ctl);
    447 #endif
    448646#if defined(UARCH_ppc32)
    449647        kbd_add_dev(&adb_port, &apple_ctl);
     
    451649#if defined(UARCH_sparc64) && defined(PROCESSOR_sun4v)
    452650        kbd_add_dev(&niagara_port, &stty_ctl);
    453 #endif
    454 #if defined(UARCH_sparc64) && defined(MACHINE_generic)
    455         kbd_add_dev(&ns16550_port, &sun_ctl);
    456651#endif
    457652        /* Silence warning on abs32le about kbd_add_dev() being unused */
     
    473668}
    474669
    475 static void kbd_devs_yield(void)
    476 {
    477         /* For each keyboard device */
    478         list_foreach(kbd_devs, kdev_link) {
    479                 kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,
    480                     kbd_devs);
    481                
    482                 /* Yield port */
    483                 if (kdev->port_ops != NULL)
    484                         (*kdev->port_ops->yield)();
    485         }
    486 }
    487 
    488 static void kbd_devs_reclaim(void)
    489 {
    490         /* For each keyboard device */
    491         list_foreach(kbd_devs, kdev_link) {
    492                 kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,
    493                     kbd_devs);
    494                
    495                 /* Reclaim port */
    496                 if (kdev->port_ops != NULL)
    497                         (*kdev->port_ops->reclaim)();
    498         }
    499 }
    500 
    501670static int dev_check_new_kbdevs(void)
    502671{
     
    527696               
    528697                /* Determine whether we already know this device. */
    529                 list_foreach(kbd_devs, kdev_link) {
    530                         kbd_dev_t *kdev = list_get_instance(kdev_link,
    531                             kbd_dev_t, kbd_devs);
     698                list_foreach(kbd_devs, link, kbd_dev_t, kdev) {
    532699                        if (kdev->svc_id == svcs[i]) {
    533700                                already_known = true;
     
    580747               
    581748                /* Determine whether we already know this device. */
    582                 list_foreach(mouse_devs, mdev_link) {
    583                         mouse_dev_t *mdev = list_get_instance(mdev_link,
    584                             mouse_dev_t, mouse_devs);
     749                list_foreach(mouse_devs, link, mouse_dev_t, mdev) {
    585750                        if (mdev->svc_id == svcs[i]) {
    586751                                already_known = true;
     
    605770}
    606771
     772static int dev_check_new_serialdevs(void)
     773{
     774        category_id_t serial_cat;
     775        service_id_t *svcs;
     776        size_t count, i;
     777        bool already_known;
     778        int rc;
     779       
     780        rc = loc_category_get_id("serial", &serial_cat, IPC_FLAG_BLOCKING);
     781        if (rc != EOK) {
     782                printf("%s: Failed resolving category 'serial'.\n", NAME);
     783                return ENOENT;
     784        }
     785       
     786        /*
     787         * Check for new serial devices
     788         */
     789        rc = loc_category_get_svcs(serial_cat, &svcs, &count);
     790        if (rc != EOK) {
     791                printf("%s: Failed getting list of serial devices.\n",
     792                    NAME);
     793                return EIO;
     794        }
     795
     796        for (i = 0; i < count; i++) {
     797                already_known = false;
     798               
     799                /* Determine whether we already know this device. */
     800                list_foreach(serial_devs, link, serial_dev_t, sdev) {
     801                        if (sdev->kdev->svc_id == svcs[i]) {
     802                                already_known = true;
     803                                break;
     804                        }
     805                }
     806               
     807                if (!already_known) {
     808                        serial_dev_t *sdev;
     809                        if (serial_add_srldev(svcs[i], &sdev) == EOK) {
     810                                printf("%s: Connected serial device '%s'\n",
     811                                    NAME, sdev->kdev->svc_name);
     812                        }
     813                }
     814        }
     815       
     816        free(svcs);
     817       
     818        /* XXX Handle device removal */
     819       
     820        return EOK;
     821}
     822
    607823static int dev_check_new(void)
    608824{
     
    611827        fibril_mutex_lock(&discovery_lock);
    612828       
    613         rc = dev_check_new_kbdevs();
    614         if (rc != EOK) {
    615                 fibril_mutex_unlock(&discovery_lock);
    616                 return rc;
    617         }
    618        
    619         rc = dev_check_new_mousedevs();
    620         if (rc != EOK) {
    621                 fibril_mutex_unlock(&discovery_lock);
    622                 return rc;
     829        if (!serial_console) {
     830                rc = dev_check_new_kbdevs();
     831                if (rc != EOK) {
     832                        fibril_mutex_unlock(&discovery_lock);
     833                        return rc;
     834                }
     835       
     836                rc = dev_check_new_mousedevs();
     837                if (rc != EOK) {
     838                        fibril_mutex_unlock(&discovery_lock);
     839                        return rc;
     840                }
     841        } else {
     842                rc = dev_check_new_serialdevs();
     843                if (rc != EOK) {
     844                        fibril_mutex_unlock(&discovery_lock);
     845                        return rc;
     846                }
    623847        }
    624848       
     
    636860static int input_start_dev_discovery(void)
    637861{
    638         int rc;
    639 
    640         rc = loc_register_cat_change_cb(cat_change_cb);
     862        int rc = loc_register_cat_change_cb(cat_change_cb);
    641863        if (rc != EOK) {
    642864                printf("%s: Failed registering callback for device discovery. "
     
    644866                return rc;
    645867        }
    646 
     868       
    647869        return dev_check_new();
    648870}
     
    655877int main(int argc, char **argv)
    656878{
     879        int rc;
     880
    657881        if (argc < 2) {
    658882                usage(argv[0]);
     
    662886        printf("%s: HelenOS input service\n", NAME);
    663887       
    664         sysarg_t obio;
    665        
     888        list_initialize(&clients);
    666889        list_initialize(&kbd_devs);
    667890        list_initialize(&mouse_devs);
    668        
    669         if ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio))
    670                 irc_service = true;
    671        
    672         if (irc_service) {
    673                 while (irc_sess == NULL)
    674                         irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
    675                             SERVICE_IRC, 0, 0);
    676         }
     891        list_initialize(&serial_devs);
     892       
     893        serial_console = config_get_value("console");
    677894       
    678895        /* Add legacy keyboard devices. */
     
    683900       
    684901        /* Register driver */
    685         async_set_client_connection(client_connection);
    686         int rc = loc_server_register(NAME);
     902        async_set_client_data_constructor(client_data_create);
     903        async_set_client_data_destructor(client_data_destroy);
     904        async_set_fallback_port_handler(client_connection, NULL);
     905       
     906        rc = loc_server_register(NAME);
    687907        if (rc != EOK) {
    688908                printf("%s: Unable to register server\n", NAME);
     
    696916                return rc;
    697917        }
     918       
     919        /* Receive kernel notifications */
     920        rc = async_event_subscribe(EVENT_KCONSOLE, kconsole_event_handler, NULL);
     921        if (rc != EOK)
     922                printf("%s: Failed to register kconsole notifications (%s)\n",
     923                    NAME, str_error(rc));
    698924       
    699925        /* Start looking for new input devices */
Note: See TracChangeset for help on using the changeset viewer.