diff options
Diffstat (limited to 'hidio.c')
-rw-r--r-- | hidio.c | 252 |
1 files changed, 134 insertions, 118 deletions
@@ -2,7 +2,7 @@ /* */ /* interface to native HID (Human Interface Devices) API */ /* Written by Hans-Christoph Steiner <hans@at.or.at> */ -/* Max/MSP port by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Max/MSP port by Olaf Matthes <olaf.matthes@gmx.de> */ /* */ /* Copyright (c) 2004-2006 Hans-Christoph Steiner */ /* */ @@ -23,19 +23,19 @@ /* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* */ /* --------------------------------------------------------------------------*/ -
-#ifdef _WINDOWS
-/* any Windows specific includes go in here */
-#ifdef PD
-#include <windows.h>
-#endif /* PD */
+ +#ifdef _WIN32 +/* any Windows specific includes go in here */ +#ifdef PD +#include <windows.h> +#endif /* PD */ #else #include <unistd.h> -#include <ctype.h>
-#endif -#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
+#include <ctype.h> +#endif /* _WIN32 */ +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> #include "hidio.h" @@ -72,6 +72,13 @@ unsigned short element_count[MAX_DEVICES]; /* pre-generated symbols */ t_symbol *ps_open, *ps_device, *ps_poll, *ps_total, *ps_range; +t_symbol *ps_absolute, *ps_button, *ps_key, *ps_led, *ps_pid, *ps_relative; +t_symbol *absolute_symbols[ABSOLUTE_ARRAY_MAX]; +t_symbol *button_symbols[BUTTON_ARRAY_MAX]; +t_symbol *key_symbols[KEY_ARRAY_MAX]; +t_symbol *led_symbols[LED_ARRAY_MAX]; +t_symbol *pid_symbols[PID_ARRAY_MAX]; +t_symbol *relative_symbols[RELATIVE_ARRAY_MAX]; /*------------------------------------------------------------------------------ * FUNCTION PROTOTYPES @@ -91,14 +98,14 @@ static void hidio_open(t_hidio *x, t_symbol *s, int argc, t_atom *argv); void debug_print(t_int message_debug_level, const char *fmt, ...) { if(message_debug_level <= global_debug_level) - {
+ { char buf[MAXPDSTRING]; va_list ap; //t_int arg[8]; va_start(ap, fmt); vsnprintf(buf, MAXPDSTRING-1, fmt, ap); post(buf); - va_end(ap);
+ va_end(ap); } } @@ -125,7 +132,7 @@ static void output_status(t_hidio *x, t_symbol *selector, t_float output_value) SETFLOAT(output_atom, output_value); #else atom_setlong(output_atom, output_value); -#endif +#endif /* PD */ outlet_anything( x->x_status_outlet, selector, 1, output_atom); freebytes(output_atom,sizeof(t_atom)); } @@ -167,7 +174,7 @@ static void output_element_ranges(t_hidio *x) #else atom_setlong(output_data + 2, element[x->x_device_number][i]->min); atom_setlong(output_data + 3, element[x->x_device_number][i]->max); -#endif +#endif /* PD */ outlet_anything(x->x_status_outlet, ps_range, 4, output_data); } } @@ -197,7 +204,7 @@ static short get_device_number_from_arguments(int argc, t_atom *argv) long device_number = -1; char *device_type_string; long device_type_instance; -#endif +#endif /* PD */ unsigned int usage; unsigned short vendor_id; unsigned short product_id; @@ -212,14 +219,14 @@ static short get_device_number_from_arguments(int argc, t_atom *argv) #else atom_arg_getsym(&first_argument, 0,argc,argv); if(first_argument == _sym_nothing) -#endif +#endif /* PD */ { // single float arg means device # post("first_argument == &s_"); #ifdef PD device_number = (short) atom_getfloatarg(0,argc,argv); #else atom_arg_getlong(&device_number, 0, argc, argv); -#endif +#endif /* PD */ if(device_number < 0) device_number = -1; debug_print(LOG_DEBUG,"[hidio] setting device# to %d",device_number); } @@ -230,7 +237,7 @@ static short get_device_number_from_arguments(int argc, t_atom *argv) #else device_type_string = atom_string(argv); // LATER do we have to free this string manually??? -#endif +#endif /* PD */ usage = name_to_usage(device_type_string); device_number = get_device_number_from_usage(0, usage >> 16, usage & 0xffff); @@ -248,7 +255,7 @@ static short get_device_number_from_arguments(int argc, t_atom *argv) atom_arg_getsym(&first_argument, 0,argc,argv); atom_arg_getsym(&second_argument, 1,argc,argv); if( second_argument == _sym_nothing ) -#endif +#endif /* PD */ { /* a symbol then a float means match on usage */ #ifdef PD atom_string(argv, device_type_string, MAXPDSTRING-1); @@ -258,7 +265,7 @@ static short get_device_number_from_arguments(int argc, t_atom *argv) device_type_string = atom_string(argv); usage = name_to_usage(device_type_string); atom_arg_getlong(&device_type_instance, 1, argc, argv); -#endif +#endif /* PD */ debug_print(LOG_DEBUG,"[hidio] looking for %s at #%d", device_type_string, device_type_instance); device_number = get_device_number_from_usage(device_type_instance, @@ -280,8 +287,8 @@ static short get_device_number_from_arguments(int argc, t_atom *argv) void hidio_output_event(t_hidio *x, t_hid_element *output_data) { - if( (output_data->value != output_data->previous_value) || - (output_data->relative) ) // relative data should always be output + if( (output_data->relative) || // relative data should always be output + (output_data->value != output_data->previous_value) ) { t_atom event_data[3]; SETSYMBOL(event_data, output_data->name); @@ -389,11 +396,11 @@ t_int hidio_close(t_hidio *x) * closed / same device open * open / same device no action * closed / different device open - * open / different device close open + * open / different device close, open */ static void hidio_open(t_hidio *x, t_symbol *s, int argc, t_atom *argv) { - short device_number;
+ short device_number; debug_print(LOG_DEBUG,"hid_%s",s->s_name); pthread_mutex_lock(&x->x_mutex); @@ -417,8 +424,11 @@ t_int hidio_child_read(t_hidio *x) #ifdef PD double right_now = clock_getlogicaltime(); #else +/* TODO: this should use gettime() not systime_ms(). This needs to be logical + * time, not system time because the idea is that only one instance should get + * events from the OS in each slice of logical time <hans@at.or.at> */ double right_now = (double)systime_ms(); -#endif +#endif /* PD */ t_hid_element *current_element; if(right_now > last_execute_time[x->x_device_number]) @@ -481,13 +491,13 @@ static void hidio_int(t_hidio* x, long l) hidio_set_from_float(x, (float)l); } -#endif +#endif /* NOT PD */ static void hidio_debug(t_hidio *x, t_float f) { - pthread_mutex_lock(&x->x_mutex);
+ pthread_mutex_lock(&x->x_mutex); global_debug_level = f; - pthread_mutex_unlock(&x->x_mutex);
+ pthread_mutex_unlock(&x->x_mutex); } @@ -497,7 +507,7 @@ static void hidio_debug(t_hidio *x, t_float f) static void *hidio_child(void *zz) { - t_hidio *x = zz;
+ t_hidio *x = zz; short device_number = -1; pthread_mutex_lock(&x->x_mutex); @@ -513,19 +523,19 @@ static void *hidio_child(void *zz) short new_device_number = x->x_device_number; /* store running state to be restored after the device has been opened */ t_int started = x->x_started; - int ret;
- /* check whether we have to close previous device */
- if (x->x_device_open && device_number != x->x_device_number)
- {
- pthread_mutex_unlock(&x->x_mutex);
- stop_poll(x);
- ret = hidio_close_device(x);
- pthread_mutex_lock(&x->x_mutex);
- x->x_device_open = 0;
- device_number = -1;
- }
- /* no device open, so open one now */
- if (!x->x_device_open)
+ int ret; + /* check whether we have to close previous device */ + if (x->x_device_open && device_number != x->x_device_number) + { + pthread_mutex_unlock(&x->x_mutex); + stop_poll(x); + ret = hidio_close_device(x); + pthread_mutex_lock(&x->x_mutex); + x->x_device_open = 0; + device_number = -1; + } + /* no device open, so open one now */ + if (!x->x_device_open) { pthread_mutex_unlock(&x->x_mutex); ret = hidio_open_device(x, new_device_number); @@ -537,7 +547,7 @@ static void *hidio_child(void *zz) } else { - x->x_device_open = 1;
+ x->x_device_open = 1; device_number = x->x_device_number; /* keep local copy */ pthread_mutex_unlock(&x->x_mutex); /* restore the polling state so that when I [tgl] is used to start/stop [hidio], @@ -548,7 +558,7 @@ static void *hidio_child(void *zz) output_open_status(x); output_device_number(x); pthread_mutex_lock(&x->x_mutex); - }
+ } } if (x->x_requestcode == REQUEST_OPEN) x->x_requestcode = REQUEST_NOTHING; @@ -618,45 +628,45 @@ static void *hidio_child(void *zz) return (0); } -/* change priority of child thread */
-#ifdef PD
-static void hidio_priority(t_hidio *x, t_floatarg p)
-#else
-static void hidio_priority(t_hidio *x, long p)
-#endif
-{
- pthread_mutex_lock(&x->x_mutex);
- p = 2 * (CLIP(p, 0, 10) - 5);
- if (x->x_thread)
- {
- struct sched_param parm;
- int policy;
- if (pthread_getschedparam(x->x_thread, &policy, &parm) < 0)
- {
- post("hidio: warning: failed to get thread priority");
- }
- else
- {
- parm.sched_priority = x->x_priority + (int)p; /* adjust priority */
-
- if (parm.sched_priority < sched_get_priority_min(policy))
- {
- parm.sched_priority = sched_get_priority_min(policy);
- }
- else if (parm.sched_priority > sched_get_priority_max(policy))
- {
- parm.sched_priority = sched_get_priority_max(policy);
- }
-
- if (pthread_setschedparam(x->x_thread, policy, &parm) < 0)
- {
- post("hidio: warning: failed to change thread priority to %d", parm.sched_priority);
- }
- }
- }
- pthread_mutex_unlock(&x->x_mutex);
-}
-
+/* change priority of child thread */ +#ifdef PD +static void hidio_priority(t_hidio *x, t_floatarg p) +#else +static void hidio_priority(t_hidio *x, long p) +#endif +{ + pthread_mutex_lock(&x->x_mutex); + p = 2 * (CLIP(p, 0, 10) - 5); + if (x->x_thread) + { + struct sched_param parm; + int policy; + if (pthread_getschedparam(x->x_thread, &policy, &parm) < 0) + { + post("hidio: warning: failed to get thread priority"); + } + else + { + parm.sched_priority = x->x_priority + (int)p; /* adjust priority */ + + if (parm.sched_priority < sched_get_priority_min(policy)) + { + parm.sched_priority = sched_get_priority_min(policy); + } + else if (parm.sched_priority > sched_get_priority_max(policy)) + { + parm.sched_priority = sched_get_priority_max(policy); + } + + if (pthread_setschedparam(x->x_thread, policy, &parm) < 0) + { + post("hidio: warning: failed to change thread priority to %d", parm.sched_priority); + } + } + } + pthread_mutex_unlock(&x->x_mutex); +} + /*------------------------------------------------------------------------------ * system functions @@ -699,12 +709,12 @@ static void hidio_free(t_hidio* x) pthread_cond_destroy(&x->x_requestcondition); pthread_cond_destroy(&x->x_answercondition); pthread_mutex_destroy(&x->x_mutex); -}
+} /* create a new instance of this class */ static void *hidio_new(t_symbol *s, int argc, t_atom *argv) { - unsigned int i;
+ unsigned int i; #ifdef PD t_hidio *x = (t_hidio *)pd_new(hidio_class); @@ -721,19 +731,19 @@ static void *hidio_new(t_symbol *s, int argc, t_atom *argv) /* create anything outlet used for HID data */ x->x_status_outlet = outlet_new(x, "anything"); x->x_data_outlet = outlet_new(x, "anything"); -#endif +#endif /* PD */ + + /* init vars */ + global_debug_level = 9; /* high numbers here means see more messages */ + x->x_has_ff = 0; + x->x_device_open = 0; + x->x_started = 0; + x->x_delay = DEFAULT_DELAY; + for(i=0; i<MAX_DEVICES; ++i) last_execute_time[i] = 0; +#ifdef _WIN32 + x->x_fd = INVALID_HANDLE_VALUE; +#endif /* _WIN32 */ - /* init vars */
- global_debug_level = 9; /* high numbers here means see more messages */
- x->x_has_ff = 0;
- x->x_device_open = 0;
- x->x_started = 0;
- x->x_delay = DEFAULT_DELAY;
- for(i=0; i<MAX_DEVICES; ++i) last_execute_time[i] = 0;
-#ifdef _WINDOWS
- x->x_fd = INVALID_HANDLE_VALUE;
-#endif
-
pthread_mutex_init(&x->x_mutex, 0); pthread_cond_init(&x->x_requestcondition, 0); pthread_cond_init(&x->x_answercondition, 0); @@ -744,8 +754,8 @@ static void *hidio_new(t_symbol *s, int argc, t_atom *argv) hidio_instance_count++; x->x_requestcode = REQUEST_NOTHING; - pthread_create(&x->x_thread, 0, hidio_child, x);
-
+ pthread_create(&x->x_thread, 0, hidio_child, x); + return (x); } @@ -767,6 +777,7 @@ void hidio_setup(void) /* add inlet message methods */ class_addmethod(hidio_class,(t_method) hidio_debug,gensym("debug"),A_DEFFLOAT,0); class_addmethod(hidio_class,(t_method) hidio_build_device_list,gensym("refresh"),0); +/* TODO: [print( should be dumped for [devices( and [elements( messages */ class_addmethod(hidio_class,(t_method) hidio_print,gensym("print"),0); class_addmethod(hidio_class,(t_method) hidio_info,gensym("info"),0); class_addmethod(hidio_class,(t_method) hidio_open,gensym("open"),A_GIMME,0); @@ -783,9 +794,9 @@ void hidio_setup(void) class_addmethod(hidio_class,(t_method) hidio_ff_stopall,gensym("ff_stopall"),0); /* ff tests */ class_addmethod(hidio_class,(t_method) hidio_ff_fftest,gensym("fftest"),A_DEFFLOAT,0); - class_addmethod(hidio_class,(t_method) hidio_ff_print,gensym("ff_print"),0);
-
- class_addmethod(hidio_class,(t_method) hidio_priority, gensym("priority"), A_FLOAT, A_NULL);
+ class_addmethod(hidio_class,(t_method) hidio_ff_print,gensym("ff_print"),0); + + class_addmethod(hidio_class,(t_method) hidio_priority, gensym("priority"), A_FLOAT, A_NULL); post("[hidio] %d.%d, written by Hans-Christoph Steiner <hans@eds.org>", @@ -799,6 +810,8 @@ void hidio_setup(void) ps_total = gensym("total"); ps_range = gensym("range"); + generate_type_symbols(); + generate_event_symbols(); } #else /* Max */ static void hidio_notify(t_hidio *x, t_symbol *s, t_symbol *msg, void *sender, void *data) @@ -814,15 +827,15 @@ static void hidio_assist(t_hidio *x, void *b, long m, long a, char *s) { if (m == 2) { - switch (a)
- {
- case 0:
- sprintf(s, "(list) Received Events");
- break;
- case 1:
- sprintf(s, "(list) Status Info");
- break;
- }
+ switch (a) + { + case 0: + sprintf(s, "(list) Received Events"); + break; + case 1: + sprintf(s, "(list) Status Info"); + break; + } } else { @@ -859,6 +872,7 @@ int main() /* add inlet message methods */ class_addmethod(c, (method)hidio_debug, "debug",A_DEFFLOAT,0); class_addmethod(c, (method)hidio_build_device_list, "refresh",0); +/* TODO: [print( should be dumped for [devices( and [elements( messages */ class_addmethod(c, (method)hidio_print, "print",0); class_addmethod(c, (method)hidio_info, "info",0); class_addmethod(c, (method)hidio_open, "open",A_GIMME,0); @@ -875,8 +889,8 @@ int main() /* ff tests */ class_addmethod(c, (method)hidio_ff_fftest, "fftest",A_DEFFLOAT,0); class_addmethod(c, (method)hidio_ff_print, "ff_print",0); - /* perfomrance / system stuff */
- class_addmethod(c, (method)hidio_priority, "priority", A_LONG,0);
+ /* perfomrance / system stuff */ + class_addmethod(c, (method)hidio_priority, "priority", A_LONG,0); class_addmethod(c, (method)hidio_assist, "assist", A_CANT, 0); @@ -891,9 +905,9 @@ int main() hidio_class = c; finder_addclass("Devices", "hidio"); - post("hidio %d.%d: © 2006 by Hans-Christoph Steiner & Olaf Matthes",
+ post("hidio %d.%d: © 2006 by Hans-Christoph Steiner & Olaf Matthes", HIDIO_MAJOR_VERSION, HIDIO_MINOR_VERSION); - post("hidio: compiled on "__DATE__" at "__TIME__ " ");
+ post("hidio: compiled on "__DATE__" at "__TIME__ " "); /* pre-generate often used symbols */ ps_open = gensym("open"); @@ -902,7 +916,9 @@ int main() ps_total = gensym("total"); ps_range = gensym("range"); + generate_event_symbols(); + return 0; } -#endif +#endif /* PD */ |