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 {
00059 int bus;
00060 int vendor;
00061 int product;
00062 int version;
00063
00064 dbus_uint32_t evbit;
00065 dbus_uint32_t ledbit;
00066 dbus_uint32_t relbit;
00067 dbus_uint32_t absbit;
00068
00069 char name[128];
00070 char phys_name[128];
00071 char handlers[128];
00072 char keybit[128];
00073
00074 struct input_proc_info_s* next;
00075 } input_proc_info;
00076
00081 static input_proc_info* get_input_proc_cur_info_obj()
00082 {
00083 input_proc_info* i;
00084
00085 i = malloc(sizeof(input_proc_info));
00086 if( i==NULL )
00087 DIE(("Cannot allocated memory"));
00088
00089 (i->name)[0] = '\0';
00090 (i->phys_name)[0] = '\0';
00091 (i->handlers)[0] = '\0';
00092 (i->keybit)[0] = '\0';
00093 i->evbit = 0;
00094 i->ledbit = 0;
00095 i->relbit = 0;
00096 i->absbit = 0;
00097 i->bus = 0;
00098 i->vendor = 0;
00099 i->product = 0;
00100 i->version = 0;
00101
00102 return i;
00103 }
00104
00105
00107 static input_proc_info* input_proc_head = NULL;
00108
00110 static input_proc_info* input_proc_cur_info = NULL;
00111
00112
00119 static void input_proc_handle_interface(input_proc_info* info, char* s)
00120 {
00121 info->bus = find_num("Bus=", s, 16);
00122 info->vendor = find_num("Vendor=", s, 16);
00123 info->product = find_num("Product=", s, 16);
00124 info->version = find_num("Version=", s, 16);
00125 }
00126
00133 static void input_proc_handle_name(input_proc_info* info, char* s)
00134 {
00135 char* str;
00136
00137 str = find_string("Name=\"", s);
00138
00139 if( str!=NULL )
00140 {
00141 strncpy(info->name, str, 128);
00142
00143 (info->name)[strlen(info->name)-1] = '\0';
00144 }
00145 else
00146 (info->name)[0]='\0';
00147
00148
00149 }
00150
00157 static void input_proc_handle_phys(input_proc_info* info, char* s)
00158 {
00159 char* str;
00160 str = find_string("Phys=", s);
00161 if( str!=NULL )
00162 strncpy(info->phys_name, str, 128);
00163 else
00164 (info->phys_name)[0]='\0';
00165 }
00166
00173 static void input_proc_handle_handlers(input_proc_info* info, char* s)
00174 {
00175 char* str;
00176 str = find_string("Handlers=", s);
00177 if( str!=NULL )
00178 strncpy(info->handlers, str, 128);
00179 else
00180 (info->handlers)[0]='\0';
00181 }
00182
00189 static void input_proc_handle_bits(input_proc_info* info, char* s)
00190 {
00191 int num;
00192
00193 if( (num=find_num("EV=", s, 16))!=LONG_MAX )
00194 {
00195 info->evbit = num;
00196 return;
00197 }
00198
00199 if( (num=find_num("LED=", s, 16))!=LONG_MAX )
00200 {
00201 info->ledbit = num;
00202 return;
00203 }
00204
00205 if( (num=find_num("REL=", s, 16))!=LONG_MAX )
00206 {
00207 info->relbit = num;
00208 return;
00209 }
00210
00211 if( (num=find_num("ABS=", s, 16))!=LONG_MAX )
00212 {
00213 info->absbit = num;
00214 return;
00215 }
00216
00217 if( strncmp("B: KEY=", s, 7)==0 )
00218 {
00219 strncpy(info->keybit, s+7, 128);
00220
00221 info->keybit[strlen(info->keybit)-1] = '\0';
00222 }
00223 }
00224
00225
00226
00231 static void 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 input_proc_parse_line(char* s)
00243 {
00244
00245
00246
00247
00248 switch( s[0] )
00249 {
00250 case 'I':
00251 if( input_proc_cur_info!=NULL )
00252 {
00253
00254 input_proc_device_done(input_proc_cur_info);
00255 }
00256
00257 input_proc_cur_info = get_input_proc_cur_info_obj();
00258
00259 input_proc_handle_interface(input_proc_cur_info, s);
00260 break;
00261
00262 case 'N':
00263 input_proc_handle_name(input_proc_cur_info, s);
00264 break;
00265
00266 case 'P':
00267 input_proc_handle_phys(input_proc_cur_info, s);
00268 break;
00269
00270 case 'H':
00271 input_proc_handle_handlers(input_proc_cur_info, s);
00272 break;
00273
00274 case 'B':
00275 input_proc_handle_bits(input_proc_cur_info, s);
00276 break;
00277
00278
00279 default:
00280 break;
00281 }
00282 }
00283
00286 static void 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 {
00294 DIE(("Couldn't open /proc/bus/input/devices"));
00295 }
00296
00297 while( !feof(f) )
00298 {
00299 fgets(buf, 256, f);
00300 input_proc_parse_line(buf);
00301 }
00302 input_proc_device_done(input_proc_cur_info);
00303
00304 {
00305 input_proc_info* i;
00306 for(i=input_proc_head; i!=NULL; i=i->next)
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
00384
00385
00386 static void input_got_sysdevice(HalDevice* device,
00387 void* data1, void* data2);
00388
00393 static void process_input_proc_info(input_proc_info* i)
00394 {
00395 int n;
00396 HalDevice* d;
00397 char phys[128];
00398
00399
00400 for(n=0; n<128; n++)
00401 {
00402 if( i->phys_name[n]=='/' )
00403 break;
00404 phys[n] = i->phys_name[n];
00405 }
00406 phys[n] = '\0';
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 d = ds_device_new();
00417
00418 ds_property_set_string(d, "input.linux.phys",
00419 i->phys_name);
00420 ds_property_set_string(d, "input.linux.handlers",
00421 i->handlers);
00422 ds_property_set_int(d, "input.linux.evbit",
00423 i->evbit);
00424 ds_property_set_int(d, "input.linux.ledbit",
00425 i->ledbit);
00426 ds_property_set_int(d, "input.linux.relbit",
00427 i->relbit);
00428 ds_property_set_int(d, "input.linux.absbit",
00429 i->absbit);
00430 ds_property_set_string(d, "input.linux.keybit",
00431 i->keybit);
00432
00433
00434
00435
00436
00437 ds_property_set_bool(d, "input.key",
00438 i->evbit&(1<<EV_KEY));
00439 ds_property_set_bool(d, "input.relative",
00440 i->evbit&(1<<EV_REL));
00441 ds_property_set_bool(d, "input.absolute",
00442 i->evbit&(1<<EV_ABS));
00443 ds_property_set_bool(d, "input.led",
00444 i->evbit&(1<<EV_LED));
00445 ds_property_set_bool(d, "input.sound",
00446 i->evbit&(1<<EV_SND));
00447 ds_property_set_bool(d, "input.repeat",
00448 i->evbit&(1<<EV_REP));
00449 ds_property_set_bool(d, "input.force_feedback",
00450 i->evbit&(1<<EV_FF));
00451 ds_property_set_bool(d, "input.misc",
00452 i->evbit&(1<<EV_MSC));
00453 #ifdef EV_RST
00454 ds_property_set_bool(d, "input.rst",
00455 i->evbit&(1<<EV_RST));
00456 #elif EV_SYN
00457 ds_property_set_bool(d, "input.rst",
00458 i->evbit&(1<<EV_SYN));
00459 #endif
00460
00461 if( i->evbit&(1<<EV_LED) )
00462 {
00463 ds_property_set_bool(d, "input.led.numlock",
00464 i->ledbit&(1<<LED_NUML));
00465 ds_property_set_bool(d, "input.led.capslock",
00466 i->ledbit&(1<<LED_CAPSL));
00467 ds_property_set_bool(d, "input.led.scrolllock",
00468 i->ledbit&(1<<LED_SCROLLL));
00469 ds_property_set_bool(d, "input.led.compose",
00470 i->ledbit&(1<<LED_COMPOSE));
00471 ds_property_set_bool(d, "input.led.kana",
00472 i->ledbit&(1<<LED_KANA));
00473 ds_property_set_bool(d, "input.led.sleep",
00474 i->ledbit&(1<<LED_SLEEP));
00475 ds_property_set_bool(d, "input.led.suspend",
00476 i->ledbit&(1<<LED_SUSPEND));
00477 ds_property_set_bool(d, "input.led.mute",
00478 i->ledbit&(1<<LED_MUTE));
00479 ds_property_set_bool(d, "input.led.misc",
00480 i->ledbit&(1<<LED_MISC));
00481 ds_property_set_bool(d, "input.led.max",
00482 i->ledbit&(1<<LED_MAX));
00483 }
00484
00485 if( i->evbit&(1<<EV_REL) )
00486 {
00487 ds_property_set_bool(d, "input.relative.x",
00488 i->relbit&(1<<REL_X));
00489 ds_property_set_bool(d, "input.relative.y",
00490 i->relbit&(1<<REL_Y));
00491 ds_property_set_bool(d, "input.relative.z",
00492 i->relbit&(1<<REL_Z));
00493 ds_property_set_bool(d, "input.relative.hwheel",
00494 i->relbit&(1<<REL_HWHEEL));
00495 ds_property_set_bool(d, "input.relative.dial",
00496 i->relbit&(1<<REL_DIAL));
00497 ds_property_set_bool(d, "input.relative.wheel",
00498 i->relbit&(1<<REL_WHEEL));
00499 ds_property_set_bool(d, "input.relative.misc",
00500 i->relbit&(1<<REL_MISC));
00501 }
00502
00503 if( i->evbit&(1<<EV_ABS) )
00504 {
00505 ds_property_set_bool(d, "input.absolute.x",
00506 i->absbit&(1<<ABS_X));
00507 ds_property_set_bool(d, "input.absolute.y",
00508 i->absbit&(1<<ABS_Y));
00509 ds_property_set_bool(d, "input.absolute.z",
00510 i->absbit&(1<<ABS_Z));
00511 ds_property_set_bool(d, "input.absolute.rx",
00512 i->absbit&(1<<ABS_RX));
00513 ds_property_set_bool(d, "input.absolute.ry",
00514 i->absbit&(1<<ABS_RY));
00515 ds_property_set_bool(d, "input.absolute.rz",
00516 i->absbit&(1<<ABS_RZ));
00517 ds_property_set_bool(d, "input.absolute.throttle",
00518 i->absbit&(1<<ABS_THROTTLE));
00519 ds_property_set_bool(d, "input.absolute.rudder",
00520 i->absbit&(1<<ABS_RUDDER));
00521 ds_property_set_bool(d, "input.absolute.wheel",
00522 i->absbit&(1<<ABS_WHEEL));
00523 ds_property_set_bool(d, "input.absolute.gas",
00524 i->absbit&(1<<ABS_GAS));
00525 ds_property_set_bool(d, "input.absolute.brake",
00526 i->absbit&(1<<ABS_BRAKE));
00527 ds_property_set_bool(d, "input.absolute.hat0x",
00528 i->absbit&(1<<ABS_HAT0X));
00529 ds_property_set_bool(d, "input.absolute.hat0y",
00530 i->absbit&(1<<ABS_HAT0Y));
00531 ds_property_set_bool(d, "input.absolute.hat1x",
00532 i->absbit&(1<<ABS_HAT1X));
00533 ds_property_set_bool(d, "input.absolute.hat1y",
00534 i->absbit&(1<<ABS_HAT1Y));
00535 ds_property_set_bool(d, "input.absolute.hat2x",
00536 i->absbit&(1<<ABS_HAT2X));
00537 ds_property_set_bool(d, "input.absolute.hat2y",
00538 i->absbit&(1<<ABS_HAT2Y));
00539 ds_property_set_bool(d, "input.absolute.pressure",
00540 i->absbit&(1<<ABS_PRESSURE));
00541 ds_property_set_bool(d, "input.absolute.distance",
00542 i->absbit&(1<<ABS_DISTANCE));
00543 ds_property_set_bool(d, "input.absolute.tilt_x",
00544 i->absbit&(1<<ABS_TILT_X));
00545 ds_property_set_bool(d, "input.absolute.tilt_Y",
00546 i->absbit&(1<<ABS_TILT_Y));
00547 ds_property_set_bool(d, "input.absolute.misc",
00548 i->absbit&(1<<ABS_MISC));
00549 }
00550
00551
00552 ds_add_capability(d, "input");
00553
00558 if( i->relbit!=0 )
00559 {
00560 ds_add_capability(d, "input.mouse");
00561 ds_property_set_string(d, "info.category", "input.mouse");
00562 }
00563 else
00564 {
00565 ds_add_capability(d, "input.keyboard");
00566 ds_property_set_string(d, "info.category", "input.keyboard");
00567 }
00568
00574
00575
00576
00577
00578 ds_device_async_find_by_key_value_string("linux.kernel_devname",
00579 phys,
00580 FALSE,
00581 input_got_sysdevice,
00582 (void*) d, NULL,
00583 is_probing ? 0 :
00584 HAL_LINUX_HOTPLUG_TIMEOUT);
00585 }
00586
00594 static void input_got_sysdevice(HalDevice* sysdevice,
00595 void* data1, void* data2)
00596 {
00597 HalDevice* d = (HalDevice*) data1;
00598
00599 if( sysdevice==NULL )
00600 {
00601 HAL_WARNING(("Sysdevice for a class input device never appeared!"));
00602 }
00603 else
00604 {
00605
00606
00607
00608 ds_device_merge(sysdevice, d);
00609 }
00610
00611
00612 ds_device_destroy(d);
00613 }
00614
00615
00620 void linux_class_input_probe()
00621 {
00622 input_proc_info* i;
00623
00624 input_proc_parse();
00625
00626 for(i=input_proc_head; i!=NULL; i=i->next)
00627 process_input_proc_info(i);
00628 }
00629
00630
00641 void linux_class_input_handle_hotplug_add(char* name, char* phys, char* key,
00642 int ev, int rel, int abs, int led)
00643 {
00644 char* s;
00645 input_proc_info* i;
00646
00647 i = get_input_proc_cur_info_obj();
00648
00651 strncpy(i->name, name, 128);
00652 strncpy(i->phys_name, phys, 128);
00653 strncpy(i->keybit, key, 128);
00654 i->evbit = ev;
00655 i->relbit = rel;
00656 i->absbit = abs;
00657 i->ledbit = led;
00658
00659 process_input_proc_info(i);
00660 }
00661
00665 void linux_class_input_init()
00666 {
00667 }
00668
00673 void linux_class_input_detection_done()
00674 {
00675 }
00676
00680 void linux_class_input_shutdown()
00681 {
00682 }
00683