aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hidio.c890
-rw-r--r--hidio_darwin.c26
-rw-r--r--hidio_linux.c24
3 files changed, 495 insertions, 445 deletions
diff --git a/hidio.c b/hidio.c
index fc8ed65..97b4158 100644
--- a/hidio.c
+++ b/hidio.c
@@ -95,193 +95,202 @@ static void hidio_open(t_hidio *x, t_symbol *s, int argc, t_atom *argv);
void debug_post(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);
-
- }
+ 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);
+
+ }
}
void debug_error(t_hidio *x, 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);
- pd_error(x, buf);
- va_end(ap);
- }
+ 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);
+ pd_error(x, buf);
+ va_end(ap);
+ }
}
static void output_status(t_hidio *x, t_symbol *selector, t_float output_value)
{
- t_atom *output_atom = (t_atom *)getbytes(sizeof(t_atom));
+ t_atom *output_atom = (t_atom *)getbytes(sizeof(t_atom));
#ifdef PD
- SETFLOAT(output_atom, output_value);
+ SETFLOAT(output_atom, output_value);
#else /* Max */
- atom_setlong(output_atom, (long)output_value);
+ atom_setlong(output_atom, (long)output_value);
#endif /* PD */
- outlet_anything( x->x_status_outlet, selector, 1, output_atom);
- freebytes(output_atom,sizeof(t_atom));
+ outlet_anything( x->x_status_outlet, selector, 1, output_atom);
+ freebytes(output_atom,sizeof(t_atom));
}
static void output_open_status(t_hidio *x)
{
- output_status(x, ps_open, x->x_device_open);
+ output_status(x, ps_open, x->x_device_open);
}
static void output_device_number(t_hidio *x)
{
- output_status(x, ps_device, x->x_device_number);
+ output_status(x, ps_device, x->x_device_number);
}
static void output_poll_time(t_hidio *x)
{
- output_status(x, ps_poll, x->x_delay);
+ output_status(x, ps_poll, x->x_delay);
}
static void output_device_count(t_hidio *x)
{
- output_status(x, ps_total, device_count);
+ output_status(x, ps_total, device_count);
}
static void output_element_ranges(t_hidio *x)
{
- if( (x->x_device_number > -1) && (x->x_device_open) )
- {
- unsigned int i;
- t_atom output_data[4];
-
- for(i=0;i<element_count[x->x_device_number];++i)
- {
+ if( (x->x_device_number > -1) && (x->x_device_open) )
+ {
+ unsigned int i;
+ t_atom output_data[4];
+
+ for(i=0;i<element_count[x->x_device_number];++i)
+ {
#ifdef PD
- SETSYMBOL(output_data, element[x->x_device_number][i]->type);
- SETSYMBOL(output_data + 1, element[x->x_device_number][i]->name);
- SETFLOAT(output_data + 2, element[x->x_device_number][i]->min);
- SETFLOAT(output_data + 3, element[x->x_device_number][i]->max);
+ SETSYMBOL(output_data, element[x->x_device_number][i]->type);
+ SETSYMBOL(output_data + 1, element[x->x_device_number][i]->name);
+ SETFLOAT(output_data + 2, element[x->x_device_number][i]->min);
+ SETFLOAT(output_data + 3, element[x->x_device_number][i]->max);
#else
- atom_setsym(output_data, element[x->x_device_number][i]->type);
- atom_setsym(output_data + 1, element[x->x_device_number][i]->name);
- atom_setlong(output_data + 2, element[x->x_device_number][i]->min);
- atom_setlong(output_data + 3, element[x->x_device_number][i]->max);
+ atom_setsym(output_data, element[x->x_device_number][i]->type);
+ atom_setsym(output_data + 1, element[x->x_device_number][i]->name);
+ 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 /* PD */
- outlet_anything(x->x_status_outlet, ps_range, 4, output_data);
- }
- }
+ outlet_anything(x->x_status_outlet, ps_range, 4, output_data);
+ }
+ }
}
static unsigned int name_to_usage(char *usage_name)
{ // output usagepage << 16 + usage
- if(strcmp(usage_name,"pointer") == 0) return 0x00010001;
- if(strcmp(usage_name,"mouse") == 0) return 0x00010002;
- if(strcmp(usage_name,"joystick") == 0) return 0x00010004;
- if(strcmp(usage_name,"gamepad") == 0) return 0x00010005;
- if(strcmp(usage_name,"keyboard") == 0) return 0x00010006;
- if(strcmp(usage_name,"keypad") == 0) return 0x00010007;
- if(strcmp(usage_name,"multiaxiscontroller") == 0) return 0x00010008;
- return 0;
+ if(strcmp(usage_name,"pointer") == 0) return 0x00010001;
+ if(strcmp(usage_name,"mouse") == 0) return 0x00010002;
+ if(strcmp(usage_name,"joystick") == 0) return 0x00010004;
+ if(strcmp(usage_name,"gamepad") == 0) return 0x00010005;
+ if(strcmp(usage_name,"keyboard") == 0) return 0x00010006;
+ if(strcmp(usage_name,"keypad") == 0) return 0x00010007;
+ if(strcmp(usage_name,"multiaxiscontroller") == 0) return 0x00010008;
+ return 0;
+}
+
+
+static t_int convert_symbol_hex_to_int(t_symbol *s)
+{
+ if(strncmp(s->s_name, "0x", 2) == 0)
+ return (t_int) strtoul(s->s_name, NULL, 16);
+ else
+ return -1;
}
static short get_device_number_from_arguments(int argc, t_atom *argv)
{
#ifdef PD
- short device_number = -1;
- char device_type_string[MAXPDSTRING] = "";
- unsigned short device_type_instance;
+ short device_number = -1;
+ char device_type_string[MAXPDSTRING] = "";
+ unsigned short device_type_instance;
#else
- long device_number = -1;
- char *device_type_string;
- long device_type_instance;
+ long device_number = -1;
+ char *device_type_string;
+ long device_type_instance;
#endif /* PD */
- unsigned int usage;
- unsigned short vendor_id;
- unsigned short product_id;
- t_symbol *first_argument;
- t_symbol *second_argument;
-
- if(argc == 1)
- {
+ unsigned int usage;
+ unsigned short vendor_id;
+ unsigned short product_id;
+ t_symbol *first_argument;
+ t_symbol *second_argument;
+
+ if(argc == 1)
+ {
#ifdef PD
- first_argument = atom_getsymbolarg(0,argc,argv);
- if(first_argument == &s_)
+ first_argument = atom_getsymbolarg(0,argc,argv);
+ if(first_argument == &s_)
#else
- atom_arg_getsym(&first_argument, 0,argc,argv);
- if(first_argument == _sym_nothing)
+ atom_arg_getsym(&first_argument, 0,argc,argv);
+ if(first_argument == _sym_nothing)
#endif /* PD */
- { // single float arg means device #
- post("first_argument == &s_");
+ { // single float arg means device #
+ post("first_argument == &s_");
#ifdef PD
- device_number = (short) atom_getfloatarg(0,argc,argv);
+ device_number = (short) atom_getfloatarg(0,argc,argv);
#else
- atom_arg_getlong(&device_number, 0, argc, argv);
+ atom_arg_getlong(&device_number, 0, argc, argv);
#endif /* PD */
- if(device_number < 0) device_number = -1;
- debug_post(LOG_DEBUG,"[hidio] setting device# to %d",device_number);
- }
- else
- { // single symbol arg means first instance of a device type
+ if(device_number < 0) device_number = -1;
+ debug_post(LOG_DEBUG,"[hidio] setting device# to %d",device_number);
+ }
+ else
+ { // single symbol arg means first instance of a device type
#ifdef PD
- atom_string(argv, device_type_string, MAXPDSTRING-1);
+ atom_string(argv, device_type_string, MAXPDSTRING-1);
#else
- device_type_string = atom_string(argv);
- // LATER do we have to free this string manually???
+ device_type_string = atom_string(argv);
+ // LATER do we have to free this string manually???
#endif /* PD */
- usage = name_to_usage(device_type_string);
- device_number = get_device_number_from_usage(0, usage >> 16,
- usage & 0xffff);
- debug_post(LOG_INFO,"[hidio] using 0x%04x 0x%04x for %s",
- usage >> 16, usage & 0xffff, device_type_string);
- }
- }
- else if(argc == 2)
- {
+ usage = name_to_usage(device_type_string);
+ device_number = get_device_number_from_usage(0, usage >> 16,
+ usage & 0xffff);
+ debug_post(LOG_INFO,"[hidio] using 0x%04x 0x%04x for %s",
+ usage >> 16, usage & 0xffff, device_type_string);
+ }
+ }
+ else if(argc == 2)
+ {
#ifdef PD
- first_argument = atom_getsymbolarg(0,argc,argv);
- second_argument = atom_getsymbolarg(1,argc,argv);
- if( second_argument == &s_ )
+ first_argument = atom_getsymbolarg(0,argc,argv);
+ second_argument = atom_getsymbolarg(1,argc,argv);
+ if( second_argument == &s_ )
#else
- atom_arg_getsym(&first_argument, 0,argc,argv);
- atom_arg_getsym(&second_argument, 1,argc,argv);
- if( second_argument == _sym_nothing )
+ atom_arg_getsym(&first_argument, 0,argc,argv);
+ atom_arg_getsym(&second_argument, 1,argc,argv);
+ if( second_argument == _sym_nothing )
#endif /* PD */
- { /* a symbol then a float means match on usage */
+ { /* a symbol then a float means match on usage */
#ifdef PD
- atom_string(argv, device_type_string, MAXPDSTRING-1);
- usage = name_to_usage(device_type_string);
- device_type_instance = atom_getfloatarg(1,argc,argv);
+ atom_string(argv, device_type_string, MAXPDSTRING-1);
+ usage = name_to_usage(device_type_string);
+ device_type_instance = atom_getfloatarg(1,argc,argv);
#else
- device_type_string = atom_string(argv);
- usage = name_to_usage(device_type_string);
- atom_arg_getlong(&device_type_instance, 1, argc, argv);
+ device_type_string = atom_string(argv);
+ usage = name_to_usage(device_type_string);
+ atom_arg_getlong(&device_type_instance, 1, argc, argv);
#endif /* PD */
- debug_post(LOG_DEBUG,"[hidio] looking for %s at #%d",
- device_type_string, device_type_instance);
- device_number = get_device_number_from_usage(device_type_instance,
- usage >> 16,
- usage & 0xffff);
- }
- else
- { /* two symbols means idVendor and idProduct in hex */
- vendor_id =
- (unsigned short) strtol(first_argument->s_name, NULL, 16);
- product_id =
- (unsigned short) strtol(second_argument->s_name, NULL, 16);
- device_number = get_device_number_by_id(vendor_id,product_id);
- }
- }
- return device_number;
+ debug_post(LOG_DEBUG,"[hidio] looking for %s at #%d",
+ device_type_string, device_type_instance);
+ device_number = get_device_number_from_usage(device_type_instance,
+ usage >> 16,
+ usage & 0xffff);
+ }
+ else
+ { /* two symbols means idVendor and idProduct in hex */
+ vendor_id =
+ (unsigned short) strtol(first_argument->s_name, NULL, 16);
+ product_id =
+ (unsigned short) strtol(second_argument->s_name, NULL, 16);
+ device_number = get_device_number_by_id(vendor_id,product_id);
+ }
+ }
+ return device_number;
}
@@ -290,55 +299,62 @@ static short get_device_number_from_arguments(int argc, t_atom *argv)
* of CPU time since this is run for every event that is output. */
void hidio_output_event(t_hidio *x, t_hid_element *output_element)
{
-/* debug_post(LOG_DEBUG,"hidio_output_event: instance %d/%d last: %llu",
- x->x_instance+1, hidio_instance_count,
- last_execute_time[x->x_device_number]);*/
+/* debug_post(LOG_DEBUG,"hidio_output_event: instance %d/%d last: %llu",
+ x->x_instance+1, hidio_instance_count,
+ last_execute_time[x->x_device_number]);*/
#ifdef PD
- SETFLOAT(output_element->output_message + 2, output_element->value);
+ SETFLOAT(output_element->output_message + 2, output_element->value);
#else /* Max */
- atom_setlong(output_element->output_message + 2, (long)output_element->value);
+ atom_setlong(output_element->output_message + 2, (long)output_element->value);
#endif /* PD */
- outlet_anything(x->x_data_outlet, output_element->type, 3,
- output_element->output_message);
+ outlet_anything(x->x_data_outlet, output_element->type, 3,
+ output_element->output_message);
}
void hidio_write_event(t_hidio *x, t_symbol *s, int argc, t_atom *argv)
{
- debug_post(LOG_DEBUG,"hidio_write_event_symbols");
+ debug_post(LOG_DEBUG,"hidio_write_event");
t_symbol *first_argument;
- t_symbol *second_argument;
+ t_symbol *second_argument;
+ t_int first_argument_int;
+ t_int second_argument_int;
- if(argc == 4)
- {
- first_argument = atom_getsymbolarg(0,argc,argv);
- if(first_argument == &s_)
- { // first float arg means all float message
- debug_post(LOG_DEBUG,"first_argument == &s_");
- hidio_write_event_ints(x, atom_getintarg(0,argc,argv), atom_getintarg(1,argc,argv),
- atom_getintarg(2,argc,argv), atom_getintarg(3,argc,argv));
- }
- else
- {
- second_argument = atom_getsymbolarg(1,argc,argv);
- if(second_argument == &s_)
- { // symbol page and float usage
- debug_post(LOG_DEBUG,"second_argument == &s_");
- hidio_write_event_symbol_int(x, first_argument,
- atom_getintarg(1,argc,argv),
- atom_getintarg(2,argc,argv),
- atom_getintarg(3,argc,argv));
- }
- else
- { // symbol page and usage
- hidio_write_event_symbols(x, first_argument, second_argument,
- atom_getintarg(2,argc,argv), atom_getintarg(3,argc,argv));
- }
- }
-
+/* TODO add symbol for value to allow for hex values. This would be useful
+ * for sending values greater than Pd's t_float can handle */
+ if(argc != 4)
+ {
+ pd_error(x, "[hidio] write message must have exactly 4 atoms");
+ return;
}
- else
+
+ first_argument = atom_getsymbolarg(0,argc,argv);
+ if(first_argument == &s_)
+ { // first float arg means all float message
+ debug_post(LOG_DEBUG,"first_argument == &s_");
+ hidio_write_event_ints(x, atom_getintarg(0,argc,argv), atom_getintarg(1,argc,argv),
+ atom_getintarg(2,argc,argv), atom_getintarg(3,argc,argv));
+ }
+ else
{
- pd_error(x, "[hidio] write message format not supported");
+ // if the symbol is a hex number, convert it to a t_int
+ first_argument_int = convert_symbol_hex_to_int(first_argument);
+ second_argument = atom_getsymbolarg(1,argc,argv);
+ if((second_argument == &s_) && (first_argument_int > -1))
+ { // symbol page and float usage
+ debug_post(LOG_DEBUG,"second_argument == &s_");
+ hidio_write_event_symbol_int(x, first_argument,
+ atom_getintarg(1,argc,argv),
+ atom_getintarg(2,argc,argv),
+ atom_getintarg(3,argc,argv));
+ }
+ else
+ { // symbol page and usage
+ // if the symbol is a hex number, convert it to a t_int
+ if( (first_argument->s_name[0] == '0') && (first_argument->s_name[1] == 'x') )
+ first_argument_int = (t_int) strtoul(first_argument->s_name, 0, 16);
+ hidio_write_event_symbols(x, first_argument, second_argument,
+ atom_getintarg(2,argc,argv), atom_getintarg(3,argc,argv));
+ }
}
}
@@ -349,9 +365,9 @@ static void hidio_stop_poll(t_hidio* x)
if (x->x_started)
{
- clock_unset(x->x_clock);
- debug_post(LOG_INFO,"[hidio] polling stopped");
- x->x_started = 0;
+ clock_unset(x->x_clock);
+ debug_post(LOG_INFO,"[hidio] polling stopped");
+ x->x_started = 0;
}
}
@@ -365,63 +381,63 @@ static void hidio_stop_poll(t_hidio* x)
*/
void hidio_poll(t_hidio* x, t_float f)
{
- debug_post(LOG_DEBUG,"hidio_poll");
+ debug_post(LOG_DEBUG,"hidio_poll");
-/* if the user sets the delay less than 2, set to block size */
- if( f > 2 )
- x->x_delay = (t_int)f;
- else if( f > 0 ) //TODO make this the actual time between message processing
- x->x_delay = 1.54;
- if(x->x_device_number > -1)
- {
- if(!x->x_device_open)
- {
- hidio_open(x,ps_open,0,NULL);
- }
- if(!x->x_started)
- {
- clock_delay(x->x_clock, x->x_delay);
- debug_post(LOG_DEBUG,"[hidio] polling started");
- x->x_started = 1;
- }
- }
+/* if the user sets the delay less than 2, set to block size */
+ if( f > 2 )
+ x->x_delay = (t_int)f;
+ else if( f > 0 ) //TODO make this the actual time between message processing
+ x->x_delay = 1.54;
+ if(x->x_device_number > -1)
+ {
+ if(!x->x_device_open)
+ {
+ hidio_open(x,ps_open,0,NULL);
+ }
+ if(!x->x_started)
+ {
+ clock_delay(x->x_clock, x->x_delay);
+ debug_post(LOG_DEBUG,"[hidio] polling started");
+ x->x_started = 1;
+ }
+ }
}
static void hidio_set_from_float(t_hidio *x, t_floatarg f)
{
/* values greater than 1 set the polling delay time */
/* 1 and 0 for start/stop so you can use a [tgl] */
- if(f > 1)
- {
- x->x_delay = (t_int)f;
- hidio_poll(x,f);
- }
- else if(f == 1)
- {
- if(! x->x_started)
- {
- hidio_poll(x,f);
- }
- }
- else if(f == 0)
- {
- hidio_stop_poll(x);
- }
+ if(f > 1)
+ {
+ x->x_delay = (t_int)f;
+ hidio_poll(x,f);
+ }
+ else if(f == 1)
+ {
+ if(! x->x_started)
+ {
+ hidio_poll(x,f);
+ }
+ }
+ else if(f == 0)
+ {
+ hidio_stop_poll(x);
+ }
}
/* close the device */
static void hidio_close(t_hidio *x)
{
- debug_post(LOG_DEBUG,"hidio_close");
+ debug_post(LOG_DEBUG,"hidio_close");
/* just to be safe, stop it first */
- hidio_stop_poll(x);
+ hidio_stop_poll(x);
- if(! hidio_close_device(x))
- {
- debug_post(LOG_INFO,"[hidio] closed device %d",x->x_device_number);
- x->x_device_open = 0;
- }
+ if(! hidio_close_device(x))
+ {
+ debug_post(LOG_INFO,"[hidio] closed device %d",x->x_device_number);
+ x->x_device_open = 0;
+ }
}
@@ -435,117 +451,117 @@ static void hidio_close(t_hidio *x)
*/
static void hidio_open(t_hidio *x, t_symbol *s, int argc, t_atom *argv)
{
- short new_device_number = get_device_number_from_arguments(argc, argv);
- t_int started = x->x_started; // store state to restore after device is opened
- debug_post(LOG_DEBUG,"hid_%s",s->s_name);
-
- if (new_device_number > -1)
- {
- /* check whether we have to close previous device */
- if (x->x_device_open && new_device_number != x->x_device_number)
- {
- hidio_close(x);
- }
- /* no device open, so open one now */
- if (!x->x_device_open)
- {
- if(hidio_open_device(x, new_device_number) == EXIT_SUCCESS)
- {
- x->x_device_open = 1;
- x->x_device_number = new_device_number;
- /* 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); // TODO is this useful?
- debug_post(LOG_DEBUG,"[hidio] set device# to %d",new_device_number);
- output_device_number(x);
- }
- else
- {
- x->x_device_number = -1;
- error("[hidio] can not open device %d",new_device_number);
- }
- }
- }
- else debug_post(LOG_WARNING,"[hidio] device does not exist");
- /* always output open result so you can test for success in Pd space */
- output_open_status(x);
+ short new_device_number = get_device_number_from_arguments(argc, argv);
+ t_int started = x->x_started; // store state to restore after device is opened
+ debug_post(LOG_DEBUG,"hid_%s",s->s_name);
+
+ if (new_device_number > -1)
+ {
+ /* check whether we have to close previous device */
+ if (x->x_device_open && new_device_number != x->x_device_number)
+ {
+ hidio_close(x);
+ }
+ /* no device open, so open one now */
+ if (!x->x_device_open)
+ {
+ if(hidio_open_device(x, new_device_number) == EXIT_SUCCESS)
+ {
+ x->x_device_open = 1;
+ x->x_device_number = new_device_number;
+ /* 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); // TODO is this useful?
+ debug_post(LOG_DEBUG,"[hidio] set device# to %d",new_device_number);
+ output_device_number(x);
+ }
+ else
+ {
+ x->x_device_number = -1;
+ error("[hidio] can not open device %d",new_device_number);
+ }
+ }
+ }
+ else debug_post(LOG_WARNING,"[hidio] device does not exist");
+ /* always output open result so you can test for success in Pd space */
+ output_open_status(x);
}
static void hidio_tick(t_hidio *x)
{
-// debug_post(LOG_DEBUG,"hidio_tick");
- t_hid_element *current_element;
- unsigned int i;
- double right_now;
+// debug_post(LOG_DEBUG,"hidio_tick");
+ t_hid_element *current_element;
+ unsigned int i;
+ double right_now;
#ifdef PD
- right_now = clock_getlogicaltime();
+ right_now = clock_getlogicaltime();
#else /* Max */
- clock_getftime(&right_now);
+ clock_getftime(&right_now);
#endif /* PD */
-// debug_post(LOG_DEBUG,"# %u\tnow: %llu\tlast: %llu", x->x_device_number,
-// right_now, last_execute_time[x->x_device_number]);
- if(right_now > last_execute_time[x->x_device_number])
- {
- hidio_get_events(x);
- last_execute_time[x->x_device_number] = right_now;
-/* debug_post(LOG_DEBUG,"executing: instance %d/%d at %llu last: %llu",
- x->x_instance+1, hidio_instance_count, right_now,
- last_execute_time[x->x_device_number]);*/
- }
- for(i=0; i< element_count[x->x_device_number]; ++i)
- {
- /* TODO: since relative events need to be output every time, they need
- * to be flagged when new relative events arrive. Otherwise, it'll
- * just spam out relative events no matter if anything new has
- * arrived */
- current_element = element[x->x_device_number][i];
- if(current_element->previous_value != current_element->value)
- {
- hidio_output_event(x, current_element);
- if(!current_element->relative)
- current_element->previous_value = current_element->value;
- }
- }
- if (x->x_started)
- {
- clock_delay(x->x_clock, x->x_delay);
- }
+// debug_post(LOG_DEBUG,"# %u\tnow: %llu\tlast: %llu", x->x_device_number,
+// right_now, last_execute_time[x->x_device_number]);
+ if(right_now > last_execute_time[x->x_device_number])
+ {
+ hidio_get_events(x);
+ last_execute_time[x->x_device_number] = right_now;
+/* debug_post(LOG_DEBUG,"executing: instance %d/%d at %llu last: %llu",
+ x->x_instance+1, hidio_instance_count, right_now,
+ last_execute_time[x->x_device_number]);*/
+ }
+ for(i=0; i< element_count[x->x_device_number]; ++i)
+ {
+ /* TODO: since relative events need to be output every time, they need
+ * to be flagged when new relative events arrive. Otherwise, it'll
+ * just spam out relative events no matter if anything new has
+ * arrived */
+ current_element = element[x->x_device_number][i];
+ if(current_element->previous_value != current_element->value)
+ {
+ hidio_output_event(x, current_element);
+ if(!current_element->relative)
+ current_element->previous_value = current_element->value;
+ }
+ }
+ if (x->x_started)
+ {
+ clock_delay(x->x_clock, x->x_delay);
+ }
}
static void hidio_info(t_hidio *x)
{
- output_open_status(x);
- output_device_number(x);
- output_device_count(x);
- output_poll_time(x);
- output_element_ranges(x);
- hidio_platform_specific_info(x);
+ output_open_status(x);
+ output_device_number(x);
+ output_device_count(x);
+ output_poll_time(x);
+ output_element_ranges(x);
+ hidio_platform_specific_info(x);
}
static void hidio_float(t_hidio* x, t_floatarg f)
{
- debug_post(LOG_DEBUG,"hid_float");
+ debug_post(LOG_DEBUG,"hid_float");
- hidio_set_from_float(x,f);
+ hidio_set_from_float(x,f);
}
#ifndef PD /* Max */
static void hidio_int(t_hidio* x, long l)
{
- debug_post(LOG_DEBUG,"hid_int");
+ debug_post(LOG_DEBUG,"hid_int");
- hidio_set_from_float(x, (float)l);
+ hidio_set_from_float(x, (float)l);
}
#endif /* NOT PD */
static void hidio_debug(t_hidio *x, t_float f)
{
- global_debug_level = f;
+ global_debug_level = f;
}
@@ -554,192 +570,192 @@ static void hidio_debug(t_hidio *x, t_float f)
*/
static void hidio_free(t_hidio* x)
{
- debug_post(LOG_DEBUG,"hidio_free");
+ debug_post(LOG_DEBUG,"hidio_free");
- hidio_close(x);
- clock_free(x->x_clock);
- hidio_instance_count--;
+ hidio_close(x);
+ clock_free(x->x_clock);
+ hidio_instance_count--;
- hidio_platform_specific_free(x);
+ hidio_platform_specific_free(x);
}
/* 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);
-
- x->x_clock = clock_new(x, (t_method)hidio_tick);
+ t_hidio *x = (t_hidio *)pd_new(hidio_class);
+
+ 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);
-
- x->x_clock = clock_new(x, (method)hidio_tick);
+ t_hidio *x = (t_hidio *)object_alloc(hidio_class);
+
+ x->x_clock = clock_new(x, (method)hidio_tick);
- /* create anything outlet used for HID data */
- x->x_status_outlet = outlet_new(x, "anything");
- x->x_data_outlet = outlet_new(x, "anything");
+ /* create anything outlet used for HID data */
+ x->x_status_outlet = outlet_new(x, "anything");
+ x->x_data_outlet = outlet_new(x, "anything");
#endif /* PD */
- /* init vars */
- global_debug_level = 9; /* high numbers here means see more messages */
- 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_hid_device = hidio_platform_specific_new(x);
+ /* init vars */
+ global_debug_level = 9; /* high numbers here means see more messages */
+ 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_hid_device = hidio_platform_specific_new(x);
#endif
- x->x_device_number = get_device_number_from_arguments(argc, argv);
+ x->x_device_number = get_device_number_from_arguments(argc, argv);
- x->x_instance = hidio_instance_count;
- hidio_instance_count++;
+ x->x_instance = hidio_instance_count;
+ hidio_instance_count++;
- return x;
+ return x;
}
#ifdef PD
void hidio_setup(void)
{
- hidio_class = class_new(gensym("hidio"),
- (t_newmethod)hidio_new,
- (t_method)hidio_free,
- sizeof(t_hidio),
- CLASS_DEFAULT,
- A_GIMME,0);
-
- /* add inlet datatype methods */
- class_addfloat(hidio_class,(t_method) hidio_float);
- class_addbang(hidio_class,(t_method) hidio_tick);
-/* class_addanything(hidio_class,(t_method) hidio_anything); */
-
- /* 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);
+ hidio_class = class_new(gensym("hidio"),
+ (t_newmethod)hidio_new,
+ (t_method)hidio_free,
+ sizeof(t_hidio),
+ CLASS_DEFAULT,
+ A_GIMME,0);
+
+ /* add inlet datatype methods */
+ class_addfloat(hidio_class,(t_method) hidio_float);
+ class_addbang(hidio_class,(t_method) hidio_tick);
+/* class_addanything(hidio_class,(t_method) hidio_anything); */
+
+ /* 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);
- class_addmethod(hidio_class,(t_method) hidio_close,gensym("close"),0);
- class_addmethod(hidio_class,(t_method) hidio_poll,gensym("poll"),A_DEFFLOAT,0);
+ 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);
+ class_addmethod(hidio_class,(t_method) hidio_close,gensym("close"),0);
+ class_addmethod(hidio_class,(t_method) hidio_poll,gensym("poll"),A_DEFFLOAT,0);
/* test function for output support */
- class_addmethod(hidio_class,(t_method) hidio_write_event, gensym("write"), A_GIMME ,0);
-
-
- post("[hidio] %d.%d, written by Hans-Christoph Steiner <hans@eds.org>",
- HIDIO_MAJOR_VERSION, HIDIO_MINOR_VERSION);
- post("\tcompiled on "__DATE__" at "__TIME__ " ");
-
- /* pre-generate often used symbols */
- ps_open = gensym("open");
- ps_device = gensym("device");
- ps_poll = gensym("poll");
- ps_total = gensym("total");
- ps_range = gensym("range");
-
- generate_type_symbols();
- generate_event_symbols();
+ class_addmethod(hidio_class,(t_method) hidio_write_event, gensym("write"), A_GIMME ,0);
+
+
+ post("[hidio] %d.%d, written by Hans-Christoph Steiner <hans@eds.org>",
+ HIDIO_MAJOR_VERSION, HIDIO_MINOR_VERSION);
+ post("\tcompiled on "__DATE__" at "__TIME__ " ");
+
+ /* pre-generate often used symbols */
+ ps_open = gensym("open");
+ ps_device = gensym("device");
+ ps_poll = gensym("poll");
+ 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)
{
- if (msg == _sym_free) // this message is sent when a child object is freeing
- {
- object_detach(gensym("_obex_hidio"), s, x);
- object_unregister(sender);
- }
+ if (msg == _sym_free) // this message is sent when a child object is freeing
+ {
+ object_detach(gensym("_obex_hidio"), s, x);
+ object_unregister(sender);
+ }
}
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;
- }
- }
- else
- {
- switch (a)
- {
- case 0:
- sprintf(s, "Control Messages");
- break;
- case 1:
- sprintf(s, "nothing");
- break;
- }
- }
+ if (m == 2)
+ {
+ 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, "Control Messages");
+ break;
+ case 1:
+ sprintf(s, "nothing");
+ break;
+ }
+ }
}
int main()
{
- t_class *c;
-
- c = class_new("hidio", (method)hidio_new, (method)hidio_free, (short)sizeof(t_hidio),
- 0L, A_GIMME, 0);
-
- /* initialize the common symbols, since we want to use them */
- common_symbols_init();
-
- /* register the byte offset of obex with the class */
- class_obexoffset_set(c, calcoffset(t_hidio, x_obex));
-
- /* add methods to the class */
- class_addmethod(c, (method)hidio_int, "int", A_LONG, 0);
- class_addmethod(c, (method)hidio_float, "float", A_FLOAT, 0);
- class_addmethod(c, (method)hidio_tick, "bang", A_GIMME, 0);
-
- /* add inlet message methods */
- class_addmethod(c, (method)hidio_debug, "debug",A_DEFFLOAT,0);
- class_addmethod(c, (method)hidio_build_device_list, "refresh",0);
+ t_class *c;
+
+ c = class_new("hidio", (method)hidio_new, (method)hidio_free, (short)sizeof(t_hidio),
+ 0L, A_GIMME, 0);
+
+ /* initialize the common symbols, since we want to use them */
+ common_symbols_init();
+
+ /* register the byte offset of obex with the class */
+ class_obexoffset_set(c, calcoffset(t_hidio, x_obex));
+
+ /* add methods to the class */
+ class_addmethod(c, (method)hidio_int, "int", A_LONG, 0);
+ class_addmethod(c, (method)hidio_float, "float", A_FLOAT, 0);
+ class_addmethod(c, (method)hidio_tick, "bang", A_GIMME, 0);
+
+ /* 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);
- class_addmethod(c, (method)hidio_close, "close",0);
- class_addmethod(c, (method)hidio_poll, "poll",A_DEFFLOAT,0);
- /* perfomrance / system stuff */
-
- class_addmethod(c, (method)hidio_assist, "assist", A_CANT, 0);
-
- /* add a notify method, so we get notifications from child objects */
- class_addmethod(c, (method)hidio_notify, "notify", A_CANT, 0);
- // add methods for dumpout and quickref
- class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0);
- class_addmethod(c, (method)object_obex_quickref, "quickref", A_CANT, 0);
-
- /* we want this class to instantiate inside of the Max UI; ergo CLASS_BOX */
- class_register(CLASS_BOX, c);
- hidio_class = c;
-
- finder_addclass("Devices", "hidio");
- 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");
- ps_device = gensym("device");
- ps_poll = gensym("poll");
- ps_total = gensym("total");
- ps_range = gensym("range");
-
- generate_type_symbols();
- generate_event_symbols();
-
- return EXIT_SUCCESS;
+ 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);
+ class_addmethod(c, (method)hidio_close, "close",0);
+ class_addmethod(c, (method)hidio_poll, "poll",A_DEFFLOAT,0);
+ /* perfomrance / system stuff */
+
+ class_addmethod(c, (method)hidio_assist, "assist", A_CANT, 0);
+
+ /* add a notify method, so we get notifications from child objects */
+ class_addmethod(c, (method)hidio_notify, "notify", A_CANT, 0);
+ // add methods for dumpout and quickref
+ class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0);
+ class_addmethod(c, (method)object_obex_quickref, "quickref", A_CANT, 0);
+
+ /* we want this class to instantiate inside of the Max UI; ergo CLASS_BOX */
+ class_register(CLASS_BOX, c);
+ hidio_class = c;
+
+ finder_addclass("Devices", "hidio");
+ 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");
+ ps_device = gensym("device");
+ ps_poll = gensym("poll");
+ ps_total = gensym("total");
+ ps_range = gensym("range");
+
+ generate_type_symbols();
+ generate_event_symbols();
+
+ return EXIT_SUCCESS;
}
#endif /* PD */
diff --git a/hidio_darwin.c b/hidio_darwin.c
index 529dc3b..ed157cf 100644
--- a/hidio_darwin.c
+++ b/hidio_darwin.c
@@ -497,7 +497,7 @@ static void hidio_print_element_list(t_hidio *x)
return;
}
post("[hidio] found %d elements:",element_count[x->x_device_number]);
- post("\n TYPE\tCODE\t#\tEVENT NAME");
+ post("\n TYPE\t\tCODE\t#\tcookie\tEVENT NAME");
post("-----------------------------------------------------------");
for(i=0; i<element_count[x->x_device_number]; i++)
{
@@ -506,8 +506,9 @@ static void hidio_print_element_list(t_hidio *x)
HIDGetTypeName((IOHIDElementType) pCurrentHIDElement->type, type_name);
HIDGetUsageName(pCurrentHIDElement->usagePage,
pCurrentHIDElement->usage, usage_name);
- post(" %s\t%s\t%d\t%s, %s", current_element->type->s_name,
+ post(" %s\t%s\t%d\t%d\t%s, %s", current_element->type->s_name,
current_element->name->s_name,(int) current_element->instance,
+ pCurrentHIDElement->cookie,
type_name, usage_name);
}
post("");
@@ -713,13 +714,21 @@ void hidio_get_events(t_hidio *x)
}
}
+
+/* switch to transactions */
+
+void hidio_write_packet(void)
+{
+}
+
+
void hidio_write_event_symbol_int(t_hidio *x, t_symbol *type, t_int code,
t_int instance, t_int value)
{
debug_post(LOG_DEBUG,"hidio_write_event_symbol_float");
}
-void hidio_write_event_symbols(t_hidio *x, t_symbol *type, t_symbol *code,
+void hidio_write_event_symbols(t_hidio *x, t_symbol *type, t_symbol *name,
t_int instance, t_int value)
{
/* TODO handle multiple instances of the same usage, i.e. arrays */
@@ -727,13 +736,14 @@ void hidio_write_event_symbols(t_hidio *x, t_symbol *type, t_symbol *code,
int i;
t_hid_element *current_element;
IOHIDEventStruct event;
- int cookie = (int) instance;
pRecDevice pCurrentHIDDevice = device_pointer[x->x_device_number];
pRecElement pCurrentHIDElement;
for(i=0; i<element_count[x->x_device_number]; i++)
{
current_element = element[x->x_device_number][i];
- if((current_element->type == type) && (current_element->name == code))
+ if((current_element->type == type)
+ && (current_element->name == name)
+ && (current_element->instance == instance))
{
pCurrentHIDElement = current_element->pHIDElement;
break;
@@ -742,12 +752,12 @@ void hidio_write_event_symbols(t_hidio *x, t_symbol *type, t_symbol *code,
post("element usage page and usage: 0x%04x 0x%04x", pCurrentHIDElement->usagePage, pCurrentHIDElement->usage);
event.elementCookie = (IOHIDElementCookie)pCurrentHIDElement->cookie;
event.value = (SInt32)value;
- post("pCurrentHIDElement->cookie, cookie, event.value, value: %d %d %d %f",
- pCurrentHIDElement->cookie, cookie, event.value, value);
+ post("pCurrentHIDElement->cookie %d, event.elementCookie %d, event.value %d, value %d",
+ pCurrentHIDElement->cookie, event.elementCookie, event.value, value);
HIDSetElementValue(pCurrentHIDDevice, pCurrentHIDElement, &event);
}
-void hidio_write_event_ints(t_hidio *x, t_int type, t_int code,
+void hidio_write_event_ints(t_hidio *x, t_int type, t_int name,
t_int instance, t_int value)
{
debug_post(LOG_DEBUG,"hidio_write_event_floats");
diff --git a/hidio_linux.c b/hidio_linux.c
index 72e57f4..89fef49 100644
--- a/hidio_linux.c
+++ b/hidio_linux.c
@@ -437,6 +437,30 @@ void hidio_print(t_hidio* x)
hidio_print_element_list(x);
}
+void hidio_write_packet(void)
+{
+ debug_post(LOG_DEBUG,"hidio_write_packet");
+}
+
+
+void hidio_write_event_symbol_int(t_hidio *x, t_symbol *type, t_int code,
+ t_int instance, t_int value)
+{
+ debug_post(LOG_DEBUG,"hidio_write_event_symbol_int");
+}
+
+void hidio_write_event_symbols(t_hidio *x, t_symbol *type, t_symbol *code,
+ t_int instance, t_int value)
+{
+ debug_post(LOG_DEBUG,"hidio_write_event_symbols");
+}
+
+void hidio_write_event_ints(t_hidio *x, t_int type, t_int code,
+ t_int instance, t_int value)
+{
+ debug_post(LOG_DEBUG,"hidio_write_event_ints");
+}
+
t_int hidio_open_device(t_hidio *x, short device_number)
{