From e6087aad22076ca3f2066020bd4271bb0991d370 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Sun, 28 May 2006 20:13:58 +0000 Subject: On Mac OSX, replaced hid_get_device_by_number() by a global array of pointers, it should reduce the CPU load noticably. next I need to handle elements independently svn path=/trunk/externals/hcs/hid/; revision=5147 --- TODO | 56 +++++++++++++++++++++++++++++++--------- doc/hid-help.pd | 31 +++++++++++++++++----- hid.h | 23 +++++++++++------ hid_darwin.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 154 insertions(+), 36 deletions(-) diff --git a/TODO b/TODO index a6d899c..66a26dd 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,29 @@ ============================================================================== -= make second inlet for poll # (for [human->pd] += output one value per poll + +- for relative axes, sum up all events and output one +http://lists.apple.com/archives/mac-games-dev/2005/Oct/msg00060.html + +- for absolute axes, just output latest value. if they are not in the queue, + I can check them manually + +- buttons, output everything + +- is this at all necessary? How often do multiple events happen in one poll period? + + +============================================================================== += iterate through elements and do a proper queue of the ones we want: + +- also, label multiple instances of the same usage + +http://mud.5341.com/msg/8455.html + + +============================================================================== += make second inlet for poll # (for [human->pd]) ============================================================================== @@ -18,6 +40,17 @@ i.e "Trackpad" a la Max's [hi] +============================================================================== += += autoscaling based on Logical min/max + +- this is probably essential for input, the question is how to find out what + the data range is easily. + +- output would be handy, rather than autoscale, to save on CPU + + + ============================================================================== = test verbose names @@ -42,6 +75,12 @@ i.e "Trackpad" a la Max's [hi] - change word "code" to "element" +============================================================================== += event name changes + +- make key/button Type "button" rather than "key" (undecided on this one) + + ============================================================================== = hid/serial @@ -61,10 +100,6 @@ i.e "Trackpad" a la Max's [hi] data, as they are intended. -============================================================================== -= open/close status outlet - - ============================================================================== = profile [hid] object and usage @@ -72,6 +107,7 @@ i.e "Trackpad" a la Max's [hi] - find out if [autoscale] takes a lot of CPU power, or where in [hid] is using CPU where it doesn't have to be + ============================================================================== = Report available FF effects @@ -97,16 +133,12 @@ i.e "Trackpad" a la Max's [hi] - most functions probably do not need return values -============================================================================== -= event name changes - -- make key/button Type "button" rather than "key" (undecided on this one) - - ============================================================================== = check out using USB timestamp -- use the USB timestamp to correctly space the output data +- use the USB timestamp to correctly space the output data (meh, probably + unnecessary) + /++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\ diff --git a/doc/hid-help.pd b/doc/hid-help.pd index 541ea8e..41b97c2 100644 --- a/doc/hid-help.pd +++ b/doc/hid-help.pd @@ -1,10 +1,10 @@ -#N canvas 54 47 924 649 10; -#X msg 233 353 not_implemented notimp_64 -255; +#N canvas 242 96 932 657 10; +#X msg 233 353 abs abs_y 55; #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 obj 129 122 tgl 35 0 empty empty empty 0 -6 0 8 -24198 -1 -1 25 +25; #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 - -; @@ -34,7 +34,7 @@ #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.22 $$Date: 2006-05-27 23:12:51 $; +#X text 472 589 $Revision: 1.23 $$Date: 2006-05-28 20:13:58 $; #X text 473 602 $Author: eighthave $; #X msg 421 266 poll 20; #X msg 359 266 poll 2; @@ -265,7 +265,7 @@ of it could change without notice !!!; #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; +-1 2; #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 @@ -387,9 +387,23 @@ vendorID productID; #X connect 0 7 4 0; #X connect 2 0 0 0; #X connect 2 0 3 0; -#X restore 494 323 pd see device info; +#X restore 512 290 pd see device info; #X msg 397 179 open 0x046d 0xc01d; #X text 535 179 Logitech USB-PS/2 Optical Mouse; +#N canvas 0 22 458 308 test 1; +#X obj 60 23 inlet; +#X obj 61 53 route not_implemented; +#X obj 65 100 route notimp_64; +#X obj 165 138 print; +#X floatatom 69 146 5 0 0 0 - - -; +#X connect 0 0 1 0; +#X connect 1 0 2 0; +#X connect 2 0 4 0; +#X connect 2 1 3 0; +#X restore 490 330 pd test; +#X obj 36 63 hradio 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1 +-1 0; +#X msg 45 83 open joystick \$1; #X connect 4 0 49 0; #X connect 23 0 24 1; #X connect 24 0 23 0; @@ -413,6 +427,7 @@ vendorID productID; #X connect 49 0 38 0; #X connect 49 0 59 0; #X connect 49 0 94 0; +#X connect 49 0 108 0; #X connect 49 1 105 0; #X connect 56 0 49 0; #X connect 57 0 1 0; @@ -462,3 +477,5 @@ vendorID productID; #X connect 103 0 49 0; #X connect 104 0 49 0; #X connect 106 0 49 0; +#X connect 109 0 110 0; +#X connect 110 0 49 0; diff --git a/hid.h b/hid.h index 7c74d46..b4db8bb 100644 --- a/hid.h +++ b/hid.h @@ -15,7 +15,16 @@ #define HID_MAJOR_VERSION 0 #define HID_MINOR_VERSION 7 -/* static char *version = "$Revision: 1.22 $"; */ +/* static char *version = "$Revision: 1.23 $"; */ + +/*------------------------------------------------------------------------------ + * GLOBAL DEFINES + */ + +#define DEFAULT_DELAY 5 + +/* this is set to simplify data structures (arrays instead of linked lists) */ +#define MAX_DEVICES 128 /*------------------------------------------------------------------------------ * CLASS DEF @@ -25,8 +34,8 @@ typedef struct _hid 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 +// unsigned short vendor_id; // USB idVendor for current device +// unsigned short product_id; // USB idProduct for current device t_int x_has_ff; void *x_ff_device; t_clock *x_clock; @@ -38,11 +47,6 @@ typedef struct _hid } t_hid; -/*------------------------------------------------------------------------------ - * GLOBAL DEFINES - */ - -#define DEFAULT_DELAY 5 /*------------------------------------------------------------------------------ @@ -57,6 +61,9 @@ t_int hid_instance_count; extern unsigned short global_debug_level; +/* next I need to make a data structure to hold the data to be output for this + * poll. This should probably be an array for efficiency */ + /*------------------------------------------------------------------------------ * FUNCTION PROTOTYPES FOR DIFFERENT PLATFORMS */ diff --git a/hid_darwin.c b/hid_darwin.c index 07076b3..66fe4f1 100644 --- a/hid_darwin.c +++ b/hid_darwin.c @@ -62,8 +62,11 @@ extern t_int hid_instance_count; +/* store device pointers */ +pRecDevice device_pointer[MAX_DEVICES]; + /*============================================================================== -h * FUNCTION PROTOTYPES + * FUNCTION PROTOTYPES *============================================================================== */ @@ -182,6 +185,8 @@ pRecDevice hid_get_device_by_number(t_int device_number) pRecDevice pCurrentHIDDevice; t_int i, numdevs; +// TODO: implement this using the global array built by hid_build_device_list() + /* * If the specified device is greater than the total number of devices, return * an error. @@ -289,7 +294,39 @@ t_int get_device_number_from_usage_list(t_int device_number, /* void hid_build_element_list(t_hid *x) { - + if ( HIDIsValidDevice( device ) ) { + elRec = HIDGetFirstDeviceElement( js_devices[id].device, +kHIDElementTypeInput ); + if ( elRec ) { + switch (elRec->usagePage) { + case kHIDPage_GenericDesktop: + switch ( elRec->usage ) { + case kHIDUsage_GD_X: + x_axis = elRec; + break; + case kHIDUsage_GD_Y: + y_axis = elRec; + break; + case kHIDUsage_GD_GamePad: + pad = elRec; + break; + //etc + } + } + //if the right element was not found, continue looping through the + //rest of the elements by calling HIDGetNextDeviceElement() until you + //find the right one or it returns NULL + } + + // only queue buttons and relative axes + if ( HIDIsValidElement( devicePtr, elementPtr ) ) { + HIDQueueElement (devicePtr, elementPtr); + } + + // for absolute axes, poll them + if ( HIDIsValidElement( devicePtr, elementPtr ) ) { + value = HIDGetElementValue(devicePtr, elementPtr); + } } */ @@ -306,7 +343,8 @@ t_int hid_print_element_list(t_hid *x) char type_name[256]; char usage_name[256]; - pCurrentHIDDevice = hid_get_device_by_number(x->x_device_number); +// pCurrentHIDDevice = hid_get_device_by_number(x->x_device_number); + pCurrentHIDDevice = device_pointer[x->x_device_number]; if ( ! HIDIsValidDevice(pCurrentHIDDevice) ) { error("[hid]: device %d is not a valid device\n",x->x_device_number); @@ -387,7 +425,8 @@ void hid_print_device_list(t_hid *x) /* display device list in console */ for(i=0; i < numdevs; i++) { - pCurrentHIDDevice = hid_get_device_by_number(i); +// pCurrentHIDDevice = hid_get_device_by_number(i); + pCurrentHIDDevice = device_pointer[i]; debug_print(LOG_INFO,"Device %d: '%s' '%s' version %d", i, pCurrentHIDDevice->manufacturer, @@ -423,7 +462,8 @@ void hid_platform_specific_info(t_hid *x) if(x->x_device_number > -1) { - pCurrentHIDDevice = hid_get_device_by_number(x->x_device_number); +// pCurrentHIDDevice = hid_get_device_by_number(x->x_device_number); + pCurrentHIDDevice = device_pointer[x->x_device_number]; if(pCurrentHIDDevice != NULL) { /* product */ @@ -619,7 +659,8 @@ t_int hid_get_events(t_hid *x) int event_counter = 0; // Boolean result; - pCurrentHIDDevice = hid_get_device_by_number(x->x_device_number); +// pCurrentHIDDevice = hid_get_device_by_number(x->x_device_number); + pCurrentHIDDevice = device_pointer[x->x_device_number]; if(!pCurrentHIDDevice) { @@ -767,7 +808,8 @@ t_int hid_open_device(t_hid *x, t_int device_number) /* rebuild device list to make sure the list is current */ if( !HIDHaveDeviceList() ) hid_build_device_list(); - pCurrentHIDDevice = hid_get_device_by_number(device_number); +// pCurrentHIDDevice = hid_get_device_by_number(device_number); + pCurrentHIDDevice = device_pointer[device_number]; if( HIDIsValidDevice(pCurrentHIDDevice) ) { x->x_device_number = device_number; @@ -802,7 +844,10 @@ t_int hid_open_device(t_hid *x, t_int device_number) HIDQueueDevice(pCurrentHIDDevice); // TODO: queue all elements except absolute axes, those can just be polled - +/* if ( HIDIsValidElement( devicePtr, elementPtr ) ) { + value = HIDGetElementValue(devicePtr, elementPtr); + } +*/ return(result); } @@ -812,7 +857,8 @@ t_int hid_close_device(t_hid *x) debug_print(LOG_DEBUG,"hid_close_device"); t_int result = 0; - pRecDevice pCurrentHIDDevice = hid_get_device_by_number(x->x_device_number); +// pRecDevice pCurrentHIDDevice = hid_get_device_by_number(x->x_device_number); + pRecDevice pCurrentHIDDevice = device_pointer[x->x_device_number]; HIDDequeueDevice(pCurrentHIDDevice); // this doesn't seem to be needed at all, but why not use it? @@ -824,11 +870,27 @@ t_int hid_close_device(t_hid *x) void hid_build_device_list(void) { + int device_number = 0; + pRecDevice pCurrentHIDDevice; + debug_print(LOG_DEBUG,"hid_build_device_list"); debug_print(LOG_WARNING,"[hid] Building device list..."); if(HIDBuildDeviceList (0, 0)) post("[hid]: no HID devices found\n"); + +/* The most recently discovered HID is the first element of the list here. I + * want the oldest to be number 0 rather than the newest. */ + device_number = (int) HIDCountDevices(); + pCurrentHIDDevice = HIDGetFirstDevice(); + while(pCurrentHIDDevice != NULL) + { + --device_number; + if(device_number < MAX_DEVICES) + device_pointer[device_number] = pCurrentHIDDevice; + pCurrentHIDDevice = HIDGetNextDevice(pCurrentHIDDevice); + } + debug_print(LOG_WARNING,"[hid] completed device list."); } -- cgit v1.2.1