aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hidio.c191
-rw-r--r--hidio.h13
2 files changed, 135 insertions, 69 deletions
diff --git a/hidio.c b/hidio.c
index 8562b0c..3a93938 100644
--- a/hidio.c
+++ b/hidio.c
@@ -26,6 +26,9 @@
#ifdef _WINDOWS
/* any Windows specific includes go in here */
+#ifdef PD
+#include <windows.h>
+#endif /* PD */
#else
#include <unistd.h>
#include <ctype.h>
@@ -395,16 +398,11 @@ static void hidio_open(t_hidio *x, t_symbol *s, int argc, t_atom *argv)
pthread_mutex_lock(&x->x_mutex);
device_number = get_device_number_from_arguments(argc, argv);
- if(device_number > -1)
+ if (device_number > -1)
{
- if( (device_number != x->x_device_number) && (x->x_device_open) )
- hidio_close(x); /* LATER move this also to child thread */
- if(! x->x_device_open)
- {
- x->x_device_number = device_number;
- x->x_requestcode = REQUEST_OPEN;
- pthread_cond_signal(&x->x_requestcondition);
- }
+ x->x_device_number = device_number;
+ x->x_requestcode = REQUEST_OPEN;
+ pthread_cond_signal(&x->x_requestcondition);
}
else debug_print(LOG_WARNING,"[hidio] device does not exist");
pthread_mutex_unlock(&x->x_mutex);
@@ -487,7 +485,9 @@ static void hidio_int(t_hidio* x, long l)
static void hidio_debug(t_hidio *x, t_float f)
{
+ pthread_mutex_lock(&x->x_mutex);
global_debug_level = f;
+ pthread_mutex_unlock(&x->x_mutex);
}
@@ -497,7 +497,8 @@ 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);
while (1)
@@ -509,30 +510,45 @@ static void *hidio_child(void *zz)
}
else if (x->x_requestcode == REQUEST_OPEN)
{
- short device_number = x->x_device_number;
+ 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 err;
- pthread_mutex_unlock(&x->x_mutex);
- err = hidio_open_device(x, device_number);
- pthread_mutex_lock(&x->x_mutex);
- if (err)
+ 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)
{
- x->x_device_number = -1;
- error("[hidio] can not open device %d",device_number);
- }
- else
- {
- x->x_device_open = 1;
pthread_mutex_unlock(&x->x_mutex);
- /* restore the polling state so that when I [tgl] is used to start/stop [hidio],
- * the [tgl]'s state will continue to accurately reflect [hidio]'s state */
- if (started)
- hidio_set_from_float(x,x->x_delay);
- debug_print(LOG_DEBUG,"[hidio] set device# to %d",device_number);
- output_open_status(x);
- output_device_number(x);
+ ret = hidio_open_device(x, new_device_number);
pthread_mutex_lock(&x->x_mutex);
+ if (ret)
+ {
+ x->x_device_number = -1;
+ error("[hidio] can not open device %d",device_number);
+ }
+ else
+ {
+ 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],
+ * the [tgl]'s state will continue to accurately reflect [hidio]'s state */
+ if (started)
+ hidio_set_from_float(x,x->x_delay);
+ debug_print(LOG_DEBUG,"[hidio] set device# to %d",device_number);
+ 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;
@@ -602,7 +618,46 @@ 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);
+}
+
+
/*------------------------------------------------------------------------------
* system functions
*/
@@ -644,46 +699,23 @@ 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;
#ifdef PD
t_hidio *x = (t_hidio *)pd_new(hidio_class);
- unsigned int i;
-#if !defined(__linux__) && !defined(__APPLE__)
- error(" !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!");
- error(" This is a dummy, since this object only works GNU/Linux and MacOS X!");
- error(" !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!");
-#endif
-
- /* 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;
+ x->x_clock = clock_new(x, (t_method)hidio_tick);
- x->x_clock = clock_new(x, (t_method)hidio_tick);
-
- /* create anything outlet used for HID data */
- x->x_data_outlet = outlet_new(&x->x_obj, 0);
- x->x_status_outlet = outlet_new(&x->x_obj, 0);
+ /* create anything outlet used for HID data */
+ x->x_data_outlet = outlet_new(&x->x_obj, 0);
+ x->x_status_outlet = outlet_new(&x->x_obj, 0);
#else /* Max */
t_hidio *x = (t_hidio *)object_alloc(hidio_class);
- unsigned int i;
- /* 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;
-
x->x_clock = clock_new(x, (method)hidio_tick);
/* create anything outlet used for HID data */
@@ -691,6 +723,17 @@ static void *hidio_new(t_symbol *s, int argc, t_atom *argv)
x->x_data_outlet = outlet_new(x, "anything");
#endif
+ /* 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);
@@ -701,8 +744,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);
}
@@ -729,7 +772,7 @@ void hidio_setup(void)
class_addmethod(hidio_class,(t_method) hidio_open,gensym("open"),A_GIMME,0);
class_addmethod(hidio_class,(t_method) hidio_close,gensym("close"),0);
class_addmethod(hidio_class,(t_method) hidio_poll,gensym("poll"),A_DEFFLOAT,0);
- /* force feedback messages */
+ /* force feedback messages */
class_addmethod(hidio_class,(t_method) hidio_ff_autocenter,
gensym("ff_autocenter"),A_DEFFLOAT,0);
class_addmethod(hidio_class,(t_method) hidio_ff_gain,gensym("ff_gain"),A_DEFFLOAT,0);
@@ -740,7 +783,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_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>",
@@ -769,17 +814,25 @@ static void hidio_assist(t_hidio *x, void *b, long m, long a, char *s)
{
if (m == 2)
{
- sprintf(s, "hidio outlet");
+ switch (a)
+ {
+ case 0:
+ sprintf(s, "(list) Received Events");
+ break;
+ case 1:
+ sprintf(s, "(list) Status Info");
+ break;
+ }
}
else
{
switch (a)
{
case 0:
- sprintf(s, "inlet 1");
+ sprintf(s, "Control Messages");
break;
case 1:
- sprintf(s, "inlet 2");
+ sprintf(s, "nothing");
break;
}
}
@@ -822,6 +875,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);
class_addmethod(c, (method)hidio_assist, "assist", A_CANT, 0);
@@ -836,7 +891,9 @@ int main()
hidio_class = c;
finder_addclass("Devices", "hidio");
- post("hidio: © 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__ " ");
/* pre-generate often used symbols */
ps_open = gensym("open");
diff --git a/hidio.h b/hidio.h
index 8c15eb4..4bb6f18 100644
--- a/hidio.h
+++ b/hidio.h
@@ -48,7 +48,15 @@ typedef void t_clock;
#define HIDIO_MAJOR_VERSION 0
#define HIDIO_MINOR_VERSION 0
-/* static char *version = "$Revision: 1.7 $"; */
+/* static char *version = "$Revision: 1.8 $"; */
+
+/*------------------------------------------------------------------------------
+ * MACRO DEFINES
+ */
+
+#ifndef CLIP
+#define CLIP(a, lo, hi) ( (a)>(lo)?( (a)<(hi)?(a):(hi) ):(lo) )
+#endif
/*------------------------------------------------------------------------------
* GLOBAL DEFINES
@@ -109,7 +117,8 @@ typedef struct _hidio
pthread_mutex_t x_mutex;
pthread_cond_t x_requestcondition;
pthread_cond_t x_answercondition;
- pthread_t x_thread;
+ pthread_t x_thread;
+ t_int x_priority;
} t_hidio;