Update of /cvsroot/pure-data/externals/hcs/hid In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16784
Modified Files: TODO hid.c hid.h hid_darwin.c Log Message: new open-by methods seem to be working properly
Index: TODO =================================================================== RCS file: /cvsroot/pure-data/externals/hcs/hid/TODO,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** TODO 27 May 2006 00:57:15 -0000 1.21 --- TODO 27 May 2006 16:41:59 -0000 1.22 *************** *** 1,12 ****
! TODO: make open functions:
- device number - vendor_id product_id - Product String
============================================================================== --- 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(
+ ============================================================================== + = open devices by name + + i.e "Trackpad" a la Max's [hi] +
============================================================================== *************** *** 64,75 **** 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 --- 71,74 ---- *************** *** 79,100 ****
============================================================================== - = 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
--- 78,81 ---- *************** *** 116,131 ****
============================================================================== - = 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
--- 97,100 ---- *************** *** 134,183 ****
============================================================================== - = 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
--- 103,106 ---- *************** *** 209,222 ****
______________________________________________________________________________ - - 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. --- 132,135 ----
Index: hid_darwin.c =================================================================== RCS file: /cvsroot/pure-data/externals/hcs/hid/hid_darwin.c,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** hid_darwin.c 27 May 2006 00:57:15 -0000 1.19 --- hid_darwin.c 27 May 2006 16:41:59 -0000 1.20 *************** *** 145,159 **** /* temporary kludge until I feel like writing the translation table */ sprintf(linux_type, "led"); ! sprintf(linux_code, "led_%ld", element->usage - 1); 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); 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); } } --- 145,159 ---- /* temporary kludge until I feel like writing the translation table */ sprintf(linux_type, "led"); ! 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); break; default: /* temporary kludge until I feel like writing the translation table */ sprintf(linux_type, "not_implemented"); ! sprintf(linux_code, "notimp_%ld", element->usage); } } *************** *** 165,175 **** * function converts the unique number to the Linux style axes. */ 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(). - */ }
/* ============================================================================== */ --- 165,176 ---- * 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) { } + */
/* ============================================================================== */ *************** *** 203,209 **** }
! t_int get_device_number_by_ids(unsigned short vendor_id, unsigned short product_id) { ! return(1); }
--- 204,211 ---- }
! t_int get_device_number_by_id(unsigned short vendor_id, unsigned short product_id) { ! // TODO: implement! (check usbhid.c) ! return(-1); }
*************** *** 221,224 **** --- 223,229 ---- 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) *************** *** 233,245 **** 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) && --- 238,244 ---- *************** *** 250,266 **** pCurrentHIDDevice->usage, cstrDeviceName); ! debug_print(LOG_DEBUG,"[hid]: found a %s at %d: %s %s",cstrDeviceName,i, ! pCurrentHIDDevice->manufacturer,pCurrentHIDDevice->product); } pCurrentHIDDevice = HIDGetNextDevice(pCurrentHIDDevice); ! } ! return(device_count); }
! void hid_build_element_list(t_hid *x) { }
t_int hid_print_element_list(t_hid *x) --- 249,272 ---- pCurrentHIDDevice->usage, cstrDeviceName); ! debug_print(LOG_DEBUG,"[hid]: found a %s at %d: %s %s" ! ,cstrDeviceName, ! i, ! pCurrentHIDDevice->manufacturer, ! pCurrentHIDDevice->product); } pCurrentHIDDevice = HIDGetNextDevice(pCurrentHIDDevice); ! } ! 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) *************** *** 380,383 **** --- 386,402 ---- } } + /* ============================================================================== + * 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) *************** *** 698,707 **** pCurrentHIDDevice = hid_get_device_by_number(device_number); ! if( ! HIDIsValidDevice(pCurrentHIDDevice) ) { ! error("[hid]: device %d is not a valid device\n",device_number); return(1); } ! hid_output_device_name( x, pCurrentHIDDevice->manufacturer, pCurrentHIDDevice->product );
--- 717,730 ---- pCurrentHIDDevice = hid_get_device_by_number(device_number); ! if( HIDIsValidDevice(pCurrentHIDDevice) ) { ! 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 );
*************** *** 709,718 **** device_number, pCurrentHIDDevice->manufacturer, pCurrentHIDDevice->product);
! hid_build_element_list(x);
hidDevice = AllocateHIDObjectFromRecDevice( pCurrentHIDDevice ); if( FFIsForceFeedback(hidDevice) == FF_OK ) { ! post("\tdevice has Force Feedback support"); if( FFCreateDevice(hidDevice,&ffDeviceReference) == FF_OK ) { --- 732,741 ---- device_number, pCurrentHIDDevice->manufacturer, pCurrentHIDDevice->product);
! //hid_build_element_list(x);
hidDevice = AllocateHIDObjectFromRecDevice( pCurrentHIDDevice ); if( FFIsForceFeedback(hidDevice) == FF_OK ) { ! debug_print(LOG_WARNING,"\tdevice has Force Feedback support"); if( FFCreateDevice(hidDevice,&ffDeviceReference) == FF_OK ) {
Index: hid.h =================================================================== RCS file: /cvsroot/pure-data/externals/hcs/hid/hid.h,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** hid.h 27 May 2006 00:57:15 -0000 1.20 --- hid.h 27 May 2006 16:41:59 -0000 1.21 *************** *** 25,30 **** t_object x_obj; t_int x_fd; ! // unsigned short x_device_number; ! t_float x_device_number; unsigned short vendor_id; // USB idVendor for current device unsigned short product_id; // USB idProduct for current device --- 25,29 ---- t_object x_obj; t_int x_fd; ! t_int x_device_number; unsigned short vendor_id; // USB idVendor for current device unsigned short product_id; // USB idProduct for current device *************** *** 75,81 **** void hid_build_device_list(void); t_int hid_get_events(t_hid *x); ! void hid_print(t_hid* x); 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_from_usage_list(t_int device_number, unsigned short usage_page, unsigned short usage); --- 74,81 ---- void hid_build_device_list(void); t_int hid_get_events(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_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);
Index: hid.c =================================================================== RCS file: /cvsroot/pure-data/externals/hcs/hid/hid.c,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** hid.c 27 May 2006 00:57:15 -0000 1.22 --- hid.c 27 May 2006 16:41:59 -0000 1.23 *************** *** 47,55 **** */
! 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);
--- 47,55 ---- */
! //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);
*************** *** 98,101 **** --- 98,162 ---- }
+ + 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) { *************** *** 110,114 ****
/* stop polling the device */ ! void stop_poll(t_hid* x) { debug_print(LOG_DEBUG,"stop_poll"); --- 171,175 ----
/* stop polling the device */ ! static void stop_poll(t_hid* x) { debug_print(LOG_DEBUG,"stop_poll"); *************** *** 122,126 **** }
! void hid_set_from_float(t_hid *x, t_floatarg f) { /* values greater than 1 set the polling delay time */ --- 183,211 ---- }
! /*------------------------------------------------------------------------------ ! * 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 */ *************** *** 142,150 **** }
- /*------------------------------------------------------------------------------ - * METHODS FOR [hid]'s MESSAGES - */ - - /* close the device */ t_int hid_close(t_hid *x) --- 227,230 ---- *************** *** 174,257 **** * open / different device close open */ ! ! t_int hid_open(t_hid *x, t_symbol *s, t_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 */ ! } ! /* 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) { ! if(hid_open_device(x,x->x_device_number)) ! { ! error("[hid] can not open device %d",x->x_device_number); ! 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 */ 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) { // debug_print(LOG_DEBUG,"hid_read"); --- 254,285 ---- * open / different device close open */ ! static void hid_open(t_hid *x, t_symbol *s, int argc, t_atom *argv) { ! 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; ! ! int device_number = get_device_number_from_arguments(argc, argv); ! if(device_number > -1) { ! if( (device_number != x->x_device_number) && (x->x_device_open) ) ! hid_close(x); ! if(! x->x_device_open) { ! 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); }
! t_int hid_read(t_hid *x, int fd) { // debug_print(LOG_DEBUG,"hid_read"); *************** *** 268,295 **** }
! 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; ! } ! } ! 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]; startpost("ANYTHING! selector: %s data:"); --- 296,305 ---- }
! /* 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]; startpost("ANYTHING! selector: %s data:"); *************** *** 303,307 **** } } !
static void hid_float(t_hid* x, t_floatarg f) --- 313,317 ---- } } ! */
static void hid_float(t_hid* x, t_floatarg f) *************** *** 333,341 ****
/* create a new instance of this class */ ! static void *hid_new(t_float f) { ! t_hid *x = (t_hid *)pd_new(hid_class);
! debug_print(LOG_DEBUG,"hid_new");
/* only display the version when the first instance is loaded */ --- 343,351 ----
/* create a new instance of this class */ ! static void *hid_new(t_symbol *s, int argc, t_atom *argv) { ! t_hid *x = (t_hid *)pd_new(hid_class);
! debug_print(LOG_DEBUG,"hid_%s",s->s_name);
/* only display the version when the first instance is loaded */ *************** *** 366,375 **** 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;
hid_instance_count++; --- 376,380 ---- x->x_device_name_outlet = outlet_new(&x->x_obj, 0);
! x->x_device_number = get_device_number_from_arguments(argc, argv);
hid_instance_count++; *************** *** 386,395 **** sizeof(t_hid), CLASS_DEFAULT, ! A_DEFFLOAT,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); /* add inlet message methods */ --- 391,400 ---- sizeof(t_hid), CLASS_DEFAULT, ! 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); */ /* add inlet message methods */ *************** *** 397,400 **** --- 402,406 ---- 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);