Update of /cvsroot/pure-data/externals/hcs/hid In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3977
Modified Files: hid.c Added Files: hid-help.pd Log Message: first functional first with new outlet format
--- NEW FILE: hid-help.pd --- #N canvas 282 80 613 460 10; #X msg 340 212 ev_rel rel_x 1 1.09824e+09; #X obj 340 191 prepend set; #X obj 102 357 route rel_x rel_y; #X floatatom 102 377 5 0 0 0 - - -; #X floatatom 159 377 5 0 0 0 - - -; #X obj 180 226 print; #X msg 106 48 start; #X msg 125 67 stop; #X obj 198 155 hid /dev/input/event0; #X floatatom 444 331 12 0 0 1 time - -; #X obj 351 311 unpack s s f f; #X msg 222 52 open /dev/input/event1; #X msg 214 29 open /dev/input/event0; #X msg 238 74 open /dev/input/event2; #X msg 250 95 open /dev/input/event3; #X msg 262 115 open /dev/input/event4; #X obj 43 292 route ev_key ev_rel ev_abs; #X floatatom 161 338 7 0 0 0 - - -; #X floatatom 219 338 7 0 0 0 - - -; #X obj 161 317 route abs_x abs_y; #X obj 44 52 tgl 35 0 empty empty empty 0 -6 0 8 -24198 -1 -1 1 1; #X floatatom 413 348 12 0 0 1 value - -; #X symbolatom 381 365 10 0 0 1 eventcode - -; #X symbolatom 351 384 15 0 0 1 eventtype - -; #X floatatom 43 422 5 0 0 0 - - -; #X floatatom 118 423 5 0 0 0 - - -; #X obj 43 400 route key_f key_leftctrl btn_left; #X floatatom 193 423 5 0 0 0 - - -; #X obj 11 166 bng 35 250 50 0 empty empty event_received 38 18 1 8 -225280 -1 -1; #X obj 2 2 cnv 15 600 20 empty empty "hid" 2 11 1 18 -233017 -66577 0; #X text 312 234 outlet message format:; #X text 336 248 eventtype eventcode value timestamp; #X connect 1 0 0 0; #X connect 2 0 3 0; #X connect 2 1 4 0; #X connect 6 0 8 0; #X connect 7 0 8 0; #X connect 8 0 5 0; #X connect 8 0 1 0; #X connect 8 0 10 0; #X connect 8 0 16 0; #X connect 8 0 28 0; #X connect 10 0 23 0; #X connect 10 1 22 0; #X connect 10 2 21 0; #X connect 10 3 9 0; #X connect 11 0 8 0; #X connect 12 0 8 0; #X connect 13 0 8 0; #X connect 14 0 8 0; #X connect 15 0 8 0; #X connect 16 0 26 0; #X connect 16 1 2 0; #X connect 16 2 19 0; #X connect 19 0 17 0; #X connect 19 1 18 0; #X connect 20 0 8 0; #X connect 26 0 24 0; #X connect 26 1 25 0; #X connect 26 2 27 0;
Index: hid.c =================================================================== RCS file: /cvsroot/pure-data/externals/hcs/hid/hid.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** hid.c 18 Oct 2004 21:10:48 -0000 1.2 --- hid.c 20 Oct 2004 02:06:08 -0000 1.3 *************** *** 47,54 **** #ifndef __APPLE_CC__ #include "Carbon_Include.h" ! #endif
#include <HID_Utilities.h> ! #endif
#include "linuxhid.h" --- 47,54 ---- #ifndef __APPLE_CC__ #include "Carbon_Include.h" ! #endif /* #ifndef __APPLE_CC__ */
#include <HID_Utilities.h> ! #endif /* #ifdef __APPLE__ */
#include "linuxhid.h" *************** *** 62,73 **** static t_class *hid_class;
! typedef struct _hid { t_object x_obj; t_int x_fd; t_symbol *x_devname; t_clock *x_clock; ! int x_read_ok; ! int x_started; ! int x_delay; #ifdef __gnu_linux__ struct input_event x_input_event; --- 62,74 ---- static t_class *hid_class;
! typedef struct _hid ! { t_object x_obj; t_int x_fd; t_symbol *x_devname; t_clock *x_clock; ! t_int x_read_ok; ! t_int x_started; ! t_int x_delay; #ifdef __gnu_linux__ struct input_event x_input_event; *************** *** 75,92 **** IOHIDEventStruct event; #endif ! t_outlet *x_input_event_time_outlet; ! t_outlet *x_input_event_type_outlet; ! t_outlet *x_input_event_code_outlet; ! t_outlet *x_input_event_value_outlet; }t_hid;
/*------------------------------------------------------------------------------ * IMPLEMENTATION */
! void hid_stop(t_hid* x) { DEBUG(post("hid_stop"););
! if (x->x_fd >= 0 && x->x_started) { clock_unset(x->x_clock); post("hid: polling stopped"); --- 76,93 ---- IOHIDEventStruct event; #endif ! t_outlet *x_event_outlet; }t_hid;
+ /*------------------------------------------------------------------------------ * IMPLEMENTATION */
! void hid_stop(t_hid* x) ! { DEBUG(post("hid_stop"););
! if (x->x_fd >= 0 && x->x_started) ! { clock_unset(x->x_clock); post("hid: polling stopped"); *************** *** 95,99 **** }
! static int hid_close(t_hid *x) { DEBUG(post("hid_close"););
--- 96,101 ---- }
! static t_int hid_close(t_hid *x) ! { DEBUG(post("hid_close"););
*************** *** 108,113 **** }
! static int hid_open(t_hid *x, t_symbol *s) { ! int eventType, eventCode, buttons, rel_axes, abs_axes, ff; #ifdef __gnu_linux__ unsigned long bitmask[EV_MAX][NBITS(KEY_MAX)]; --- 110,119 ---- }
! static t_int hid_open(t_hid *x, t_symbol *s) ! { ! t_int eventType, eventCode; ! char *eventTypeName = ""; ! /* counts for various event types */ ! t_int synCount,keyCount,relCount,absCount,mscCount,ledCount,sndCount,repCount,ffCount,pwrCount,ff_statusCount; #ifdef __gnu_linux__ unsigned long bitmask[EV_MAX][NBITS(KEY_MAX)]; *************** *** 126,135 **** #ifdef __gnu_linux__ /* open device */ ! if (x->x_devname) { /* open the device read-only, non-exclusive */ x->x_fd = open (x->x_devname->s_name, O_RDONLY | O_NONBLOCK); /* test if device open */ ! if (x->x_fd < 0 ) { ! post("[hid] open %s failed",x->x_devname->s_name); x->x_fd = -1; return 0; --- 132,143 ---- #ifdef __gnu_linux__ /* open device */ ! if (x->x_devname) ! { /* open the device read-only, non-exclusive */ x->x_fd = open (x->x_devname->s_name, O_RDONLY | O_NONBLOCK); /* test if device open */ ! if (x->x_fd < 0 ) ! { ! error("[hid] open %s failed",x->x_devname->s_name); x->x_fd = -1; return 0; *************** *** 138,142 ****
/* read input_events from the HID_DEVICE stream ! * It seems that is just there to flush the event input buffer? */ while (read (x->x_fd, &(x->x_input_event), sizeof(struct input_event)) > -1); --- 146,150 ----
/* read input_events from the HID_DEVICE stream ! * It seems that is just there to flush the input event queue */ while (read (x->x_fd, &(x->x_input_event), sizeof(struct input_event)) > -1); *************** *** 144,241 **** /* get name of device */ ioctl(x->x_fd, EVIOCGNAME(sizeof(devicename)), devicename); ! post ("Configuring %s on %s",devicename,x->x_devname->s_name);
! /* get bitmask representing supported events (axes, buttons, etc.) */ memset(bitmask, 0, sizeof(bitmask)); ioctl(x->x_fd, EVIOCGBIT(0, EV_MAX), bitmask[0]); post("\nSupported events:");
! rel_axes = 0; ! abs_axes = 0; ! buttons = 0; ! ff = 0;
/* cycle through all possible event types */ for (eventType = 0; eventType < EV_MAX; eventType++) { ! if (test_bit(eventType, bitmask[0])) ! { ! post(" %s (type %d) ", ev[eventType] ? ev[eventType] : "?", eventType); ! // post("Event type %d",eventType); ! /* get bitmask representing supported button types */ ! ioctl(x->x_fd, EVIOCGBIT(eventType, KEY_MAX), bitmask[eventType]); ! /* cycle through all possible event codes (axes, keys, etc.) ! * testing to see which are supported ! */ ! for (eventCode = 0; eventCode < KEY_MAX; eventCode++) ! if (test_bit(eventCode, bitmask[eventType])) ! { ! post(" Event code %s (%d)", event_names[eventType] ? (event_names[eventType][eventCode] ? event_names[eventType][eventCode] : "?") : "?", eventCode); /* post(" Event code %d (%s)", eventCode, names[eventType] ? (names[eventType][eventCode] ? names[eventType][eventCode] : "?") : "?"); */ ! switch(eventType) { ! // the API changed at some point... #ifdef EV_RST ! case EV_RST: ! break; #else ! case EV_SYN: ! break; #endif ! case EV_KEY: ! buttons++; ! break; ! case EV_REL: ! rel_axes++; ! break; ! case EV_ABS: ! abs_axes++; ! break; ! case EV_MSC: ! break; ! case EV_LED: ! break; ! case EV_SND: ! break; ! case EV_REP: ! break; ! case EV_FF: ! ff++; ! break; ! } ! } ! } }
! post ("\nUsing %d relative axes, %d absolute axes, and %d buttons.", rel_axes, abs_axes, buttons); ! if (ff > 0) post ("Detected %d force feedback types",ff); ! post ("\nWARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING"); ! post ("This object is under development! The interface could change at anytime!"); ! post ("As I write cross-platform versions, the interface might have to change."); ! post ("WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING\n"); ! #endif
return 1; }
! static int hid_read(t_hid *x,int fd) { ! if (x->x_fd < 0) return 0;
#ifdef __gnu_linux__ ! while (read (x->x_fd, &(x->x_input_event), sizeof(struct input_event)) > -1) { ! outlet_float (x->x_input_event_value_outlet, (int)x->x_input_event.value); ! outlet_symbol (x->x_input_event_code_outlet, gensym(event_names[x->x_input_event.type][x->x_input_event.code])); ! outlet_symbol (x->x_input_event_type_outlet, gensym(ev[x->x_input_event.type])); ! /* input_event.time is a timeval struct from <sys/time.h> */ ! /* outlet_float (x->x_input_event_time_outlet, x->x_input_event.time); */ } ! #endif #ifdef __APPLE__ pRecDevice pCurrentHIDDevice = GetSetCurrentDevice (gWindow); ! pRecElement pCurrentHIDElement = GetSetCurrentElement (gWindow); ! // if we have a good device and element which is not a collecion if (pCurrentHIDDevice && pCurrentHIDElement && (pCurrentHIDElement->type != kIOHIDElementTypeCollection)) --- 152,273 ---- /* get name of device */ ioctl(x->x_fd, EVIOCGNAME(sizeof(devicename)), devicename); ! post ("\nConfiguring %s on %s",devicename,x->x_devname->s_name);
! /* get bitmask representing supported events (axes, keys, etc.) */ memset(bitmask, 0, sizeof(bitmask)); ioctl(x->x_fd, EVIOCGBIT(0, EV_MAX), bitmask[0]); post("\nSupported events:");
! /* init all count vars */ ! synCount=keyCount=relCount=absCount=mscCount=ledCount=0; ! sndCount=repCount=ffCount=pwrCount=ff_statusCount=0;
/* cycle through all possible event types */ for (eventType = 0; eventType < EV_MAX; eventType++) { ! if (test_bit(eventType, bitmask[0])) ! { ! /* make pretty names for event types */ ! switch(eventType) ! { ! case EV_SYN: eventTypeName = "Synchronization"; break; ! case EV_KEY: eventTypeName = "Keys/Buttons"; break; ! case EV_REL: eventTypeName = "Relative Axes"; break; ! case EV_ABS: eventTypeName = "Absolute Axes"; break; ! case EV_MSC: eventTypeName = "Miscellaneous"; break; ! case EV_LED: eventTypeName = "LEDs"; break; ! case EV_SND: eventTypeName = "System Sounds"; break; ! case EV_REP: eventTypeName = "Autorepeat Values"; break; ! case EV_FF: eventTypeName = "Force Feedback"; break; ! case EV_PWR: eventTypeName = "Power"; break; ! case EV_FF_STATUS: eventTypeName = "Force Feedback Status"; break; ! } ! post(" %s (%s/type %d) ", eventTypeName, ev[eventType] ? ev[eventType] : "?", eventType); ! /* get bitmask representing supported button types */ ! ioctl(x->x_fd, EVIOCGBIT(eventType, KEY_MAX), bitmask[eventType]); ! /* cycle through all possible event codes (axes, keys, etc.) ! * testing to see which are supported ! */ ! for (eventCode = 0; eventCode < KEY_MAX; eventCode++) ! { ! if (test_bit(eventCode, bitmask[eventType])) ! { ! post(" %s (%d)", event_names[eventType] ? (event_names[eventType][eventCode] ? event_names[eventType][eventCode] : "?") : "?", eventCode); /* post(" Event code %d (%s)", eventCode, names[eventType] ? (names[eventType][eventCode] ? names[eventType][eventCode] : "?") : "?"); */ ! switch(eventType) { ! /* ! * the API changed at some point... EV_SYN seems to be the new name ! * from "Reset" events to "Syncronization" events ! */ #ifdef EV_RST ! case EV_RST: synCount++; break; #else ! case EV_SYN: synCount++; break; #endif ! case EV_KEY: keyCount++; break; ! case EV_REL: relCount++; break; ! case EV_ABS: absCount++; break; ! case EV_MSC: mscCount++; break; ! case EV_LED: ledCount++; break; ! case EV_SND: sndCount++; break; ! case EV_REP: repCount++; break; ! case EV_FF: ffCount++; break; ! case EV_PWR: pwrCount++; break; ! case EV_FF_STATUS: ff_statusCount++; break; ! } ! } ! } ! } }
! post("\nDetected:"); ! if (synCount > 0) post (" %d Sync types",synCount); ! if (keyCount > 0) post (" %d Key/Button types",keyCount); ! if (relCount > 0) post (" %d Relative Axis types",relCount); ! if (absCount > 0) post (" %d Absolute Axis types",absCount); ! if (mscCount > 0) post (" %d Misc types",mscCount); ! if (ledCount > 0) post (" %d LED types",ledCount); ! if (sndCount > 0) post (" %d System Sound types",sndCount); ! if (repCount > 0) post (" %d Key Repeat types",repCount); ! if (ffCount > 0) post (" %d Force Feedback types",ffCount); ! if (pwrCount > 0) post (" %d Power types",pwrCount); ! if (ff_statusCount > 0) post (" %d Force Feedback types",ff_statusCount); ! ! post("\nWARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING"); ! post("This object is under development! The interface could change at anytime!"); ! post("As I write cross-platform versions, the interface might have to change."); ! post("WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING"); ! post("================================= [hid] =================================\n"); ! #endif /* #ifdef __gnu_linux__ */
return 1; }
! static t_int hid_read(t_hid *x,int fd) { ! t_atom event_data[5]; ! char *eventType; ! char *eventCode;
#ifdef __gnu_linux__ ! if (x->x_fd < 0) return 0; ! ! while (read (x->x_fd, &(x->x_input_event), sizeof(struct input_event)) > -1) ! { ! /* build event_data list from event data */ ! SETSYMBOL(event_data, gensym(ev[x->x_input_event.type])); ! SETSYMBOL(event_data + 1, gensym(event_names[x->x_input_event.type][x->x_input_event.code])); ! SETFLOAT(event_data + 2, (t_float)x->x_input_event.value); ! SETFLOAT(event_data + 3, (t_float)(x->x_input_event.time).tv_sec); ! outlet_anything(x->x_obj.te_outlet,atom_gensym(event_data),3,event_data+1); } ! #endif /* #ifdef__gnu_linux__ */ #ifdef __APPLE__ pRecDevice pCurrentHIDDevice = GetSetCurrentDevice (gWindow); ! pRecElement pCurrentHIDElement = GetSetCurrenstElement (gWindow); ! r/l // if we have a good device and element which is not a collecion if (pCurrentHIDDevice && pCurrentHIDElement && (pCurrentHIDElement->type != kIOHIDElementTypeCollection)) *************** *** 245,250 **** SInt32 valueScale = HIDScaleValue (valueCal, pCurrentHIDElement); } ! #endif ! if (x->x_started) { --- 277,282 ---- SInt32 valueScale = HIDScaleValue (valueCal, pCurrentHIDElement); } ! #endif /* #ifdef __APPLE__ */ ! if (x->x_started) { *************** *** 256,310 ****
/* Actions */ ! static void hid_float(t_hid* x) { ! DEBUG(post("hid_float");) ! ! } ! ! void hid_delay(t_hid* x, t_float f) { DEBUG(post("hid_DELAY %f",f);) /* if the user sets the delay less than zero, reset to default */ ! if ( f > 0 ) { ! x->x_delay = (int)f; ! } else { x->x_delay = DEFAULT_DELAY; } }
! void hid_start(t_hid* x) { DEBUG(post("hid_start"););
! if (x->x_fd >= 0 && !x->x_started) { clock_delay(x->x_clock, DEFAULT_DELAY); post("hid: polling started"); x->x_started = 1; ! } else { ! post("You need to set a input device (i.e /dev/input/event0)"); } }
! /* setup functions */ ! static void hid_free(t_hid* x) { ! DEBUG(post("hid_free");) ! ! if (x->x_fd < 0) return;
! hid_stop(x); ! clock_free(x->x_clock); ! close (x->x_fd); }
! static void *hid_new(t_symbol *s) { ! int i; t_hid *x = (t_hid *)pd_new(hid_class);
! DEBUG(post("hid_new");)
post("[hid] %s, written by Hans-Christoph Steiner hans@eds.org",version); #ifndef __linux__ ! post(" !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!"); ! post(" This is a dummy, since this object only works with a Linux kernel!"); ! post(" !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!"); ! #endif
/* init vars */ --- 288,358 ----
/* Actions */ ! void hid_delay(t_hid* x, t_float f) ! { DEBUG(post("hid_DELAY %f",f);) /* if the user sets the delay less than zero, reset to default */ ! if ( f > 0 ) ! { ! x->x_delay = (t_int)f; ! } ! else ! { x->x_delay = DEFAULT_DELAY; } }
! void hid_start(t_hid* x) ! { DEBUG(post("hid_start"););
! if (x->x_fd >= 0 && !x->x_started) ! { clock_delay(x->x_clock, DEFAULT_DELAY); post("hid: polling started"); x->x_started = 1; ! } ! else ! { ! error("You need to set a input device (i.e /dev/input/event0)"); } }
! static void hid_float(t_hid* x, t_floatarg f) ! { ! DEBUG(post("hid_float");); ! ! if(f == 1) ! hid_start(x); ! else if(f == 0) ! hid_stop(x); ! }
! /* setup functions */ ! static void hid_free(t_hid* x) ! { ! DEBUG(post("hid_free");); ! ! if (x->x_fd < 0) return; ! ! hid_stop(x); ! clock_free(x->x_clock); ! close (x->x_fd); }
! static void *hid_new(t_symbol *s) ! { ! t_int i; t_hid *x = (t_hid *)pd_new(hid_class);
! DEBUG(post("hid_new"););
+ post("================================= [hid] ================================="); post("[hid] %s, written by Hans-Christoph Steiner hans@eds.org",version); #ifndef __linux__ ! error(" !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!"); ! error(" This is a dummy, since this object only works with a Linux kernel!"); ! error(" !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!"); ! #endif /* __linux__ */
/* init vars */ *************** *** 316,325 ****
x->x_clock = clock_new(x, (t_method)hid_read); ! ! /* create outlets for each axis */ ! x->x_input_event_time_outlet = outlet_new(&x->x_obj, &s_float); ! x->x_input_event_type_outlet = outlet_new(&x->x_obj, &s_float); ! x->x_input_event_code_outlet = outlet_new(&x->x_obj, &s_float); ! x->x_input_event_value_outlet = outlet_new(&x->x_obj, &s_float);
/* set to the value from the object argument, if that exists */ --- 364,370 ----
x->x_clock = clock_new(x, (t_method)hid_read); ! ! /* create anything outlet */ ! outlet_new(&x->x_obj, 0);
/* set to the value from the object argument, if that exists */ *************** *** 334,356 **** }
! void hid_setup(void) { ! DEBUG(post("hid_setup");) ! hid_class = class_new(gensym("hid"), ! (t_newmethod)hid_new, ! (t_method)hid_free, ! sizeof(t_hid),0,A_DEFSYM,0); ! ! /* add inlet datatype methods */ ! class_addfloat(hid_class,(t_method) hid_float); ! class_addbang(hid_class,(t_method) hid_read); ! ! /* add inlet message methods */ ! class_addmethod(hid_class,(t_method) hid_delay,gensym("delay"),A_DEFFLOAT,0); ! class_addmethod(hid_class,(t_method) hid_open,gensym("open"),A_DEFSYM,0); ! class_addmethod(hid_class,(t_method) hid_close,gensym("close"),0); ! class_addmethod(hid_class,(t_method) hid_start,gensym("start"),0); ! class_addmethod(hid_class,(t_method) hid_start,gensym("poll"),0); ! class_addmethod(hid_class,(t_method) hid_stop,gensym("stop"),0); ! class_addmethod(hid_class,(t_method) hid_stop,gensym("nopoll"),0); }
--- 379,404 ---- }
! void hid_setup(void) ! { ! DEBUG(post("hid_setup");); ! hid_class = class_new(gensym("hid"), ! (t_newmethod)hid_new, ! (t_method)hid_free, ! sizeof(t_hid), ! CLASS_DEFAULT, ! A_DEFSYM,0); ! ! /* add inlet datatype methods */ ! class_addfloat(hid_class,(t_method) hid_float); ! class_addbang(hid_class,(t_method) hid_read); ! ! /* add inlet message methods */ ! class_addmethod(hid_class,(t_method) hid_delay,gensym("delay"),A_DEFFLOAT,0); ! class_addmethod(hid_class,(t_method) hid_open,gensym("open"),A_DEFSYM,0); ! class_addmethod(hid_class,(t_method) hid_close,gensym("close"),0); ! class_addmethod(hid_class,(t_method) hid_start,gensym("start"),0); ! class_addmethod(hid_class,(t_method) hid_start,gensym("poll"),0); ! class_addmethod(hid_class,(t_method) hid_stop,gensym("stop"),0); ! class_addmethod(hid_class,(t_method) hid_stop,gensym("nopoll"),0); }