aboutsummaryrefslogtreecommitdiff
path: root/hidio.c
diff options
context:
space:
mode:
authorHans-Christoph Steiner <eighthave@users.sourceforge.net>2006-12-08 06:33:26 +0000
committerHans-Christoph Steiner <eighthave@users.sourceforge.net>2006-12-08 06:33:26 +0000
commit732d359c182794df20e78b4e00db4c5bf123dfec (patch)
tree34e8012dff92877d5edd7bbe73c57587496fa4c6 /hidio.c
parent33ed52de6e66c8767044454b1cf26de1e1b569a7 (diff)
- laid out new event labeling scheme based more on USB HID rather than Linux
input.h. It works on my devices on my Mac OS X. I probably broke Linux support. The scheme is in a new file, hidio_types.c - all event symbols except the vendor-defined usage are generated in hidio_setup(). The symbols for vendor-defined usages are generated when the device's element list is built. - changed macros to work cleanly when compiled on Windows using MinGW gcc - fixed up help file to better represent the state of things (still could be much better) svn path=/trunk/externals/io/hidio/; revision=6718
Diffstat (limited to 'hidio.c')
-rw-r--r--hidio.c252
1 files changed, 134 insertions, 118 deletions
diff --git a/hidio.c b/hidio.c
index 3a93938..9ec25fb 100644
--- a/hidio.c
+++ b/hidio.c
@@ -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 */