source: mainline/uspace/srv/hid/input/generic/input.c@ 99ac5cf

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 99ac5cf was 99ac5cf, checked in by Jiri Svoboda <jiri@…>, 14 years ago

Fix leak.

  • Property mode set to 100644
File size: 15.1 KB
RevLine 
[51d6f80]1/*
[df4ed85]2 * Copyright (c) 2006 Josef Cejka
[9be360ee]3 * Copyright (c) 2011 Jiri Svoboda
[51d6f80]4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
[231a60a]30/**
[5f88293]31 * @addtogroup inputgen generic
32 * @brief HelenOS input server.
33 * @ingroup input
[ce5bcb4]34 * @{
[215abc1]35 */
[ce5bcb4]36/** @file
37 */
38
[9be360ee]39#include <adt/list.h>
[cc574511]40#include <bool.h>
[7ee6aff]41#include <ipc/services.h>
[5f88293]42#include <ipc/input.h>
[3e5a814]43#include <sysinfo.h>
[51d6f80]44#include <stdio.h>
45#include <unistd.h>
46#include <stdlib.h>
[37458472]47#include <stdio.h>
[79ae36dd]48#include <ns.h>
49#include <ns_obsolete.h>
[fa09449]50#include <async.h>
[79ae36dd]51#include <async_obsolete.h>
[51d6f80]52#include <errno.h>
[d9c8c81]53#include <adt/fifo.h>
[215abc1]54#include <io/console.h>
55#include <io/keycode.h>
[15f3c3f]56#include <loc.h>
[854eddd6]57#include <input.h>
[51d6f80]58#include <kbd.h>
[f89979b]59#include <kbd_port.h>
60#include <kbd_ctl.h>
[1875a0c]61#include <mouse_proto.h>
[f89979b]62#include <layout.h>
[854eddd6]63#include <mouse.h>
[51d6f80]64
[79ae36dd]65// FIXME: remove this header
[c0699467]66#include <abi/ipc/methods.h>
[79ae36dd]67
[1875a0c]68#define NUM_LAYOUTS 3
69
70static layout_ops_t *layout[NUM_LAYOUTS] = {
71 &us_qwerty_ops,
72 &us_dvorak_ops,
73 &cz_ops
74};
[854387b]75
[9be360ee]76static void kbd_devs_yield(void);
77static void kbd_devs_reclaim(void);
78
[3f29834]79int client_phone = -1;
[d1eece6]80
[9be360ee]81/** List of keyboard devices */
[b72efe8]82static list_t kbd_devs;
[b1bdc7a4]83
[854eddd6]84/** List of mouse devices */
[1875a0c]85static list_t mouse_devs;
[854eddd6]86
[57d129e]87bool irc_service = false;
88int irc_phone = -1;
[3e5a814]89
[1875a0c]90void kbd_push_data(kbd_dev_t *kdev, sysarg_t data)
91{
92 (*kdev->ctl_ops->parse)(data);
93}
[0175246]94
[1875a0c]95void mouse_push_data(mouse_dev_t *mdev, sysarg_t data)
[f89979b]96{
[1875a0c]97 (*mdev->proto_ops->parse)(data);
[f89979b]98}
99
[1875a0c]100void kbd_push_event(kbd_dev_t *kdev, int type, unsigned int key)
[085bd54]101{
[79ae36dd]102 kbd_event_t ev;
[1875a0c]103 unsigned int mod_mask;
104
[d1eece6]105 switch (key) {
106 case KC_LCTRL: mod_mask = KM_LCTRL; break;
107 case KC_RCTRL: mod_mask = KM_RCTRL; break;
108 case KC_LSHIFT: mod_mask = KM_LSHIFT; break;
109 case KC_RSHIFT: mod_mask = KM_RSHIFT; break;
110 case KC_LALT: mod_mask = KM_LALT; break;
111 case KC_RALT: mod_mask = KM_RALT; break;
112 default: mod_mask = 0; break;
113 }
[1875a0c]114
[d1eece6]115 if (mod_mask != 0) {
[215abc1]116 if (type == KEY_PRESS)
[2f7a564]117 kdev->mods = kdev->mods | mod_mask;
[d1eece6]118 else
[2f7a564]119 kdev->mods = kdev->mods & ~mod_mask;
[d1eece6]120 }
[1875a0c]121
[d1eece6]122 switch (key) {
123 case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break;
124 case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break;
125 case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break;
126 default: mod_mask = 0; break;
127 }
[1875a0c]128
[12b6796]129 if (mod_mask != 0) {
[215abc1]130 if (type == KEY_PRESS) {
[12b6796]131 /*
132 * Only change lock state on transition from released
133 * to pressed. This prevents autorepeat from messing
134 * up the lock state.
135 */
[2f7a564]136 kdev->mods = kdev->mods ^ (mod_mask & ~kdev->lock_keys);
137 kdev->lock_keys = kdev->lock_keys | mod_mask;
[1875a0c]138
[c145bc2]139 /* Update keyboard lock indicator lights. */
[2f7a564]140 (*kdev->ctl_ops->set_ind)(kdev, kdev->mods);
[12b6796]141 } else {
[2f7a564]142 kdev->lock_keys = kdev->lock_keys & ~mod_mask;
[12b6796]143 }
144 }
[1875a0c]145
[2f7a564]146 if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
[1875a0c]147 key == KC_F1) {
[2f7a564]148 layout_destroy(kdev->active_layout);
149 kdev->active_layout = layout_create(layout[0]);
[0175246]150 return;
151 }
[1875a0c]152
[2f7a564]153 if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
[1875a0c]154 key == KC_F2) {
[2f7a564]155 layout_destroy(kdev->active_layout);
156 kdev->active_layout = layout_create(layout[1]);
[0175246]157 return;
158 }
[1875a0c]159
[2f7a564]160 if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
[1875a0c]161 key == KC_F3) {
[2f7a564]162 layout_destroy(kdev->active_layout);
163 kdev->active_layout = layout_create(layout[2]);
[0175246]164 return;
165 }
[1875a0c]166
[f89979b]167 ev.type = type;
168 ev.key = key;
[2f7a564]169 ev.mods = kdev->mods;
[1875a0c]170
[2f7a564]171 ev.c = layout_parse_ev(kdev->active_layout, &ev);
[1875a0c]172 async_obsolete_msg_4(client_phone, INPUT_EVENT_KEY, ev.type, ev.key,
173 ev.mods, ev.c);
[854eddd6]174}
175
176/** Mouse pointer has moved. */
[1875a0c]177void mouse_push_event_move(mouse_dev_t *mdev, int dx, int dy)
[854eddd6]178{
179 async_obsolete_msg_2(client_phone, INPUT_EVENT_MOVE, dx, dy);
180}
181
182/** Mouse button has been pressed. */
[1875a0c]183void mouse_push_event_button(mouse_dev_t *mdev, int bnum, int press)
[854eddd6]184{
185 async_obsolete_msg_2(client_phone, INPUT_EVENT_BUTTON, bnum, press);
[085bd54]186}
187
[9934f7d]188static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
[085bd54]189{
190 ipc_callid_t callid;
191 ipc_call_t call;
192 int retval;
[1875a0c]193
[ffa2c8ef]194 async_answer_0(iid, EOK);
[1875a0c]195
[79ae36dd]196 while (true) {
[085bd54]197 callid = async_get_call(&call);
[79ae36dd]198
199 if (!IPC_GET_IMETHOD(call)) {
[3f29834]200 if (client_phone != -1) {
[79ae36dd]201 async_obsolete_hangup(client_phone);
[3f29834]202 client_phone = -1;
[47a350f]203 }
204
[ffa2c8ef]205 async_answer_0(callid, EOK);
[085bd54]206 return;
[79ae36dd]207 }
208
209 switch (IPC_GET_IMETHOD(call)) {
[085bd54]210 case IPC_M_CONNECT_TO_ME:
[3f29834]211 if (client_phone != -1) {
[085bd54]212 retval = ELIMIT;
213 break;
214 }
[3f29834]215 client_phone = IPC_GET_ARG5(call);
[085bd54]216 retval = 0;
217 break;
[5f88293]218 case INPUT_YIELD:
[9be360ee]219 kbd_devs_yield();
[ccd1a14]220 retval = 0;
221 break;
[5f88293]222 case INPUT_RECLAIM:
[9be360ee]223 kbd_devs_reclaim();
[ccd1a14]224 retval = 0;
225 break;
[153a209]226 default:
227 retval = EINVAL;
[085bd54]228 }
[1875a0c]229
[ffa2c8ef]230 async_answer_0(callid, retval);
[1875a0c]231 }
[085bd54]232}
233
[2f7a564]234static kbd_dev_t *kbd_dev_new(void)
[b1bdc7a4]235{
[1875a0c]236 kbd_dev_t *kdev = calloc(1, sizeof(kbd_dev_t));
[9be360ee]237 if (kdev == NULL) {
[1875a0c]238 printf("%s: Error allocating keyboard device. "
239 "Out of memory.\n", NAME);
[2f7a564]240 return NULL;
[9be360ee]241 }
[1875a0c]242
[9be360ee]243 link_initialize(&kdev->kbd_devs);
[1875a0c]244
[2f7a564]245 kdev->mods = KM_NUM_LOCK;
246 kdev->lock_keys = 0;
247 kdev->active_layout = layout_create(layout[0]);
[1875a0c]248
[2f7a564]249 return kdev;
250}
251
[1875a0c]252static mouse_dev_t *mouse_dev_new(void)
253{
254 mouse_dev_t *mdev = calloc(1, sizeof(mouse_dev_t));
255 if (mdev == NULL) {
256 printf("%s: Error allocating keyboard device. "
257 "Out of memory.\n", NAME);
258 return NULL;
259 }
260
261 link_initialize(&mdev->mouse_devs);
262
263 return mdev;
264}
265
[2f7a564]266/** Add new legacy keyboard device. */
267static void kbd_add_dev(kbd_port_ops_t *port, kbd_ctl_ops_t *ctl)
268{
[1875a0c]269 kbd_dev_t *kdev = kbd_dev_new();
[2f7a564]270 if (kdev == NULL)
271 return;
[1875a0c]272
[9be360ee]273 kdev->port_ops = port;
274 kdev->ctl_ops = ctl;
[cce8a83]275 kdev->svc_id = 0;
[1875a0c]276
[9be360ee]277 /* Initialize port driver. */
[af897ff0]278 if ((*kdev->port_ops->init)(kdev) != 0)
279 goto fail;
[1875a0c]280
[9be360ee]281 /* Initialize controller driver. */
282 if ((*kdev->ctl_ops->init)(kdev) != 0) {
283 /* XXX Uninit port */
284 goto fail;
285 }
[1875a0c]286
[9be360ee]287 list_append(&kdev->kbd_devs, &kbd_devs);
288 return;
[1875a0c]289
[9be360ee]290fail:
291 free(kdev);
292}
293
[1875a0c]294/** Add new legacy mouse device. */
295static void mouse_add_dev(mouse_port_ops_t *port, mouse_proto_ops_t *proto)
296{
297 mouse_dev_t *mdev = mouse_dev_new();
298 if (mdev == NULL)
299 return;
300
301 mdev->port_ops = port;
302 mdev->proto_ops = proto;
[cce8a83]303 mdev->svc_id = 0;
[1875a0c]304
305 /* Initialize port driver. */
306 if ((*mdev->port_ops->init)(mdev) != 0)
307 goto fail;
308
309 /* Initialize protocol driver. */
310 if ((*mdev->proto_ops->init)(mdev) != 0) {
311 /* XXX Uninit port */
312 goto fail;
313 }
314
315 list_append(&mdev->mouse_devs, &mouse_devs);
316 return;
317
318fail:
319 free(mdev);
320}
321
[af897ff0]322/** Add new kbdev device.
323 *
[cc574511]324 * @param service_id Service ID of the keyboard device
[1875a0c]325 *
[af897ff0]326 */
[cce8a83]327static int kbd_add_kbdev(service_id_t service_id, kbd_dev_t **kdevp)
[af897ff0]328{
[1875a0c]329 kbd_dev_t *kdev = kbd_dev_new();
[2f7a564]330 if (kdev == NULL)
[af897ff0]331 return -1;
[1875a0c]332
[cce8a83]333 kdev->svc_id = service_id;
[af897ff0]334 kdev->port_ops = NULL;
335 kdev->ctl_ops = &kbdev_ctl;
[1875a0c]336
[cce8a83]337 int rc = loc_service_get_name(service_id, &kdev->svc_name);
338 if (rc != EOK) {
339 kdev->svc_name = NULL;
340 goto fail;
341 }
342
[af897ff0]343 /* Initialize controller driver. */
344 if ((*kdev->ctl_ops->init)(kdev) != 0) {
345 goto fail;
346 }
[1875a0c]347
[af897ff0]348 list_append(&kdev->kbd_devs, &kbd_devs);
[cce8a83]349 *kdevp = kdev;
[af897ff0]350 return EOK;
[1875a0c]351
[af897ff0]352fail:
[cce8a83]353 if (kdev->svc_name != NULL)
354 free(kdev->svc_name);
[af897ff0]355 free(kdev);
356 return -1;
357}
358
[1875a0c]359/** Add new mousedev device.
360 *
[cc574511]361 * @param service_id Service ID of the mouse device
[1875a0c]362 *
363 */
[cce8a83]364static int mouse_add_mousedev(service_id_t service_id, mouse_dev_t **mdevp)
[1875a0c]365{
366 mouse_dev_t *mdev = mouse_dev_new();
367 if (mdev == NULL)
368 return -1;
369
[cce8a83]370 mdev->svc_id = service_id;
[1875a0c]371 mdev->port_ops = NULL;
372 mdev->proto_ops = &mousedev_proto;
373
[cce8a83]374 int rc = loc_service_get_name(service_id, &mdev->svc_name);
375 if (rc != EOK) {
376 mdev->svc_name = NULL;
377 goto fail;
378 }
379
[1875a0c]380 /* Initialize controller driver. */
381 if ((*mdev->proto_ops->init)(mdev) != 0) {
382 goto fail;
383 }
384
385 list_append(&mdev->mouse_devs, &mouse_devs);
[cce8a83]386 *mdevp = mdev;
[1875a0c]387 return EOK;
388
389fail:
390 free(mdev);
391 return -1;
392}
393
[9be360ee]394/** Add legacy drivers/devices. */
395static void kbd_add_legacy_devs(void)
396{
397 /*
398 * Need to add these drivers based on config unless we can probe
399 * them automatically.
400 */
[b1bdc7a4]401#if defined(UARCH_amd64)
[9be360ee]402 kbd_add_dev(&chardev_port, &pc_ctl);
403#endif
404#if defined(UARCH_arm32) && defined(MACHINE_gta02)
405 kbd_add_dev(&chardev_port, &stty_ctl);
406#endif
407#if defined(UARCH_arm32) && defined(MACHINE_testarm) && defined(CONFIG_FB)
408 kbd_add_dev(&gxemul_port, &gxe_fb_ctl);
409#endif
410#if defined(UARCH_arm32) && defined(MACHINE_testarm) && !defined(CONFIG_FB)
411 kbd_add_dev(&gxemul_port, &stty_ctl);
412#endif
413#if defined(UARCH_arm32) && defined(MACHINE_integratorcp)
414 kbd_add_dev(&pl050_port, &pc_ctl);
415#endif
416#if defined(UARCH_ia32)
417 kbd_add_dev(&chardev_port, &pc_ctl);
418#endif
419#if defined(MACHINE_i460GX)
420 kbd_add_dev(&chardev_port, &pc_ctl);
421#endif
422#if defined(MACHINE_ski)
423 kbd_add_dev(&ski_port, &stty_ctl);
424#endif
425#if defined(MACHINE_msim)
[333c233]426 kbd_add_dev(&msim_port, &stty_ctl);
[9be360ee]427#endif
428#if (defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)) && defined(CONFIG_FB)
429 kbd_add_dev(&gxemul_port, &gxe_fb_ctl);
[b1bdc7a4]430#endif
[9be360ee]431#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul) && !defined(CONFIG_FB)
432 kbd_add_dev(&gxemul_port, &stty_ctl);
433#endif
434#if defined(UARCH_ppc32)
435 kbd_add_dev(&adb_port, &apple_ctl);
436#endif
437#if defined(UARCH_sparc64) && defined(PROCESSOR_sun4v)
438 kbd_add_dev(&niagara_port, &stty_ctl);
439#endif
440#if defined(UARCH_sparc64) && defined(MACHINE_generic)
[4f3f9659]441 kbd_add_dev(&ns16550_port, &sun_ctl);
[9be360ee]442#endif
[af897ff0]443 /* Silence warning on abs32le about kbd_add_dev() being unused */
444 (void) kbd_add_dev;
[9be360ee]445}
446
[1875a0c]447/** Add legacy drivers/devices. */
448static void mouse_add_legacy_devs(void)
449{
450 /*
451 * Need to add these drivers based on config unless we can probe
452 * them automatically.
453 */
454#if defined(UARCH_amd64)
455 mouse_add_dev(&chardev_mouse_port, &ps2_proto);
456#endif
457#if defined(UARCH_ia32)
458 mouse_add_dev(&chardev_mouse_port, &ps2_proto);
459#endif
460#if defined(MACHINE_i460GX)
461 mouse_add_dev(&chardev_mouse_port, &ps2_proto);
462#endif
463#if defined(UARCH_ppc32)
464 mouse_add_dev(&adb_mouse_port, &adb_proto);
465#endif
466 /* Silence warning on abs32le about mouse_add_dev() being unused */
467 (void) mouse_add_dev;
468}
469
[9be360ee]470static void kbd_devs_yield(void)
471{
472 /* For each keyboard device */
473 list_foreach(kbd_devs, kdev_link) {
474 kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,
475 kbd_devs);
[1875a0c]476
[9be360ee]477 /* Yield port */
[f2f99ae]478 if (kdev->port_ops != NULL)
479 (*kdev->port_ops->yield)();
[9be360ee]480 }
481}
482
483static void kbd_devs_reclaim(void)
484{
485 /* For each keyboard device */
486 list_foreach(kbd_devs, kdev_link) {
487 kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,
488 kbd_devs);
[1875a0c]489
[9be360ee]490 /* Reclaim port */
[f2f99ae]491 if (kdev->port_ops != NULL)
492 (*kdev->port_ops->reclaim)();
[9be360ee]493 }
[b1bdc7a4]494}
[085bd54]495
[12f9f0d0]496static int dev_check_new_kbdevs(void)
[af897ff0]497{
[12f9f0d0]498 category_id_t keyboard_cat;
[cc574511]499 service_id_t *svcs;
500 size_t count, i;
501 bool already_known;
[af897ff0]502 int rc;
[1875a0c]503
[cc574511]504 rc = loc_category_get_id("keyboard", &keyboard_cat, IPC_FLAG_BLOCKING);
505 if (rc != EOK) {
506 printf("%s: Failed resolving category 'keyboard'.\n", NAME);
507 return ENOENT;
508 }
509
[12f9f0d0]510 /*
511 * Check for new keyboard devices
512 */
513 rc = loc_category_get_svcs(keyboard_cat, &svcs, &count);
514 if (rc != EOK) {
515 printf("%s: Failed getting list of keyboard devices.\n",
516 NAME);
517 return EIO;
518 }
519
520 for (i = 0; i < count; i++) {
521 already_known = false;
522
523 /* Determine whether we already know this device. */
524 list_foreach(kbd_devs, kdev_link) {
525 kbd_dev_t *kdev = list_get_instance(kdev_link,
526 kbd_dev_t, kbd_devs);
527 if (kdev->svc_id == svcs[i]) {
528 already_known = true;
529 break;
530 }
531 }
532
533 if (!already_known) {
534 kbd_dev_t *kdev;
535 if (kbd_add_kbdev(svcs[i], &kdev) == EOK) {
536 printf("%s: Connected keyboard device '%s'\n",
537 NAME, kdev->svc_name);
538 }
539 }
540 }
541
[99ac5cf]542 free(svcs);
543
[12f9f0d0]544 /* XXX Handle device removal */
545
546 return EOK;
547}
548
549static int dev_check_new_mousedevs(void)
550{
551 category_id_t mouse_cat;
552 service_id_t *svcs;
553 size_t count, i;
554 bool already_known;
555 int rc;
556
[cc574511]557 rc = loc_category_get_id("mouse", &mouse_cat, IPC_FLAG_BLOCKING);
558 if (rc != EOK) {
559 printf("%s: Failed resolving category 'mouse'.\n", NAME);
560 return ENOENT;
561 }
562
[12f9f0d0]563 /*
564 * Check for new mouse devices
565 */
566 rc = loc_category_get_svcs(mouse_cat, &svcs, &count);
567 if (rc != EOK) {
568 printf("%s: Failed getting list of mouse devices.\n",
569 NAME);
570 return EIO;
571 }
572
573 for (i = 0; i < count; i++) {
574 already_known = false;
[1875a0c]575
[12f9f0d0]576 /* Determine whether we already know this device. */
577 list_foreach(mouse_devs, mdev_link) {
578 mouse_dev_t *mdev = list_get_instance(mdev_link,
579 mouse_dev_t, mouse_devs);
580 if (mdev->svc_id == svcs[i]) {
581 already_known = true;
582 break;
[cc574511]583 }
[854eddd6]584 }
[1875a0c]585
[12f9f0d0]586 if (!already_known) {
587 mouse_dev_t *mdev;
588 if (mouse_add_mousedev(svcs[i], &mdev) == EOK) {
589 printf("%s: Connected mouse device '%s'\n",
590 NAME, mdev->svc_name);
[cc574511]591 }
[af897ff0]592 }
593 }
[1875a0c]594
[99ac5cf]595 free(svcs);
596
[12f9f0d0]597 /* XXX Handle device removal */
598
[af897ff0]599 return EOK;
600}
601
[12f9f0d0]602static int dev_check_new(void)
[af897ff0]603{
[12f9f0d0]604 int rc;
[1875a0c]605
[12f9f0d0]606 rc = dev_check_new_kbdevs();
607 if (rc != EOK)
608 return rc;
609
610 rc = dev_check_new_mousedevs();
611 if (rc != EOK)
612 return rc;
613
614 return EOK;
615}
616
617static void cat_change_cb(void)
618{
619 dev_check_new();
620}
621
622/** Start listening for new devices. */
623static int input_start_dev_discovery(void)
624{
625 int rc;
626
627 rc = loc_register_cat_change_cb(cat_change_cb);
628 if (rc != EOK) {
629 printf("%s: Failed registering callback for device discovery. "
630 "(%d)\n", NAME, rc);
631 return rc;
632 }
633
634 return dev_check_new();
[af897ff0]635}
636
[51d6f80]637int main(int argc, char **argv)
638{
[5f88293]639 printf("%s: HelenOS input service\n", NAME);
[e00938c]640
[d9fae235]641 sysarg_t obio;
642
[9be360ee]643 list_initialize(&kbd_devs);
[854eddd6]644 list_initialize(&mouse_devs);
[9be360ee]645
[336d2f52]646 if ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio))
[57d129e]647 irc_service = true;
[3e5a814]648
[57d129e]649 if (irc_service) {
650 while (irc_phone < 0)
[79ae36dd]651 irc_phone = service_obsolete_connect_blocking(SERVICE_IRC, 0, 0);
[3e5a814]652 }
653
[854eddd6]654 /* Add legacy keyboard devices. */
[9be360ee]655 kbd_add_legacy_devs();
[6d605e6]656
[1875a0c]657 /* Add legacy mouse devices. */
658 mouse_add_legacy_devs();
[51d6f80]659
[47a350f]660 /* Register driver */
[15f3c3f]661 int rc = loc_server_register(NAME, client_connection);
[47a350f]662 if (rc < 0) {
[15f3c3f]663 printf("%s: Unable to register server (%d)\n", NAME, rc);
[51d6f80]664 return -1;
[47a350f]665 }
666
[15f3c3f]667 char kbd[LOC_NAME_MAXLEN + 1];
668 snprintf(kbd, LOC_NAME_MAXLEN, "%s/%s", NAMESPACE, NAME);
[e00938c]669
[15f3c3f]670 service_id_t service_id;
671 if (loc_service_register(kbd, &service_id) != EOK) {
672 printf("%s: Unable to register service %s\n", NAME, kbd);
[47a350f]673 return -1;
674 }
[1875a0c]675
[854eddd6]676 /* Start looking for new input devices */
677 input_start_dev_discovery();
[1875a0c]678
679 printf("%s: Accepting connections\n", NAME);
[085bd54]680 async_manager();
[1875a0c]681
[f89979b]682 /* Not reached. */
[153a209]683 return 0;
[51d6f80]684}
[ce5bcb4]685
686/**
687 * @}
[5f88293]688 */
Note: See TracBrowser for help on using the repository browser.