From c20ee1f2878608e9417c9a00c487fa0fbd7837a2 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Sat, 27 May 2006 16:41:59 +0000 Subject: new open-by methods seem to be working properly svn path=/trunk/externals/hcs/hid/; revision=5143 --- TODO | 109 +++---------------------- doc/hid-help.pd | 245 ++++++++++++++++++++++++++++---------------------------- hid.c | 224 ++++++++++++++++++++++++++------------------------- hid.h | 10 +-- hid_darwin.c | 73 +++++++++++------ 5 files changed, 301 insertions(+), 360 deletions(-) diff --git a/TODO b/TODO index 74954d0..9a4af45 100644 --- a/TODO +++ b/TODO @@ -1,12 +1,19 @@ +============================================================================== += output device data on open + +- Logical Min/Max i.e. [range -127 127( +- open 1/0 i.e. [open 1( +- vendor/product id i.e. [id 0x1234 0x4567( +- device string [name Trackpad( -TODO: make open functions: -device number -vendor_id product_id -Product String +============================================================================== += open devices by name + +i.e "Trackpad" a la Max's [hi] ============================================================================== @@ -63,38 +70,12 @@ Product String - find out if [autoscale] takes a lot of CPU power, or where in [hid] is using CPU where it doesn't have to be - -============================================================================== -= device selection - -by # (1,2,...), generic name (mouse1, joystick2, tablet3...), or device name -("Trackpad", "Microsoft 5-button Mouse with IntelliEye(TM)", etc.) - - ============================================================================== = Report available FF effects - check against HID Utilities Source/PID.h -============================================================================== -= device 0 gets events for all available devices - -- it might be useful to have device #0 open all available devices and output - the events. - - -============================================================================== -= figure out how to store device ID in obj struct - -(in SC_HID.c its locID and cookie) - -- it should probably just store the Pd arguments - -- this will have to be dealt with when the "mouse0", "joystick2" arguments are - implemented - - ============================================================================== = pollfn for mouse-like devices @@ -114,70 +95,12 @@ by # (1,2,...), generic name (mouse1, joystick2, tablet3...), or device name - most functions probably do not need return values -============================================================================== -= control input messages - -- are [poll(, [start(, and [stop( needed? is 0/1/delay# enough? - - -============================================================================== -= consistent console output - -void hid_post(const char *format, const char *); - - ============================================================================== = event name changes - make key/button Type "button" rather than "key" (undecided on this one) -============================================================================== -= make [linuxhid] [darwinhid] and [windowshid] - -- so much info is lost in the translation to a common event scheme that it - would be quite handy to have platform-specific objects. This would give - access to the entire range of devices supported by HID Manager, Linux input - events, etc. - -- these objects should follow the same conventions as [hid] - - -============================================================================== -= figure out whole degree issue - -- should degree conversion also change rotation direction and 0 point? The - degrees on a compass rotate the opposite direction of radians. The 0 point - of a compass is due north, with radians, its right/due east. - -- [hid_polar] should take an argument (in degrees?) which specifies where the - 0 is on the circle - - -============================================================================== -= mapping object ideas - -[hid2midi] [midi2hid] - -midi value + bend <-> hid - - use MIDI pitch and bend data for values in between MIDI notes? - -object for Fletcher-Munson Equal-loudness contours - -median average object - -[infinitepot] for use with a [knob] or any single axis that could be infinite. - -[hid_debounce] - -peak finder object - -"kalman filters" - -Curves!! - -http://www.2dcurves.com - ============================================================================== = check out using USB timestamp @@ -207,16 +130,6 @@ ______________________________________________________________________________ pointing to that same device -______________________________________________________________________________ -- BUG: on MacOS X, mouse axis data is limited by the screen dimensions - -- the axes data stops outputting when the mouse pointer reaches the edge of - the screen. Hopefully the HID Manager API will allow raw mouse data - access. It must since its used with games. - -- turn off/unlink mousepointer for that device? - - ______________________________________________________________________________ - BUG: getting events from the queue doesn't output a 0 value event when the motion stops, so when the mouse stops, the sound keeps playing. diff --git a/doc/hid-help.pd b/doc/hid-help.pd index 892689d..74b0b51 100644 --- a/doc/hid-help.pd +++ b/doc/hid-help.pd @@ -1,53 +1,47 @@ -#N canvas 264 93 957 670 10; -#X msg 455 295 key btn_0 0; +#N canvas 164 36 915 630 10; +#X msg 233 353 rel rel_x 1; #X floatatom 27 484 5 0 0 0 - - -; #X floatatom 83 484 5 0 0 0 - - -; #X floatatom 63 440 6 0 0 0 - - -; #X obj 129 122 tgl 35 0 empty empty empty 0 -6 0 8 -24198 -1 -1 0 25 ; -#X floatatom 534 356 12 0 0 1 value - -; -#X symbolatom 494 372 15 0 0 1 event_code - -; -#X symbolatom 455 388 15 0 0 1 event_type - -; -#X obj 5 270 bng 35 250 50 0 empty empty event_received 38 18 1 9 -262144 --1 -1; +#X floatatom 571 385 12 0 0 1 value - -; +#X symbolatom 531 401 15 0 0 1 event_code - -; +#X symbolatom 492 417 15 0 0 1 event_type - -; #X obj 2 2 cnv 15 900 20 empty empty [hid] 2 11 1 18 -233017 -66577 0; -#X text 363 234 outlet message format:; -#X obj 742 104 ev-list; -#X obj 742 155 ev_syn-list; -#X obj 742 177 ev_key-list; -#X obj 742 199 ev_rel-list; -#X obj 742 221 ev_abs-list; -#X obj 742 243 ev_msc-list; -#X obj 742 265 ev_led-list; -#X obj 742 287 ev_snd-list; -#X obj 742 309 ev_rep-list; -#X obj 742 331 ev_ff-list; -#X obj 742 353 ev_ff_status-list; -#X text 710 85 Event Types:; -#X text 710 136 Event Codes:; -#X obj 51 261 print INPUT_EVENT; -#X obj 51 240 spigot; -#X obj 97 240 tgl 17 0 empty empty console_print 19 9 1 9 -262131 -1 --1 0 1; -#X floatatom 268 384 5 0 0 1 ev_syn - -; -#X obj 241 383 +; -#X msg 241 363 1; +#X text 246 368 outlet message format:; +#X obj 772 104 ev-list; +#X obj 772 155 ev_syn-list; +#X obj 772 177 ev_key-list; +#X obj 772 199 ev_rel-list; +#X obj 772 221 ev_abs-list; +#X obj 772 243 ev_msc-list; +#X obj 772 265 ev_led-list; +#X obj 772 287 ev_snd-list; +#X obj 772 309 ev_rep-list; +#X obj 772 331 ev_ff-list; +#X obj 772 353 ev_ff_status-list; +#X text 740 85 Event Types:; +#X text 740 136 Event Codes:; +#X floatatom 138 388 5 0 0 1 ev_syn - -; +#X obj 111 387 +; +#X msg 111 367 1; #X msg 402 117 close; #X msg 402 96 refresh; #X text 463 94 refresh device list; -#X text 607 531 For more info:; +#X text 537 532 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.20 $$Date: 2006-05-27 00:57:15 $; +#X text 472 589 $Revision: 1.21 $$Date: 2006-05-27 16:41:59 $; #X text 473 602 $Author: eighthave $; -#X msg 428 185 poll 20; -#X msg 366 185 poll 2; -#X text 362 170 start polling and set the poll delay in ms; -#X text 358 42 !!! This software is very much alpha \, so any aspect +#X msg 421 266 poll 20; +#X msg 359 266 poll 2; +#X text 355 251 start polling and set the poll delay in ms; +#X text 462 28 !!! This software is very much alpha \, so any aspect of it could change without notice !!!; -#X obj 72 331 route key rel abs syn; +#X obj 16 336 route key rel abs syn; #X obj 9 547 tgl 25 0 empty empty empty 0 -6 0 8 -195568 -1 -1 0 1 ; #N canvas 278 328 631 544 Event_Codes 0; @@ -202,7 +196,7 @@ of it could change without notice !!!; #X text 138 476 BTN_BASE6; #X text 245 463 298; #X text 245 477 299; -#X restore 744 419 pd Event_Codes; +#X restore 774 419 pd Event_Codes; #N canvas 50 289 469 317 Event_Types 0; #X text 28 48 (For a complete listing of Linux Input Events \, see /usr/include/linux/input.h.); @@ -245,36 +239,35 @@ of it could change without notice !!!; #X text 331 255 22; #X text 230 255 EV_PWR; #X text 61 255 Power Events (for UPS); -#X restore 744 399 pd Event_Types; +#X restore 774 399 pd Event_Types; #N canvas 0 22 450 300 Event_Values 0; #X text 28 48 (For a complete listing of Linux Input Events \, see /usr/include/linux/input.h.); #X obj 11 9 cnv 15 400 30 empty empty Event_Values 20 12 1 14 -261681 -66577 0; -#X restore 744 439 pd Event_Values; +#X restore 774 439 pd Event_Values; #X floatatom 140 484 5 0 0 0 - - -; #X obj 421 439 route abs_hat0x abs_hat0y abs_hat1x abs_hat1y; #X floatatom 421 461 7 0 0 0 - - -; #X msg 179 121 1; #X msg 179 141 0; -#X msg 868 3 pddp; #X msg 402 138 print; -#X obj 247 223 hid 0; +#X obj 304 295 hid 0; #X text 465 118 close the device; #X text 465 139 print the device and element lists; -#X text 10 50 Any non-zero value starts polling \,; -#X text 10 63 0 stops the polling. If the number; -#X text 10 76 is greater than 1 \, then the poll; -#X text 10 89 delay is set to that number.; -#X msg 496 185 poll 2000; +#X text 9 257 Any non-zero value starts polling \,; +#X text 8 270 0 stops the polling. If the number; +#X text 9 283 is greater than 1 \, then the poll; +#X text 9 296 delay is set to that number.; +#X msg 489 266 poll 2000; #X obj 27 464 route rel_x rel_y rel_z rel_wheel; #X floatatom 196 484 5 0 0 0 - - -; -#X obj 455 335 unpack s s f; -#X msg 248 91 open \$1; -#X obj 248 73 hradio 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1 +#X obj 492 366 unpack s s f; +#X msg 203 68 open \$1; +#X obj 203 50 hradio 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1 -1 0; -#X floatatom 235 94 1 0 0 0 - - -; -#X text 387 248 event_type event_code value; +#X floatatom 190 71 1 0 0 0 - - -; +#X text 270 382 event_type event_code value; #X obj 63 419 route abs_x abs_y abs_z abs_rx abs_ry abs_rz abs_throttle ; #X obj 421 477 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 @@ -326,82 +319,88 @@ btn_8 btn_9 btn_10 btn_11 btn_12 btn_13 btn_14 btn_15; 1; #X obj 459 547 tgl 25 0 empty empty empty 0 -6 0 8 -195568 -1 -1 0 1; -#X obj 455 274 cyclone/prepend set; +#X obj 234 334 cyclone/prepend set; #X msg 37 196 debug \$1; #X obj 37 174 hradio 15 1 1 10 empty empty empty 0 -6 0 8 -262144 -1 -1 9; -#X obj 716 530 pddp/pddp_open all_about_hid; -#X msg 261 110 open mouse1; -#X msg 270 133 open mouse; -#X msg 270 157 open keyboard; -#X connect 4 0 54 0; +#X obj 646 531 pddp/pddp_open all_about_hid; +#X obj 232 91 hradio 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1 +-1 0; +#X msg 233 111 open mouse \$1; +#X text 541 208 Gravis/Destroyer Tiltpad; +#X text 535 179 Microsoft 5-button Mouse; +#X msg 395 179 open 0x045e 0x0039; +#X msg 400 207 open 0x047D 0x4008; +#X obj 253 135 hradio 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1 +-1 0; +#X msg 262 155 open keyboard \$1; +#X connect 4 0 49 0; +#X connect 23 0 24 1; +#X connect 24 0 23 0; #X connect 25 0 24 0; -#X connect 25 0 8 0; -#X connect 26 0 25 1; -#X connect 27 0 28 1; -#X connect 28 0 27 0; -#X connect 29 0 28 0; -#X connect 30 0 54 0; -#X connect 31 0 54 0; -#X connect 38 0 54 0; -#X connect 39 0 54 0; -#X connect 42 0 96 0; -#X connect 42 1 62 0; -#X connect 42 2 69 0; -#X connect 42 3 29 0; +#X connect 26 0 49 0; +#X connect 27 0 49 0; +#X connect 34 0 49 0; +#X connect 35 0 49 0; +#X connect 38 0 91 0; +#X connect 38 1 57 0; +#X connect 38 2 64 0; +#X connect 38 3 25 0; +#X connect 44 0 45 0; +#X connect 44 1 66 0; +#X connect 44 2 68 0; +#X connect 44 3 70 0; +#X connect 45 0 65 0; +#X connect 46 0 49 0; +#X connect 47 0 49 0; #X connect 48 0 49 0; -#X connect 48 1 71 0; -#X connect 48 2 73 0; -#X connect 48 3 75 0; -#X connect 49 0 70 0; -#X connect 50 0 54 0; -#X connect 51 0 54 0; -#X connect 53 0 54 0; -#X connect 54 0 25 0; -#X connect 54 0 42 0; -#X connect 54 0 64 0; -#X connect 54 0 99 0; -#X connect 61 0 54 0; -#X connect 62 0 1 0; -#X connect 62 1 2 0; -#X connect 62 2 47 0; -#X connect 62 3 63 0; -#X connect 64 0 7 0; -#X connect 64 1 6 0; -#X connect 64 2 5 0; -#X connect 65 0 54 0; -#X connect 66 0 65 0; +#X connect 49 0 38 0; +#X connect 49 0 59 0; +#X connect 49 0 94 0; +#X connect 56 0 49 0; +#X connect 57 0 1 0; +#X connect 57 1 2 0; +#X connect 57 2 43 0; +#X connect 57 3 58 0; +#X connect 59 0 7 0; +#X connect 59 1 6 0; +#X connect 59 2 5 0; +#X connect 60 0 49 0; +#X connect 61 0 60 0; +#X connect 61 0 62 0; +#X connect 64 0 3 0; +#X connect 64 1 72 0; +#X connect 64 2 73 0; +#X connect 64 3 74 0; +#X connect 64 4 75 0; +#X connect 64 5 76 0; +#X connect 64 6 77 0; +#X connect 64 7 44 0; #X connect 66 0 67 0; -#X connect 69 0 3 0; -#X connect 69 1 77 0; -#X connect 69 2 78 0; -#X connect 69 3 79 0; -#X connect 69 4 80 0; -#X connect 69 5 81 0; -#X connect 69 6 82 0; -#X connect 69 7 48 0; -#X connect 71 0 72 0; -#X connect 73 0 74 0; -#X connect 75 0 76 0; -#X connect 96 0 43 0; -#X connect 96 1 83 0; -#X connect 96 2 84 0; -#X connect 96 3 85 0; -#X connect 96 4 86 0; -#X connect 96 5 87 0; -#X connect 96 6 88 0; -#X connect 96 7 89 0; -#X connect 96 8 90 0; -#X connect 96 9 91 0; -#X connect 96 10 92 0; -#X connect 96 11 93 0; -#X connect 96 12 94 0; -#X connect 96 13 95 0; -#X connect 96 14 97 0; -#X connect 96 15 98 0; -#X connect 99 0 0 0; -#X connect 100 0 54 0; -#X connect 101 0 100 0; -#X connect 103 0 54 0; -#X connect 104 0 54 0; -#X connect 105 0 54 0; +#X connect 68 0 69 0; +#X connect 70 0 71 0; +#X connect 91 0 39 0; +#X connect 91 1 78 0; +#X connect 91 2 79 0; +#X connect 91 3 80 0; +#X connect 91 4 81 0; +#X connect 91 5 82 0; +#X connect 91 6 83 0; +#X connect 91 7 84 0; +#X connect 91 8 85 0; +#X connect 91 9 86 0; +#X connect 91 10 87 0; +#X connect 91 11 88 0; +#X connect 91 12 89 0; +#X connect 91 13 90 0; +#X connect 91 14 92 0; +#X connect 91 15 93 0; +#X connect 94 0 0 0; +#X connect 95 0 49 0; +#X connect 96 0 95 0; +#X connect 98 0 99 0; +#X connect 99 0 49 0; +#X connect 102 0 49 0; +#X connect 103 0 49 0; +#X connect 104 0 105 0; +#X connect 105 0 49 0; diff --git a/hid.c b/hid.c index 4471d3a..b79a84e 100644 --- a/hid.c +++ b/hid.c @@ -46,11 +46,11 @@ static t_class *hid_class; * FUNCTION PROTOTYPES */ -static void hid_poll(t_hid *x, t_float f); -static t_int hid_open(t_hid *x, t_symbol *s, t_int argc, t_atom *argv); -static t_int hid_close(t_hid *x); -static t_int hid_read(t_hid *x,int fd); -static void hid_float(t_hid* x, t_floatarg f); +//static void hid_poll(t_hid *x, t_float f); +static void hid_open(t_hid *x, t_symbol *s, int argc, t_atom *argv); +//static t_int hid_close(t_hid *x); +//static t_int hid_read(t_hid *x,int fd); +//static void hid_float(t_hid* x, t_floatarg f); /*------------------------------------------------------------------------------ @@ -97,6 +97,67 @@ static unsigned int name_to_usage(char *usage_name) return(0); } + +static t_int get_device_number_from_arguments(int argc, t_atom *argv) +{ + t_int device_number = -1; + unsigned short usage_number; + unsigned int usage; + unsigned short vendor_id; + unsigned short product_id; + char usage_string[MAXPDSTRING] = ""; + t_symbol *first_argument; + t_symbol *second_argument; + + if(argc == 1) + { + post("one arg"); + first_argument = atom_getsymbolarg(0,argc,argv); + if(first_argument == &s_) + { // single float arg means device + device_number = (unsigned short) atom_getfloatarg(0,argc,argv); + if(device_number < 0) device_number = -1; + debug_print(LOG_DEBUG,"[hid] setting device# to %d",device_number); + } + else + { // single symbol arg means first instance of usage + debug_print(LOG_DEBUG,"[hid] setting device via usagepage/usage"); + atom_string(argv, usage_string, MAXPDSTRING-1); + usage = name_to_usage(usage_string); + device_number = get_device_number_from_usage_list(0, + usage >> 16, + usage & 0xffff); + debug_print(LOG_INFO,"[hid] using 0x%04x 0x%04x for %s", + usage, usage >> 16, usage & 0xffff, usage_string); + } + } + else if(argc == 2) + { + post("two arg"); + first_argument = atom_getsymbolarg(0,argc,argv); + second_argument = atom_getsymbolarg(1,argc,argv); + if( second_argument == &s_ ) + { /* a symbol then a float means match on usage */ + atom_string(argv, usage_string, MAXPDSTRING-1); + usage = name_to_usage(usage_string); + usage_number = atom_getfloatarg(1,argc,argv); + debug_print(LOG_DEBUG,"[hid] looking for %s at #%d",usage_string,usage_number); + device_number = get_device_number_from_usage_list(usage_number, + usage >> 16, + usage & 0xffff); + } + else + { /* two symbols means idVendor and idProduct in hex */ + post("idVendor and idProduct"); + vendor_id = (unsigned short) strtol(first_argument->s_name, NULL, 16); + product_id = (unsigned short) strtol(second_argument->s_name, NULL, 16); + device_number = get_device_number_by_id(vendor_id,product_id); + } + } + return(device_number); +} + + void hid_output_event(t_hid *x, char *type, char *code, t_float value) { t_atom event_data[3]; @@ -109,7 +170,7 @@ void hid_output_event(t_hid *x, char *type, char *code, t_float value) } /* stop polling the device */ -void stop_poll(t_hid* x) +static void stop_poll(t_hid* x) { debug_print(LOG_DEBUG,"stop_poll"); @@ -121,7 +182,31 @@ void stop_poll(t_hid* x) } } -void hid_set_from_float(t_hid *x, t_floatarg f) +/*------------------------------------------------------------------------------ + * METHODS FOR [hid]'s MESSAGES + */ + + +void hid_poll(t_hid* x, t_float f) +{ + debug_print(LOG_DEBUG,"hid_poll"); + +/* if the user sets the delay less than one, ignore */ + if( f > 0 ) + x->x_delay = (t_int)f; + + if( (!x->x_device_open) && (x->x_device_number > -1) ) + hid_open(x,gensym("open"),0,NULL); + + if(!x->x_started) + { + clock_delay(x->x_clock, x->x_delay); + debug_print(LOG_DEBUG,"[hid] polling started"); + x->x_started = 1; + } +} + +static 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] */ @@ -141,11 +226,6 @@ void hid_set_from_float(t_hid *x, t_floatarg f) } } -/*------------------------------------------------------------------------------ - * METHODS FOR [hid]'s MESSAGES - */ - - /* close the device */ t_int hid_close(t_hid *x) { @@ -173,86 +253,34 @@ t_int hid_close(t_hid *x) * closed / different device open * open / different device close open */ - -t_int hid_open(t_hid *x, t_symbol *s, t_int argc, t_atom *argv) +static void hid_open(t_hid *x, t_symbol *s, int argc, t_atom *argv) { - debug_print(LOG_DEBUG,"hid_open"); - unsigned short i; - unsigned short device_number = 0; - unsigned short usage_number; - unsigned int usage; - char usage_string[MAXPDSTRING] = ""; - - if(argc == 1) - { - if(atom_getsymbolarg(0,argc,argv) == &s_) - { // single float arg means device - debug_print(LOG_DEBUG,"[hid] setting device# to %d",device_number); - device_number = (unsigned short) atom_getfloatarg(0,argc,argv); - } - else - { // single symbol arg means usagepage/usage - debug_print(LOG_DEBUG,"[hid] setting device via usagepage/usage"); - atom_string(argv, usage_string, MAXPDSTRING-1); - i = strlen(usage_string); - do { - --i; - } while(isdigit(usage_string[i])); - usage_number = strtol(usage_string + i + 1,NULL,10); - usage_string[i+1] = '\0'; - debug_print(LOG_DEBUG,"[hid] looking for %s #%d",usage_string,usage_number); - usage = name_to_usage(usage_string); - debug_print(LOG_DEBUG,"[hid] usage 0x%08x 0x%04x 0x%04x",usage, usage >> 16, usage & 0xffff); - device_number = get_device_number_from_usage_list(usage_number, - usage >> 16, usage & 0xffff); - } - } - else if( (argc == 2) && (atom_getsymbolarg(0,argc,argv) != NULL) - && (atom_getsymbolarg(1,argc,argv) != NULL) ) - { /* two symbols means idVendor and idProduct in hex */ - } - + debug_print(LOG_DEBUG,"hid_%s",s->s_name); /* store running state to be restored after the device has been opened */ t_int started = x->x_started; - -/* only close the device if its different than the current and open */ - if( (device_number != x->x_device_number) && (x->x_device_open) ) - hid_close(x); - - if(device_number > 0) - x->x_device_number = device_number; - else - x->x_device_number = 0; - -/* if device is open still, that means the same device is trying to be opened, - * therefore ignore the redundant open request. To reopen the same device, - * send a [close( msg, then an [open( msg. */ - if(! x->x_device_open) + + int device_number = get_device_number_from_arguments(argc, argv); + if(device_number > -1) { - if(hid_open_device(x,x->x_device_number)) - { - error("[hid] can not open device %d",x->x_device_number); - return (1); - } - else + if( (device_number != x->x_device_number) && (x->x_device_open) ) + hid_close(x); + if(! x->x_device_open) { - x->x_device_open = 1; + if(hid_open_device(x,device_number)) + error("[hid] can not open device %d",device_number); + 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 */ if(started) hid_set_from_float(x,x->x_delay); - debug_print(LOG_DEBUG,"[hid] done device# to %d",device_number); - - return (0); } -t_int hid_read(t_hid *x,int fd) +t_int hid_read(t_hid *x, int fd) { // debug_print(LOG_DEBUG,"hid_read"); @@ -267,30 +295,12 @@ t_int hid_read(t_hid *x,int fd) return 1; } -void hid_poll(t_hid* x, t_float f) -{ - debug_print(LOG_DEBUG,"hid_poll"); - -/* if the user sets the delay less than one, ignore */ - if( f > 0 ) - x->x_delay = (t_int)f; - - if(!x->x_device_open) - hid_open(x,gensym("open"),0,NULL); - - if(!x->x_started) - { - clock_delay(x->x_clock, x->x_delay); - debug_print(LOG_DEBUG,"[hid] polling started"); - x->x_started = 1; - } -} - +/* eventually, this will be used to open devices by long name static void hid_anything(t_hid *x, t_symbol *s, t_int argc, t_atom *argv) { int i; t_symbol *my_symbol; - char device_name[MAXPDSTRING]; + //char device_name[MAXPDSTRING]; startpost("ANYTHING! selector: %s data:"); for(i=0; is_name); /* only display the version when the first instance is loaded */ if(!hid_instance_count) @@ -365,12 +375,7 @@ static void *hid_new(t_float f) x->x_data_outlet = outlet_new(&x->x_obj, 0); x->x_device_name_outlet = outlet_new(&x->x_obj, 0); - x->x_device_number = 0; - - if(f > 0) - x->x_device_number = f; - else - x->x_device_number = 0; + x->x_device_number = get_device_number_from_arguments(argc, argv); hid_instance_count++; @@ -385,17 +390,18 @@ void hid_setup(void) (t_method)hid_free, sizeof(t_hid), CLASS_DEFAULT, - A_DEFFLOAT,0); + A_GIMME,0); /* add inlet datatype methods */ class_addfloat(hid_class,(t_method) hid_float); class_addbang(hid_class,(t_method) hid_read); - class_addanything(hid_class,(t_method) hid_anything); +/* class_addanything(hid_class,(t_method) hid_anything); */ /* add inlet message methods */ class_addmethod(hid_class,(t_method) hid_debug,gensym("debug"),A_DEFFLOAT,0); class_addmethod(hid_class,(t_method) hid_build_device_list,gensym("refresh"),0); class_addmethod(hid_class,(t_method) hid_print,gensym("print"),0); + class_addmethod(hid_class,(t_method) hid_info,gensym("info"),0); class_addmethod(hid_class,(t_method) hid_open,gensym("open"),A_GIMME,0); class_addmethod(hid_class,(t_method) hid_close,gensym("close"),0); class_addmethod(hid_class,(t_method) hid_poll,gensym("poll"),A_DEFFLOAT,0); diff --git a/hid.h b/hid.h index a246e5b..7abddd4 100644 --- a/hid.h +++ b/hid.h @@ -15,7 +15,7 @@ #define HID_MAJOR_VERSION 0 #define HID_MINOR_VERSION 7 -/* static char *version = "$Revision: 1.20 $"; */ +/* static char *version = "$Revision: 1.21 $"; */ /*------------------------------------------------------------------------------ * CLASS DEF @@ -24,8 +24,7 @@ typedef struct _hid { t_object x_obj; t_int x_fd; -// unsigned short x_device_number; - t_float x_device_number; + t_int x_device_number; unsigned short vendor_id; // USB idVendor for current device unsigned short product_id; // USB idProduct for current device t_int x_has_ff; @@ -74,9 +73,10 @@ t_int hid_open_device(t_hid *x, t_int device_number); t_int hid_close_device(t_hid *x); void hid_build_device_list(void); t_int hid_get_events(t_hid *x); -void hid_print(t_hid* x); +void hid_info(t_hid* x); /* output device info on the status outlet */ +void hid_print(t_hid* x); /* print info to the console */ void hid_platform_specific_free(t_hid *x); -t_int get_device_number_by_ids(unsigned short vendor_id, unsigned short product_id); +t_int get_device_number_by_id(unsigned short vendor_id, unsigned short product_id); t_int get_device_number_from_usage_list(t_int device_number, unsigned short usage_page, unsigned short usage); diff --git a/hid_darwin.c b/hid_darwin.c index f4cbd4d..254dff5 100644 --- a/hid_darwin.c +++ b/hid_darwin.c @@ -144,17 +144,17 @@ void convertDarwinElementToLinuxTypeCode(pRecElement element, char *linux_type, case kHIDPage_LEDs: /* temporary kludge until I feel like writing the translation table */ sprintf(linux_type, "led"); - sprintf(linux_code, "led_%ld", element->usage - 1); + sprintf(linux_code, "led_%ld", element->usage); break; case kHIDPage_PID: /* temporary kludge until I feel like writing the translation table */ sprintf(linux_type, "ff"); - sprintf(linux_code, "ff_%ld", element->usage - 1); + sprintf(linux_code, "ff_%ld", element->usage); break; default: /* temporary kludge until I feel like writing the translation table */ sprintf(linux_type, "not_implemented"); - sprintf(linux_code, "notimp_%ld", element->usage - 1); + sprintf(linux_code, "notimp_%ld", element->usage); } } @@ -164,13 +164,14 @@ void convertDarwinElementToLinuxTypeCode(pRecElement element, char *linux_type, * hatswitch type with each direction represented by a unique number. This * function converts the unique number to the Linux style axes. */ + +/* + * hmm, not sure how to implement this cleanly yet, so I left the code + * inline in hid_get_events(). void hid_convert_hatswitch_values(IOHIDEventStruct event, char *linux_type, char *linux_code) { - /* - * hmm, not sure how to implement this cleanly yet, so I left the code - * inline in hid_get_events(). - */ } +*/ /* ============================================================================== */ /* DARWIN-SPECIFIC SUPPORT FUNCTIONS */ @@ -202,9 +203,10 @@ pRecDevice hid_get_device_by_number(t_int device_number) return pCurrentHIDDevice; } -t_int get_device_number_by_ids(unsigned short vendor_id, unsigned short product_id) +t_int get_device_number_by_id(unsigned short vendor_id, unsigned short product_id) { - return(1); + // TODO: implement! (check usbhid.c) + return(-1); } t_int get_device_number_from_usage_list(t_int device_number, @@ -220,6 +222,9 @@ t_int get_device_number_from_usage_list(t_int device_number, if( !HIDHaveDeviceList() ) hid_build_device_list(); + /* TODO: check that this function doesn't return a number that is higher + * than the highest device of this type */ + pCurrentHIDDevice = HIDGetFirstDevice(); while(pCurrentHIDDevice != NULL) { @@ -232,15 +237,9 @@ t_int get_device_number_from_usage_list(t_int device_number, } i = total_devices; device_count = HIDCountDevices(); - debug_print(LOG_DEBUG,"[hid] %d is less than %d",i,device_number); pCurrentHIDDevice = HIDGetFirstDevice(); while( (pCurrentHIDDevice != NULL) && (i > device_number) ) { - debug_print(LOG_DEBUG,"[hid] %d: %d == %d %d == %d",i, - pCurrentHIDDevice->usagePage, - usage_page, - pCurrentHIDDevice->usage, - usage); device_count--; if( (pCurrentHIDDevice->usagePage == usage_page) && (pCurrentHIDDevice->usage == usage) ) @@ -249,19 +248,26 @@ t_int get_device_number_from_usage_list(t_int device_number, HIDGetUsageName(pCurrentHIDDevice->usagePage, pCurrentHIDDevice->usage, cstrDeviceName); - debug_print(LOG_DEBUG,"[hid]: found a %s at %d: %s %s",cstrDeviceName,i, - pCurrentHIDDevice->manufacturer,pCurrentHIDDevice->product); + debug_print(LOG_DEBUG,"[hid]: found a %s at %d: %s %s" + ,cstrDeviceName, + i, + pCurrentHIDDevice->manufacturer, + pCurrentHIDDevice->product); } pCurrentHIDDevice = HIDGetNextDevice(pCurrentHIDDevice); - } - return(device_count); + } + if(device_count < total_devices) + return(device_count); + else + return(-1); } - +/* void hid_build_element_list(t_hid *x) { } +*/ t_int hid_print_element_list(t_hid *x) { @@ -379,6 +385,19 @@ void hid_print_device_list(t_hid *x) post(""); } } +/* ============================================================================== + * STATUS/INFO OUTPUT + * ============================================================================== */ + +void hid_info(t_hid *x) +{ + t_atom output_atoms[4]; + + SETSYMBOL(output_atoms,gensym("open")); + SETFLOAT(output_atoms + 1, x->x_device_open); + outlet_anything( x->x_device_name_outlet, gensym( device_name ),0,NULL ); +} + void hid_output_device_name(t_hid *x, char *manufacturer, char *product) { @@ -697,23 +716,27 @@ t_int hid_open_device(t_hid *x, t_int device_number) if( !HIDHaveDeviceList() ) hid_build_device_list(); pCurrentHIDDevice = hid_get_device_by_number(device_number); - if( ! HIDIsValidDevice(pCurrentHIDDevice) ) + if( HIDIsValidDevice(pCurrentHIDDevice) ) { - error("[hid]: device %d is not a valid device\n",device_number); + x->x_device_number = device_number; + } + else + { + debug_error(x,"[hid]: device %d is not a valid device\n",device_number); return(1); } - + hid_output_device_name( x, pCurrentHIDDevice->manufacturer, pCurrentHIDDevice->product ); post("[hid] opened device %d: %s %s", device_number, pCurrentHIDDevice->manufacturer, pCurrentHIDDevice->product); - hid_build_element_list(x); + //hid_build_element_list(x); hidDevice = AllocateHIDObjectFromRecDevice( pCurrentHIDDevice ); if( FFIsForceFeedback(hidDevice) == FF_OK ) { - post("\tdevice has Force Feedback support"); + debug_print(LOG_WARNING,"\tdevice has Force Feedback support"); if( FFCreateDevice(hidDevice,&ffDeviceReference) == FF_OK ) { x->x_has_ff = 1; -- cgit v1.2.1