From e12059711346f72f73cb3595548f75d88aef56d1 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Sun, 7 Nov 2004 16:28:25 +0000 Subject: cleaned up the code a fair amount, but there are still lots of bugs bugs bugs... svn path=/trunk/externals/hcs/hid/; revision=2238 --- TODO | 28 +---- doc/hid-help.pd | 133 +++++++++++++++-------- doc/mouse-help.pd | 34 +++++- hid.c | 129 +++++++++++++++-------- hid.h | 12 ++- hid_darwin.c | 309 +++++++++++++----------------------------------------- hid_linux.c | 8 +- 7 files changed, 293 insertions(+), 360 deletions(-) diff --git a/TODO b/TODO index 59d6891..5f5df00 100644 --- a/TODO +++ b/TODO @@ -1,14 +1,5 @@ ============================================================================== -= define generic event struct (probably Pd-ized input_event ) - something like: - -struct input_event { - struct timeval time; - t_int type; - t_int code; - t_int value; -}; - += define generic event timestamp struct (probably Pd-ized input_event ) The question is whether the timeval is needed at all. Linux and Darwin support it. Currently, I can only think of UPS PWR events actually using @@ -22,10 +13,6 @@ timevals. UsagePage -Misc Input/Generic Desktop X == ev_rel/rel_x -Button Input/Button #1 == ev_key/btn_left - - LED UsagePage => ev_led LED Usages == Linux ev_led codes @@ -60,18 +47,6 @@ Darwin implemented -============================================================================== -= raw values vs. calibrated - -- relative axes should probably be raw data, since its pixel data, but then - this causes problems with sensitivity across different mice. The mouse - sensitivity would probably best translate as resolution, ie calibrated data, - rather than sensitivity, ie raw data. - -- absolute axes should be calibrated, so that the same positions on different - devices map to the same value - - ============================================================================== = pollfn for mouse-like devices @@ -83,7 +58,6 @@ Darwin - this is probably unnecessary since the t_clock seems to run well at 1ms delay - ============================================================================== = function return values diff --git a/doc/hid-help.pd b/doc/hid-help.pd index 2b56758..340480f 100644 --- a/doc/hid-help.pd +++ b/doc/hid-help.pd @@ -1,5 +1,5 @@ -#N canvas 143 45 927 650 10; -#X msg 390 265 ev_rel rel_x 0 4.08559e+09; +#N canvas 156 27 943 666 10; +#X msg 390 265 ev_rel rel_x 2 3.57445e+09; #X obj 390 244 prepend set; #X obj 149 473 route rel_x rel_y; #X floatatom 149 493 5 0 0 0 - - -; @@ -20,10 +20,6 @@ #X floatatom 500 392 12 0 0 1 value - -; #X symbolatom 468 409 10 0 0 1 eventcode - -; #X symbolatom 438 428 15 0 0 1 eventtype - -; -#X floatatom 93 536 5 0 0 0 - - -; -#X floatatom 168 537 5 0 0 0 - - -; -#X obj 93 514 route key_f key_leftctrl btn_left; -#X floatatom 243 537 5 0 0 0 - - -; #X obj 177 296 bng 35 250 50 0 empty empty event_received 38 18 1 9 -225280 -1 -1; #X obj 2 2 cnv 15 900 20 empty empty [hid] 2 11 1 18 -233017 -66577 @@ -55,15 +51,15 @@ #X msg 336 113 refresh; #X text 397 111 refresh device list; #X obj 248 225 hid 2; -#X obj 337 514 unpack s f f; -#X obj 376 532 tgl 25 0 empty empty any_button 27 13 1 9 -195568 -1 +#X obj 94 524 unpack s f f; +#X obj 133 542 tgl 25 0 empty empty any_button 27 13 1 9 -195568 -1 -1 0 1; -#X obj 740 511 all_about_hid; -#X text 631 512 For more info:; +#X obj 746 556 all_about_hid; +#X text 637 557 For more info:; #X text 49 588 (C) Copyright 2004 Hans-Christoph Steiner ; #X text 266 602 released under the GNU GPL; -#X text 472 589 $Revision: 1.7 $$Date: 2004-11-06 21:15:04 $; +#X text 472 589 $Revision: 1.8 $$Date: 2004-11-07 16:28:25 $; #X text 473 602 $Author: eighthave $; #X obj 206 433 route abs_x abs_y abs_z; #X floatatom 322 454 7 0 0 0 - - -; @@ -74,45 +70,92 @@ #X msg 465 180 poll 2000; #X text 371 56 !!! This software is very much alpha \, so any aspect of it could change without notice !!!; +#X text 650 400 REFRESH RATES; +#X text 660 415 ADB = 15.5 ms; +#X text 660 430 USB mice on Windows = 8-10 ms; +#X text 660 445 USB mice on GNU/Linux = 1-10 ms; +#X text 660 460 USB wireless mice = 12-20 ms; +#X text 660 475 PS/2 mouse = 5-25 ms; +#X text 660 490 P5 Glove = 22 ms; +#N canvas 0 22 454 304 JustFOrTestng 0; +#X msg 390 265 ev_rel rel_x 0 2.56485e+09; +#X obj 390 244 prepend set; +#X msg 148 77 start; +#X msg 174 96 stop; +#X msg 239 57 open 0; +#X msg 246 75 open 1; +#X msg 253 93 open 2; +#X msg 259 111 open 3; +#X msg 265 129 open 4; +#X obj 86 81 tgl 35 0 empty empty empty 0 -6 0 8 -24198 -1 -1 0 25 +; +#X obj 223 266 spigot; +#X obj 269 266 tgl 17 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X msg 336 136 close; +#X text 380 136 probably not needed; +#X msg 336 113 refresh; +#X text 397 111 refresh device list; +#X msg 398 180 poll 20; +#X msg 336 180 poll 2; +#X text 332 159 start polling and set the poll delay in ms; +#X msg 465 180 poll 2000; +#X text 371 56 !!! This software is very much alpha \, so any aspect +of it could change without notice !!!; +#X obj 248 225 hid 1; +#X connect 1 0 0 0; +#X connect 2 0 21 0; +#X connect 3 0 21 0; +#X connect 4 0 21 0; +#X connect 5 0 21 0; +#X connect 6 0 21 0; +#X connect 7 0 21 0; +#X connect 8 0 21 0; +#X connect 9 0 21 0; +#X connect 11 0 10 1; +#X connect 12 0 21 0; +#X connect 14 0 21 0; +#X connect 16 0 21 0; +#X connect 17 0 21 0; +#X connect 19 0 21 0; +#X connect 21 0 10 0; +#X connect 21 0 1 0; +#X restore 446 483 pd JustFOrTestng; #X connect 1 0 0 0; #X connect 2 0 3 0; #X connect 2 1 4 0; -#X connect 5 0 51 0; -#X connect 6 0 51 0; +#X connect 5 0 47 0; +#X connect 6 0 47 0; #X connect 8 0 19 0; #X connect 8 1 18 0; #X connect 8 2 17 0; #X connect 8 3 7 0; -#X connect 9 0 51 0; -#X connect 10 0 51 0; -#X connect 11 0 51 0; -#X connect 12 0 51 0; -#X connect 13 0 51 0; -#X connect 16 0 51 0; -#X connect 22 0 20 0; -#X connect 22 1 21 0; -#X connect 22 2 23 0; -#X connect 22 3 52 0; +#X connect 9 0 47 0; +#X connect 10 0 47 0; +#X connect 11 0 47 0; +#X connect 12 0 47 0; +#X connect 13 0 47 0; +#X connect 16 0 47 0; +#X connect 37 0 36 0; +#X connect 37 0 20 0; +#X connect 38 0 37 1; +#X connect 39 0 48 0; +#X connect 39 1 2 0; +#X connect 39 2 56 0; +#X connect 39 3 42 0; +#X connect 40 0 41 1; #X connect 41 0 40 0; -#X connect 41 0 24 0; -#X connect 42 0 41 1; -#X connect 43 0 22 0; -#X connect 43 1 2 0; -#X connect 43 2 60 0; -#X connect 43 3 46 0; -#X connect 44 0 45 1; -#X connect 45 0 44 0; -#X connect 46 0 45 0; -#X connect 47 0 51 0; -#X connect 49 0 51 0; -#X connect 51 0 41 0; -#X connect 51 0 43 0; -#X connect 51 0 1 0; -#X connect 51 0 8 0; -#X connect 52 1 53 0; -#X connect 60 0 14 0; -#X connect 60 1 15 0; -#X connect 60 2 61 0; -#X connect 62 0 51 0; -#X connect 63 0 51 0; -#X connect 66 0 51 0; +#X connect 42 0 41 0; +#X connect 43 0 47 0; +#X connect 45 0 47 0; +#X connect 47 0 37 0; +#X connect 47 0 39 0; +#X connect 47 0 1 0; +#X connect 47 0 8 0; +#X connect 48 1 49 0; +#X connect 56 0 14 0; +#X connect 56 1 15 0; +#X connect 56 2 57 0; +#X connect 58 0 47 0; +#X connect 59 0 47 0; +#X connect 62 0 47 0; diff --git a/doc/mouse-help.pd b/doc/mouse-help.pd index 3ec4b50..0280fbc 100644 --- a/doc/mouse-help.pd +++ b/doc/mouse-help.pd @@ -1,4 +1,4 @@ -#N canvas 138 201 676 441 10; +#N canvas 225 161 684 449 10; #X symbolatom 233 198 0 0 0 0 - - -; #X obj 200 36 tgl 25 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 1 ; @@ -30,6 +30,34 @@ #X msg 250 42 open 1; #X msg 255 61 open 2; #X obj 200 91 mouse 1; +#N canvas 462 248 604 514 mouse-noise 0; +#X obj 90 55 inlet; +#X obj 113 173 mouse \$1; +#X obj 180 294 noise~; +#X obj 125 293 osc~; +#X obj 125 266 * 4000; +#X obj 113 367 *~; +#X msg 162 103 \; pd dsp 1; +#X obj 103 418 dac~; +#X obj 91 78 t f a b; +#X connect 0 0 8 0; +#X connect 1 0 5 0; +#X connect 1 1 4 0; +#X connect 2 0 5 1; +#X connect 3 0 5 1; +#X connect 4 0 3 0; +#X connect 5 0 7 0; +#X connect 5 0 7 1; +#X connect 8 0 5 0; +#X connect 8 1 1 0; +#X connect 8 2 6 0; +#X restore 464 163 pd mouse-noise 1; +#X msg 505 95 open 0; +#X msg 510 114 open 1; +#X msg 515 133 open 2; +#X obj 464 96 tgl 25 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 1 +; +#X text 347 72 turn this on to make some noise with the mouse; #X connect 1 0 20 0; #X connect 9 0 6 0; #X connect 9 1 7 0; @@ -48,3 +76,7 @@ #X connect 20 2 3 0; #X connect 20 3 0 0; #X connect 20 4 2 0; +#X connect 22 0 21 0; +#X connect 23 0 21 0; +#X connect 24 0 21 0; +#X connect 25 0 21 0; diff --git a/hid.c b/hid.c index 4ad7c53..9a091dc 100644 --- a/hid.c +++ b/hid.c @@ -32,6 +32,16 @@ //#define DEBUG(x) #define DEBUG(x) x +/* + * Various Max Refresh Rates: + ADB = 15.5 ms + USB mice on Windows = 8-10 ms + USB mice on GNU/Linux = 1-10 ms + USB wireless mice = 12-20 ms + PS/2 mouse = 5-25 ms + P5 Globe = 22 ms + */ + #define DEFAULT_DELAY 5 /*------------------------------------------------------------------------------ @@ -45,6 +55,44 @@ t_int hid_close(t_hid *x); t_int hid_read(t_hid *x,int fd); static void hid_float(t_hid* x, t_floatarg f); + +/*------------------------------------------------------------------------------ + * SUPPORT FUNCTIONS + */ + +void hid_output_event(t_hid *x, + char *type, char *code, t_float value, t_float timestamp) +{ + t_atom event_data[4]; + + SETSYMBOL(event_data, gensym(type)); /* type */ + SETSYMBOL(event_data + 1, gensym(code)); /* code */ + SETFLOAT(event_data + 2, value); /* value */ + SETFLOAT(event_data + 3, timestamp); /* timestamp */ + + outlet_anything(x->x_obj.te_outlet,atom_gensym(event_data),3,event_data+1); +} + +void hid_set_from_float(t_hid *x, t_floatarg f) +{ +/* values greater than 1 set the polling delay time */ +/* 1 and 0 for start/stop so you can use a [tgl] */ + if (f > 1) + { + x->x_delay = (t_int)f; + hid_start(x,f); + } + else if (f == 1) + { + if (! x->x_started) + hid_start(x,f); + } + else if (f == 0) + { + hid_stop(x); + } +} + /*------------------------------------------------------------------------------ * IMPLEMENTATION */ @@ -73,6 +121,7 @@ t_int hid_close(t_hid *x) if(! hid_close_device(x)) { post("[hid] closed device number %d",x->x_device_number); + x->x_device_open = 0; return (0); } @@ -80,43 +129,53 @@ t_int hid_close(t_hid *x) } +/* closed same device open */ +/* open same device no action */ +/* closed different device open */ +/* open different device close open */ + t_int hid_open(t_hid *x, t_float f) { DEBUG(post("hid_open");); -/* store running state so that it can be restored after the device has been opened */ - t_int started = x->x_started; - - hid_close(x); +/* store running state to be restored after the device has been opened */ + t_int started = x->x_started; - /* set obj device name to parameter - * otherwise set to default - */ - if (f > 0) - x->x_device_number = f; - else - x->x_device_number = 0; - - if (hid_open_device(x,x->x_device_number)) - { - error("[hid] can not open device %d",x->x_device_number); - post("\\=========================== [hid] ===========================/\n"); - return (1); - } + if ( (f != x->x_device_number) && (x->x_device_open) ) hid_close(x); + + /* set obj device name to parameter otherwise set to default */ + if (f > 0) + x->x_device_number = f; + else + x->x_device_number = 0; + + if (! x->x_device_open) + if (hid_open_device(x,x->x_device_number)) + { + error("[hid] can not open device %d",x->x_device_number); + post("\\=========================== [hid] ===========================/\n"); + return (1); + } + else + { + x->x_device_open = 1; + } /* restore the polling state so that when I [tgl] is used to start/stop [hid], - * the [tgl]'s state will continue to accurately reflect [hid]'s state - */ - hid_float(x,started); + * the [tgl]'s state will continue to accurately reflect [hid]'s state */ + hid_set_from_float(x,started); - post("\\=========================== [hid] ===========================/\n"); - return (0); + + post("\\=========================== [hid] ===========================/\n"); + return (0); } t_int hid_read(t_hid *x,int fd) { - hid_output_events(x); +// DEBUG(post("hid_read");); + + hid_get_events(x); if (x->x_started) { @@ -147,22 +206,7 @@ static void hid_float(t_hid* x, t_floatarg f) { DEBUG(post("hid_float");); -/* values greater than 1 set the polling delay time */ -/* 1 and 0 for start/stop so you can use a [tgl] */ - if(f > 1) - { - x->x_delay = (t_int)f; - hid_start(x,f); - } - else if(f == 1) - { - if (! x->x_started) - hid_start(x,f); - } - else if(f == 0) - { - hid_stop(x); - } + hid_set_from_float(x,f); } /* setup functions */ @@ -194,6 +238,7 @@ static void *hid_new(t_float f) #endif /* init vars */ + x->x_device_open = 0; x->x_started = 0; x->x_delay = DEFAULT_DELAY; @@ -203,7 +248,7 @@ static void *hid_new(t_float f) outlet_new(&x->x_obj, 0); /* find and report the list of devices */ - hid_devicelist_refresh(x); + hid_build_device_list(x); /* Open the device and save settings. If there is an error, return the object * anyway, so that the inlets and outlets are created, thus not breaking the @@ -229,7 +274,7 @@ void hid_setup(void) class_addbang(hid_class,(t_method) hid_read); /* add inlet message methods */ - class_addmethod(hid_class,(t_method) hid_devicelist_refresh,gensym("refresh"),0); + class_addmethod(hid_class,(t_method) hid_build_device_list,gensym("refresh"),0); class_addmethod(hid_class,(t_method) hid_open,gensym("open"),A_DEFFLOAT,0); class_addmethod(hid_class,(t_method) hid_close,gensym("close"),0); class_addmethod(hid_class,(t_method) hid_start,gensym("start"),A_DEFFLOAT,0); diff --git a/hid.h b/hid.h index f94aa53..cc8fd32 100644 --- a/hid.h +++ b/hid.h @@ -14,7 +14,7 @@ #define HID_MAJOR_VERSION 0 #define HID_MINOR_VERSION 1 -static char *version = "$Revision: 1.8 $"; +static char *version = "$Revision: 1.9 $"; /*------------------------------------------------------------------------------ * CLASS DEF @@ -27,11 +27,11 @@ typedef struct _hid t_int x_fd; t_symbol *x_devname; t_int x_device_number; - long x_locID; t_clock *x_clock; t_int x_delay; t_int x_started; t_int x_device_open; + t_int x_instance_count; } t_hid; @@ -48,11 +48,15 @@ char *codeList[256]; * FUNCTION PROTOTYPES FOR DIFFERENT PLATFORMS */ +/* support functions */ +void hid_output_event(t_hid *x, + char *type, char *code, t_float value, t_float timestamp); + /* generic, cross-platform functions */ t_int hid_open_device(t_hid *x, t_int device_number); t_int hid_close_device(t_hid *x); -t_int hid_devicelist_refresh(t_hid* x); -t_int hid_output_events(t_hid *x) ; +t_int hid_build_device_list(t_hid* x); +t_int hid_get_events(t_hid *x) ; void hid_platform_specific_free(t_hid *x); #endif /* #ifndef _HID_H */ diff --git a/hid_darwin.c b/hid_darwin.c index 751c14e..49ec028 100644 --- a/hid_darwin.c +++ b/hid_darwin.c @@ -43,14 +43,7 @@ #include #include "HID_Utilities_External.h" -#include "HID_Error_Handler.h" -/* -#include -#include -#include -#include -*/ #include #include @@ -58,13 +51,14 @@ #include "hid.h" -#define DEBUG(x) -//#define DEBUG(x) x +//#define DEBUG(x) +#define DEBUG(x) x /*============================================================================== * GLOBAL VARS *======================================================================== */ + /*============================================================================== * FUNCTION PROTOTYPES *============================================================================== @@ -73,47 +67,11 @@ /* conversion functions */ char *convertEventsFromDarwinToLinux(pRecElement element); -/* IOKit HID Utilities functions from SC_HID.cpp */ -int prHIDBuildElementList(t_hid *x); -int prHIDBuildDeviceList(void); -int prHIDGetValue(void); - /*============================================================================== * EVENT TYPE/CODE CONVERSION FUNCTIONS *============================================================================== */ -void convertDarwinToLinuxType(IOHIDElementType type, char *returnType) -{ - switch (type) - { - case kIOHIDElementTypeInput_Misc: - sprintf(returnType, "ev_msc"); - break; - case kIOHIDElementTypeInput_Button: - sprintf(returnType, "ev_key"); - break; - case kIOHIDElementTypeInput_Axis: - sprintf(returnType, "ev_abs"); - break; - case kIOHIDElementTypeInput_ScanCodes: - sprintf(returnType, "undefined"); - break; - case kIOHIDElementTypeOutput: - sprintf(returnType, "undefined"); - break; - case kIOHIDElementTypeFeature: - sprintf(returnType, "undefined"); - break; - case kIOHIDElementTypeCollection: - sprintf(returnType, "undefined"); - break; - default: - HIDReportErrorNum("Unknown element type : ", type); - sprintf(returnType, "unknown"); - } -} - void convertAxis(pRecElement element, char *linux_type, char *linux_code, char axis) { if (element->relative) @@ -128,6 +86,7 @@ void convertAxis(pRecElement element, char *linux_type, char *linux_code, char a } } + void convertDarwinElementToLinuxTypeCode(pRecElement element, char *linux_type, char *linux_code) { t_int button_offset = 0; @@ -150,6 +109,8 @@ void convertDarwinElementToLinuxTypeCode(pRecElement element, char *linux_type, case kHIDUsage_GD_Rx: convertAxis(element, linux_type, linux_code, 'x'); break; case kHIDUsage_GD_Ry: convertAxis(element, linux_type, linux_code, 'y'); break; case kHIDUsage_GD_Rz: convertAxis(element, linux_type, linux_code, 'z'); break; + case kHIDUsage_GD_Wheel: + sprintf(linux_type,"ev_rel");sprintf(linux_code,"rel_wheel");break; } break; case kHIDPage_Button: @@ -164,43 +125,6 @@ void convertDarwinElementToLinuxTypeCode(pRecElement element, char *linux_type, /* DARWIN-SPECIFIC SUPPORT FUNCTIONS */ /* ============================================================================== */ -t_int hid_build_element_list(t_hid *x) -{ - DEBUG(post("hid_build_element_list");); - - UInt32 i; - pRecElement devElement; - pRecDevice pCurrentHIDDevice; - UInt32 numElements; - char cstrElementName[256]; - - // look for the right device using locID - pCurrentHIDDevice = HIDGetFirstDevice (); - while (pCurrentHIDDevice && (pCurrentHIDDevice->locID != x->x_locID)) - pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); - if(!pCurrentHIDDevice) return (1); - - devElement = HIDGetFirstDeviceElement(pCurrentHIDDevice, kHIDElementTypeInput); - numElements = HIDCountDeviceElements(pCurrentHIDDevice, kHIDElementTypeInput); - - post("[hid] found %d elements:",numElements); - - for(i=0; itype, cstrElementName); - post(" Type: %s %d 0x%x",cstrElementName,devElement->type,devElement->type); - convertDarwinToLinuxType((IOHIDElementType) devElement->type, cstrElementName); - post(" Type: %s %d 0x%x",cstrElementName,devElement->type,devElement->type); - //usage - HIDGetUsageName (devElement->usagePage, devElement->usage, cstrElementName); - post(" Usage/Code: %s %d 0x%x",cstrElementName,devElement->usage,devElement->usage); - - devElement = HIDGetNextDeviceElement (devElement, kHIDElementTypeInput); - } - return (0); -} - pRecDevice hid_get_device_by_number(t_int device_number) { pRecDevice currentDevice; @@ -227,13 +151,46 @@ pRecDevice hid_get_device_by_number(t_int device_number) return currentDevice; } +t_int hid_build_element_list(t_hid *x) +{ + DEBUG(post("hid_build_element_list");); + + UInt32 i; + pRecElement pCurrentHIDElement; + pRecDevice pCurrentHIDDevice; + UInt32 numElements; + char type[256]; + char code[256]; + char type_name[256]; + char usage_name[256]; + + pCurrentHIDDevice = hid_get_device_by_number(x->x_device_number); + if(!pCurrentHIDDevice) return (1); + + pCurrentHIDElement = HIDGetFirstDeviceElement(pCurrentHIDDevice, kHIDElementTypeInput); + numElements = HIDCountDeviceElements(pCurrentHIDDevice, kHIDElementTypeInput); + + DEBUG(post("[hid] found %d elements:",numElements);); + + for(i=0; itype, type_name); + HIDGetUsageName(pCurrentHIDElement->usagePage, pCurrentHIDElement->usage, usage_name); + post("\tType: %s \t code: %s \t event name: \t %s, %s",type,code,type_name,usage_name); + + pCurrentHIDElement = HIDGetNextDeviceElement (pCurrentHIDElement, kHIDElementTypeInput); + } + return (0); +} + /* ============================================================================== */ /* Pd [hid] FUNCTIONS */ /* ============================================================================== */ -t_int hid_output_events(t_hid *x) +t_int hid_get_events(t_hid *x) { - DEBUG(post("hid_output_events");); + //DEBUG(post("hid_get_events");); SInt32 value; pRecDevice pCurrentHIDDevice; @@ -247,14 +204,14 @@ t_int hid_output_events(t_hid *x) int event_counter = 0; Boolean result; - // look for the right device: - pCurrentHIDDevice = HIDGetFirstDevice (); - while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=x->x_locID)) - pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); - if(!pCurrentHIDDevice) return (1); + pCurrentHIDDevice = hid_get_device_by_number(x->x_device_number); + + if(!pCurrentHIDDevice) + { + post("[hid] can't find current device %d. Was it unplugged?",x->x_device_number); + return (1); + } -// result = HIDGetEvent(pCurrentHIDDevice, (void*) &event); -// if(result) while( (HIDGetEvent(pCurrentHIDDevice, (void*) &event)) && (event_counter < 64) ) { value = event.value; @@ -267,9 +224,6 @@ t_int hid_output_events(t_hid *x) pCurrentHIDElement = HIDGetNextDeviceElement (pCurrentHIDElement, kHIDElementTypeIO); DEBUG( -// convertDarwinToLinuxType((IOHIDElementType) pCurrentHIDElement->type, event_output_string); - HIDGetUsageName(pCurrentHIDElement->usagePage, pCurrentHIDElement->usage, event_output_string); - HIDGetElementNameFromVendorProductCookie( pCurrentHIDDevice->vendorID, pCurrentHIDDevice->productID, (long) pCurrentHIDElement->cookie, event_output_string); @@ -277,16 +231,9 @@ t_int hid_output_events(t_hid *x) convertDarwinElementToLinuxTypeCode(pCurrentHIDElement,type,code); DEBUG(post("type: %s code: %s event name: %s",type,code,event_output_string);); - SETSYMBOL(event_data, gensym(type)); - /* code */ - SETSYMBOL(event_data + 1, gensym(code)); - /* value */ - SETFLOAT(event_data + 2, (t_float)value); - /* time */ - // TODO: convert this to a common time format, i.e. Linux struct timeval - SETFLOAT(event_data + 3, (t_float)(event.timestamp).lo); - - outlet_anything(x->x_obj.te_outlet,atom_gensym(event_data),3,event_data+1); + + // TODO: convert this to a common time format, i.e. Linux struct timeval + hid_output_event(x,type,code,(t_float)value,(t_float)(event.timestamp).lo); ++event_counter; } @@ -344,15 +291,13 @@ t_int hid_open_device(t_hid *x, t_int device_number) currentDevice = hid_get_device_by_number(device_number); - x->x_locID = currentDevice->locID; - post("[hid] opened device %d: %s %s", device_number, currentDevice->manufacturer, currentDevice->product); hid_build_element_list(x); HIDQueueDevice(currentDevice); -// TODO: queue all elements except absolute axes +// TODO: queue all elements except absolute axes, those can just be polled return (0); } @@ -366,160 +311,50 @@ t_int hid_close_device(t_hid *x) return( HIDDequeueDevice( hid_get_device_by_number(x->x_device_number) ) ); } -t_int hid_devicelist_refresh(t_hid *x) -{ - DEBUG(post("hid_devicelist_refresh");); - - /* the device list should be refreshed here */ - if ( (prHIDBuildDeviceList()) && (prHIDBuildElementList(x)) ) - return (0); - else - return (1); -} - -void hid_platform_specific_free(t_hid *x) -{ - HIDReleaseAllDeviceQueues(); - HIDReleaseDeviceList(); -} - -/*============================================================================== - * HID UTILIES FUNCTIONS FROM SC_HID.cpp - *============================================================================== - */ -int prHIDBuildElementList(t_hid *x) +t_int hid_build_device_list(t_hid *x) { - DEBUG(post("prHIDBuildElementList");); - - int locID = NULL; - UInt32 i; - pRecElement devElement; - pRecDevice pCurrentHIDDevice; - UInt32 numElements; - char cstrElementName [256]; - -// Apple Trackpad locID for testing - locID = 50397184; - - // look for the right device using locID - pCurrentHIDDevice = HIDGetFirstDevice (); - while (pCurrentHIDDevice && (pCurrentHIDDevice->locID != x->x_locID)) - pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); - if(!pCurrentHIDDevice) return (1); - - devElement = HIDGetFirstDeviceElement(pCurrentHIDDevice, kHIDElementTypeInput); - numElements = HIDCountDeviceElements(pCurrentHIDDevice, kHIDElementTypeInput); - - post("[hid] found %d elements",numElements); - - for(i=0; itype, cstrElementName); - post("Type: %s %d 0x%x",cstrElementName,devElement->type,devElement->type); - //usage - HIDGetUsageName (devElement->usagePage, devElement->usage, cstrElementName); - post("Usage: %s %d 0x%x",cstrElementName,devElement->usage,devElement->usage); - - //devstring = newPyrString(g->gc, cstrElementName, 0, true); - //SetObject(devElementArray->slots+devElementArray->size++, devstring); - //g->gc->GCWrite(devElementArray, (PyrObject*) devstring); - - devElement = HIDGetNextDeviceElement (devElement, kHIDElementTypeInput); - } - return (0); -} - -int prHIDBuildDeviceList(void) -{ - DEBUG(post("prHIDBuildDeviceList");); + DEBUG(post("hid_build_device_list");); int i,err; UInt32 usagePage, usage; - pRecElement devElement; pRecDevice pCurrentHIDDevice; - //pass in usage & usagepage - //kHIDUsage_GD_Joystick kHIDUsage_GD_GamePad - //usagePage = kHIDPage_GenericDesktop; - //usage = NULL; - Boolean result = HIDBuildDeviceList (NULL, NULL); // returns false if no device found - if(result) error("[hid]: no HID devices found\n"); int numdevs = HIDCountDevices(); // exit if no devices found if(!numdevs) return (0); - post("number of devices: %d", numdevs); char cstrDeviceName [256]; - pCurrentHIDDevice = HIDGetFirstDevice(); - for(i=numdevs - 1; i >= 0; --i) + /* display device list in console */ + for(i=0; i < numdevs; i++) { - post("Device %d: '%s' '%s' version %d",i, - pCurrentHIDDevice->manufacturer,pCurrentHIDDevice->product,pCurrentHIDDevice->version); + pCurrentHIDDevice = hid_get_device_by_number(i); + post("Device %d: '%s' '%s' version %d",i,pCurrentHIDDevice->manufacturer, + pCurrentHIDDevice->product,pCurrentHIDDevice->version); //usage - HIDGetUsageName (pCurrentHIDDevice->usagePage, pCurrentHIDDevice->usage, cstrDeviceName); + HIDGetUsageName (pCurrentHIDDevice->usagePage, + pCurrentHIDDevice->usage, + cstrDeviceName); post(" vendorID: %d productID: %d locID: %d", - pCurrentHIDDevice->vendorID,pCurrentHIDDevice->productID,pCurrentHIDDevice->locID); - pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); - } - - UInt32 outnum = HIDCountDeviceElements (pCurrentHIDDevice, kHIDElementTypeOutput); - post("number of outputs: %d \n", outnum); + pCurrentHIDDevice->vendorID, + pCurrentHIDDevice->productID, + pCurrentHIDDevice->locID); - return (0); + // TODO: display all of the element types/codes for each device + } + + return (0); } - -int prHIDGetValue(void) +void hid_platform_specific_free(t_hid *x) { - DEBUG(post("hid_output_events");); - - int locID = NULL; - int cookieNum = NULL; - SInt32 value; - /* - PyrSlot *a = g->sp - 2; //class - PyrSlot *b = g->sp - 1; //locID device - PyrSlot *c = g->sp; //element cookie - int locID, cookieNum; - int err = slotIntVal(b, &locID); - if (err) return err; - err = slotIntVal(c, &cookieNum); - if (err) return err; - */ - IOHIDElementCookie cookie = (IOHIDElementCookie) cookieNum; - // look for the right device: - pRecDevice pCurrentHIDDevice = HIDGetFirstDevice (); - while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID)) - pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); - if(!pCurrentHIDDevice) return (1); - - - // look for the right element: - pRecElement pCurrentHIDElement = HIDGetFirstDeviceElement (pCurrentHIDDevice, kHIDElementTypeIO); - // use gElementCookie to find current element - while (pCurrentHIDElement && (pCurrentHIDElement->cookie != cookie)) - pCurrentHIDElement = HIDGetNextDeviceElement (pCurrentHIDElement, kHIDElementTypeIO); - - - if (pCurrentHIDElement) - { - value = HIDGetElementValue (pCurrentHIDDevice, pCurrentHIDElement); - // if it's not a button and it's not a hatswitch then calibrate - if(( pCurrentHIDElement->type != kIOHIDElementTypeInput_Button ) && - ( pCurrentHIDElement->usagePage == 0x01 && pCurrentHIDElement->usage != kHIDUsage_GD_Hatswitch)) - value = HIDCalibrateValue ( value, pCurrentHIDElement ); - //SetInt(a, value); - } - //else SetNil(a); - return (0); - + HIDReleaseAllDeviceQueues(); + HIDReleaseDeviceList(); } //void HIDGetUsageName (const long valueUsagePage, const long valueUsage, char * cstrName) diff --git a/hid_linux.c b/hid_linux.c index 28732cd..9b86fec 100644 --- a/hid_linux.c +++ b/hid_linux.c @@ -37,9 +37,9 @@ * which would be very annoying. */ -t_int hid_output_events(t_hid *x) +t_int hid_get_events(t_hid *x) { - DEBUG(post("hid_output_events");); + DEBUG(post("hid_get_events");); /* for debugging, counts how many events are processed each time hid_read() is called */ t_int i; @@ -217,9 +217,9 @@ t_int hid_close_device(t_hid *x) return (close(x->x_fd)); } -t_int hid_devicelist_refresh(t_hid *x) +t_int hid_build_device_list(t_hid *x) { - DEBUG(post("hid_devicelist_refresh");); + DEBUG(post("hid_build_device_list");); /* the device list should be refreshed here */ /* * since in GNU/Linux the device list is the input event devices -- cgit v1.2.1