00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifdef HAVE_CONFIG_H
00027 # include <config.h>
00028 #endif
00029
00030 #include <ctype.h>
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <getopt.h>
00035 #include <assert.h>
00036 #include <unistd.h>
00037 #include <stdarg.h>
00038 #include <limits.h>
00039
00040 #include <linux/input.h>
00041
00042 #include "../logger.h"
00043 #include "../device_store.h"
00044 #include "linux_class_input.h"
00045
00057 typedef struct input_proc_info_s {
00058 int bus;
00059 int vendor;
00060 int product;
00061 int version;
00062
00063 dbus_uint32_t evbit;
00064 dbus_uint32_t ledbit;
00065 dbus_uint32_t relbit;
00066 dbus_uint32_t absbit;
00067
00068 char name[128];
00069 char phys_name[128];
00070 char handlers[128];
00071 char keybit[128];
00072
00073 struct input_proc_info_s *next;
00075 } input_proc_info;
00076
00081 static input_proc_info *
00082 get_input_proc_cur_info_obj ()
00083 {
00084 input_proc_info *i;
00085
00086 i = malloc (sizeof (input_proc_info));
00087 if (i == NULL)
00088 DIE (("Cannot allocated memory"));
00089
00090 (i->name)[0] = '\0';
00091 (i->phys_name)[0] = '\0';
00092 (i->handlers)[0] = '\0';
00093 (i->keybit)[0] = '\0';
00094 i->evbit = 0;
00095 i->ledbit = 0;
00096 i->relbit = 0;
00097 i->absbit = 0;
00098 i->bus = 0;
00099 i->vendor = 0;
00100 i->product = 0;
00101 i->version = 0;
00102
00103 return i;
00104 }
00105
00106
00108 static input_proc_info *input_proc_head = NULL;
00109
00111 static input_proc_info *input_proc_cur_info = NULL;
00112
00113
00120 static void
00121 input_proc_handle_interface (input_proc_info * info, char *s)
00122 {
00123 info->bus = find_num ("Bus=", s, 16);
00124 info->vendor = find_num ("Vendor=", s, 16);
00125 info->product = find_num ("Product=", s, 16);
00126 info->version = find_num ("Version=", s, 16);
00127 }
00128
00135 static void
00136 input_proc_handle_name (input_proc_info * info, char *s)
00137 {
00138 char *str;
00139
00140 str = find_string ("Name=\"", s);
00141
00142 if (str != NULL) {
00143 strncpy (info->name, str, 128);
00144
00145 (info->name)[strlen (info->name) - 1] = '\0';
00146 } else
00147 (info->name)[0] = '\0';
00148
00149
00150 }
00151
00158 static void
00159 input_proc_handle_phys (input_proc_info * info, char *s)
00160 {
00161 char *str;
00162 str = find_string ("Phys=", s);
00163 if (str != NULL)
00164 strncpy (info->phys_name, str, 128);
00165 else
00166 (info->phys_name)[0] = '\0';
00167 }
00168
00175 static void
00176 input_proc_handle_handlers (input_proc_info * info, char *s)
00177 {
00178 char *str;
00179 str = find_string ("Handlers=", s);
00180 if (str != NULL)
00181 strncpy (info->handlers, str, 128);
00182 else
00183 (info->handlers)[0] = '\0';
00184 }
00185
00192 static void
00193 input_proc_handle_bits (input_proc_info * info, char *s)
00194 {
00195 int num;
00196
00197 if ((num = find_num ("EV=", s, 16)) != LONG_MAX) {
00198 info->evbit = num;
00199 return;
00200 }
00201
00202 if ((num = find_num ("LED=", s, 16)) != LONG_MAX) {
00203 info->ledbit = num;
00204 return;
00205 }
00206
00207 if ((num = find_num ("REL=", s, 16)) != LONG_MAX) {
00208 info->relbit = num;
00209 return;
00210 }
00211
00212 if ((num = find_num ("ABS=", s, 16)) != LONG_MAX) {
00213 info->absbit = num;
00214 return;
00215 }
00216
00217 if (strncmp ("B: KEY=", s, 7) == 0) {
00218 strncpy (info->keybit, s + 7, 128);
00219
00220 info->keybit[strlen (info->keybit) - 1] = '\0';
00221 }
00222 }
00223
00224
00225
00230 static void
00231 input_proc_device_done (input_proc_info * info)
00232 {
00233 info->next = input_proc_head;
00234 input_proc_head = info;
00235 }
00236
00237
00242 static void
00243 input_proc_parse_line (char *s)
00244 {
00245
00246
00247
00248
00249 switch (s[0]) {
00250 case 'I':
00251 if (input_proc_cur_info != NULL) {
00252
00253 input_proc_device_done (input_proc_cur_info);
00254 }
00255
00256 input_proc_cur_info = get_input_proc_cur_info_obj ();
00257
00258 input_proc_handle_interface (input_proc_cur_info, s);
00259 break;
00260
00261 case 'N':
00262 input_proc_handle_name (input_proc_cur_info, s);
00263 break;
00264
00265 case 'P':
00266 input_proc_handle_phys (input_proc_cur_info, s);
00267 break;
00268
00269 case 'H':
00270 input_proc_handle_handlers (input_proc_cur_info, s);
00271 break;
00272
00273 case 'B':
00274 input_proc_handle_bits (input_proc_cur_info, s);
00275 break;
00276
00277
00278 default:
00279 break;
00280 }
00281 }
00282
00285 static void
00286 input_proc_parse ()
00287 {
00288 FILE *f;
00289 char buf[256];
00290
00291 f = fopen ("/proc/bus/input/devices", "r");
00292 if (f == NULL) {
00293 DIE (("Couldn't open /proc/bus/input/devices"));
00294 }
00295
00296 while (!feof (f)) {
00297 fgets (buf, 256, f);
00298 input_proc_parse_line (buf);
00299 }
00300 input_proc_device_done (input_proc_cur_info);
00301
00302 {
00303 input_proc_info *i;
00304 for (i = input_proc_head; i != NULL; i = i->next) {
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 }
00318 }
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 static void input_got_sysdevice (HalDevice * device,
00384 void *data1, void *data2);
00385
00390 static void
00391 process_input_proc_info (input_proc_info * i)
00392 {
00393 int n;
00394 HalDevice *d;
00395 char phys[128];
00396
00397
00398 for (n = 0; n < 128; n++) {
00399 if (i->phys_name[n] == '/')
00400 break;
00401 phys[n] = i->phys_name[n];
00402 }
00403 phys[n] = '\0';
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 d = ds_device_new ();
00414
00415 ds_property_set_string (d, "input.linux.phys", i->phys_name);
00416 ds_property_set_string (d, "input.linux.handlers", i->handlers);
00417 ds_property_set_int (d, "input.linux.evbit", i->evbit);
00418 ds_property_set_int (d, "input.linux.ledbit", i->ledbit);
00419 ds_property_set_int (d, "input.linux.relbit", i->relbit);
00420 ds_property_set_int (d, "input.linux.absbit", i->absbit);
00421 ds_property_set_string (d, "input.linux.keybit", i->keybit);
00422
00423
00424
00425
00426
00427 ds_property_set_bool (d, "input.key", i->evbit & (1 << EV_KEY));
00428 ds_property_set_bool (d, "input.relative",
00429 i->evbit & (1 << EV_REL));
00430 ds_property_set_bool (d, "input.absolute",
00431 i->evbit & (1 << EV_ABS));
00432 ds_property_set_bool (d, "input.led", i->evbit & (1 << EV_LED));
00433 ds_property_set_bool (d, "input.sound", i->evbit & (1 << EV_SND));
00434 ds_property_set_bool (d, "input.repeat", i->evbit & (1 << EV_REP));
00435 ds_property_set_bool (d, "input.force_feedback",
00436 i->evbit & (1 << EV_FF));
00437 ds_property_set_bool (d, "input.misc", i->evbit & (1 << EV_MSC));
00438 #ifdef EV_RST
00439 ds_property_set_bool (d, "input.rst", i->evbit & (1 << EV_RST));
00440 #elif EV_SYN
00441 ds_property_set_bool (d, "input.rst", i->evbit & (1 << EV_SYN));
00442 #endif
00443
00444 if (i->evbit & (1 << EV_LED)) {
00445 ds_property_set_bool (d, "input.led.numlock",
00446 i->ledbit & (1 << LED_NUML));
00447 ds_property_set_bool (d, "input.led.capslock",
00448 i->ledbit & (1 << LED_CAPSL));
00449 ds_property_set_bool (d, "input.led.scrolllock",
00450 i->ledbit & (1 << LED_SCROLLL));
00451 ds_property_set_bool (d, "input.led.compose",
00452 i->ledbit & (1 << LED_COMPOSE));
00453 ds_property_set_bool (d, "input.led.kana",
00454 i->ledbit & (1 << LED_KANA));
00455 ds_property_set_bool (d, "input.led.sleep",
00456 i->ledbit & (1 << LED_SLEEP));
00457 ds_property_set_bool (d, "input.led.suspend",
00458 i->ledbit & (1 << LED_SUSPEND));
00459 ds_property_set_bool (d, "input.led.mute",
00460 i->ledbit & (1 << LED_MUTE));
00461 ds_property_set_bool (d, "input.led.misc",
00462 i->ledbit & (1 << LED_MISC));
00463 ds_property_set_bool (d, "input.led.max",
00464 i->ledbit & (1 << LED_MAX));
00465 }
00466
00467 if (i->evbit & (1 << EV_REL)) {
00468 ds_property_set_bool (d, "input.relative.x",
00469 i->relbit & (1 << REL_X));
00470 ds_property_set_bool (d, "input.relative.y",
00471 i->relbit & (1 << REL_Y));
00472 ds_property_set_bool (d, "input.relative.z",
00473 i->relbit & (1 << REL_Z));
00474 ds_property_set_bool (d, "input.relative.hwheel",
00475 i->relbit & (1 << REL_HWHEEL));
00476 ds_property_set_bool (d, "input.relative.dial",
00477 i->relbit & (1 << REL_DIAL));
00478 ds_property_set_bool (d, "input.relative.wheel",
00479 i->relbit & (1 << REL_WHEEL));
00480 ds_property_set_bool (d, "input.relative.misc",
00481 i->relbit & (1 << REL_MISC));
00482 }
00483
00484 if (i->evbit & (1 << EV_ABS)) {
00485 ds_property_set_bool (d, "input.absolute.x",
00486 i->absbit & (1 << ABS_X));
00487 ds_property_set_bool (d, "input.absolute.y",
00488 i->absbit & (1 << ABS_Y));
00489 ds_property_set_bool (d, "input.absolute.z",
00490 i->absbit & (1 << ABS_Z));
00491 ds_property_set_bool (d, "input.absolute.rx",
00492 i->absbit & (1 << ABS_RX));
00493 ds_property_set_bool (d, "input.absolute.ry",
00494 i->absbit & (1 << ABS_RY));
00495 ds_property_set_bool (d, "input.absolute.rz",
00496 i->absbit & (1 << ABS_RZ));
00497 ds_property_set_bool (d, "input.absolute.throttle",
00498 i->absbit & (1 << ABS_THROTTLE));
00499 ds_property_set_bool (d, "input.absolute.rudder",
00500 i->absbit & (1 << ABS_RUDDER));
00501 ds_property_set_bool (d, "input.absolute.wheel",
00502 i->absbit & (1 << ABS_WHEEL));
00503 ds_property_set_bool (d, "input.absolute.gas",
00504 i->absbit & (1 << ABS_GAS));
00505 ds_property_set_bool (d, "input.absolute.brake",
00506 i->absbit & (1 << ABS_BRAKE));
00507 ds_property_set_bool (d, "input.absolute.hat0x",
00508 i->absbit & (1 << ABS_HAT0X));
00509 ds_property_set_bool (d, "input.absolute.hat0y",
00510 i->absbit & (1 << ABS_HAT0Y));
00511 ds_property_set_bool (d, "input.absolute.hat1x",
00512 i->absbit & (1 << ABS_HAT1X));
00513 ds_property_set_bool (d, "input.absolute.hat1y",
00514 i->absbit & (1 << ABS_HAT1Y));
00515 ds_property_set_bool (d, "input.absolute.hat2x",
00516 i->absbit & (1 << ABS_HAT2X));
00517 ds_property_set_bool (d, "input.absolute.hat2y",
00518 i->absbit & (1 << ABS_HAT2Y));
00519 ds_property_set_bool (d, "input.absolute.pressure",
00520 i->absbit & (1 << ABS_PRESSURE));
00521 ds_property_set_bool (d, "input.absolute.distance",
00522 i->absbit & (1 << ABS_DISTANCE));
00523 ds_property_set_bool (d, "input.absolute.tilt_x",
00524 i->absbit & (1 << ABS_TILT_X));
00525 ds_property_set_bool (d, "input.absolute.tilt_Y",
00526 i->absbit & (1 << ABS_TILT_Y));
00527 ds_property_set_bool (d, "input.absolute.misc",
00528 i->absbit & (1 << ABS_MISC));
00529 }
00530
00531
00532 ds_add_capability (d, "input");
00533
00538 if (i->relbit != 0) {
00539 ds_add_capability (d, "input.mouse");
00540 ds_property_set_string (d, "info.category", "input.mouse");
00541 } else {
00542 ds_add_capability (d, "input.keyboard");
00543 ds_property_set_string (d, "info.category",
00544 "input.keyboard");
00545 }
00546
00552
00553
00554
00555
00556 ds_device_async_find_by_key_value_string ("linux.kernel_devname", phys, FALSE,
00557 input_got_sysdevice,
00558 (void *) d, NULL,
00559 is_probing ? 0 :
00560 HAL_LINUX_HOTPLUG_TIMEOUT);
00561 }
00562
00570 static void
00571 input_got_sysdevice (HalDevice * sysdevice, void *data1, void *data2)
00572 {
00573 HalDevice *d = (HalDevice *) data1;
00574
00575 if (sysdevice == NULL) {
00576 HAL_WARNING (("Sysdevice for a class input device never appeared!"));
00577 } else {
00578
00579
00580
00581 ds_device_merge (sysdevice, d);
00582 }
00583
00584
00585 ds_device_destroy (d);
00586 }
00587
00588
00593 void
00594 linux_class_input_probe ()
00595 {
00596 input_proc_info *i;
00597
00598 input_proc_parse ();
00599
00600 for (i = input_proc_head; i != NULL; i = i->next)
00601 process_input_proc_info (i);
00602 }
00603
00604
00615 void
00616 linux_class_input_handle_hotplug_add (char *name, char *phys, char *key,
00617 int ev, int rel, int abs, int led)
00618 {
00619 char *s;
00620 input_proc_info *i;
00621
00622 i = get_input_proc_cur_info_obj ();
00623
00626 strncpy (i->name, name, 128);
00627 strncpy (i->phys_name, phys, 128);
00628 strncpy (i->keybit, key, 128);
00629 i->evbit = ev;
00630 i->relbit = rel;
00631 i->absbit = abs;
00632 i->ledbit = led;
00633
00634 process_input_proc_info (i);
00635 }
00636
00640 void
00641 linux_class_input_init ()
00642 {
00643 }
00644
00649 void
00650 linux_class_input_detection_done ()
00651 {
00652 }
00653
00657 void
00658 linux_class_input_shutdown ()
00659 {
00660 }
00661