Update of /cvsroot/pure-data/externals/hcs/usbhid In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30887/usbhid
Added Files: usbhid-help.pd usbhid.c usbhid.libs Log Message: separated usbhid into its own folder since it had dependencies that don't work on all platforms
--- NEW FILE: usbhid-help.pd --- #N canvas 254 84 629 549 10; #X obj 132 376 usbhid; #X msg 184 91 close; #X msg 184 117 reset; #X text 240 307 GARBAGE FOR TESTING; #X msg 197 155 print; #X text 317 72 Gravis/Destroyer Tiltpad; #X text 311 43 Microsoft 5-button Mouse; #N canvas 0 22 462 312 buttons 0; #X obj 99 36 inlet; #X obj 63 108 & 1; #X obj 63 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 93 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 2 ; #X obj 123 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 4; #X obj 153 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 8; #X obj 183 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 16; #X obj 223 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 32; #X obj 263 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 303 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 128; #X obj 93 108 & 2; #X obj 123 108 & 4; #X obj 153 108 & 8; #X obj 183 108 & 16; #X obj 223 108 & 32; #X obj 263 108 & 64; #X obj 303 108 & 128; #X connect 0 0 1 0; #X connect 0 0 10 0; #X connect 0 0 11 0; #X connect 0 0 12 0; #X connect 0 0 13 0; #X connect 0 0 14 0; #X connect 0 0 15 0; #X connect 0 0 16 0; #X connect 1 0 2 0; #X connect 10 0 3 0; #X connect 11 0 4 0; #X connect 12 0 5 0; #X connect 13 0 6 0; #X connect 14 0 7 0; #X connect 15 0 8 0; #X connect 16 0 9 0; #X restore 65 515 pd buttons test; #X obj 127 462 unpack float float float float; #X obj 44 83 metro 400; #X obj 46 57 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X floatatom 186 499 5 0 0 0 - - -; #X floatatom 256 500 5 0 0 0 - - -; #X floatatom 336 495 5 0 0 0 - - -; #X msg 171 43 open 0x045e 0x0039; #X msg 157 13 open vendorId productId; #X msg 176 71 open 0x047D 0x4008; #X floatatom 125 496 5 0 0 0 - - -; #X msg 239 273 debug $1; #X obj 239 251 hradio 15 1 0 10 empty empty empty 0 -6 0 8 -262144 -1 -1 0; #X obj 27 441 print data; #N canvas 458 151 454 485 parsing 0; #X obj 77 6 inlet; #X obj 80 101 route float symbol; #X obj 80 190 mapping/tolist; #X obj 139 137 trigger symbol bang; #X msg 22 139 bang; #X obj 81 226 list trim; #X obj 241 312 print; #X obj 80 272 route path; #X obj 34 328 print path-------------; #X obj 78 31 list-abs/list-drip; #X obj 198 51 trigger bang bang; #X obj 247 89 print end---------; #X connect 0 0 9 0; #X connect 1 0 2 0; #X connect 1 1 3 0; #X connect 2 0 5 0; #X connect 3 0 2 0; #X connect 3 1 2 1; #X connect 4 0 2 0; #X connect 5 0 7 0; #X connect 7 0 8 0; #X connect 7 1 6 0; #X connect 9 0 1 0; #X connect 9 1 10 0; #X connect 10 0 2 1; #X connect 10 1 11 0; #X restore 226 418 pd parsing; #X text 8 122 how many bytes to read; #X msg 194 136 refresh; #X text 259 137 reinit and refresh device list; #X text 233 117 resets device (don't really know what that does tho) ; #X obj 171 419 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X obj 171 397 route open device; #X msg 44 104 get 4; #X msg 82 137 get 2; #X msg 212 179 descriptor; #X text 291 179 get descriptor; #X msg 219 213 descriptor 1 30 1 31 1 38; #X text 398 212 [descriptor page# usage# ...(; #X text 218 197 for writing to the device:; #X msg 25 208 set 2; #X msg 237 323 close , open 0x045e 0x0039 , descriptor; #X text 183 382 <- status outlet; #X text 21 383 data outlet ->; #X connect 0 0 8 0; #X connect 0 0 20 0; #X connect 0 1 27 0; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 4 0 0 0; #X connect 8 0 7 0; #X connect 8 0 17 0; #X connect 8 1 11 0; #X connect 8 2 12 0; #X connect 8 3 13 0; #X connect 9 0 28 0; #X connect 10 0 9 0; #X connect 14 0 0 0; #X connect 16 0 0 0; #X connect 18 0 0 0; #X connect 19 0 18 0; #X connect 23 0 0 0; #X connect 27 0 26 0; #X connect 27 1 21 0; #X connect 28 0 0 0; #X connect 29 0 0 0; #X connect 30 0 0 0; #X connect 32 0 0 0; #X connect 35 0 0 0; #X connect 36 0 0 0;
--- NEW FILE: usbhid.c --- /* --------------------------------------------------------------------------*/ /* */ /* Pd interface to the USB HID API using libhid, which is built on libusb */ /* Written by Hans-Christoph Steiner hans@at.or.at */ /* */ /* Copyright (c) 2004 Hans-Christoph Steiner */ /* */ /* This program is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU General Public License */ /* as published by the Free Software Foundation; either version 2 */ /* of the License, or (at your option) any later version. */ /* */ /* See file LICENSE for further informations on licensing terms. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program; if not, write to the Free Software Foundation, */ /* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* */ /* --------------------------------------------------------------------------*/
/* libhid hasn't been ported to Win32 yet */ #ifndef _WIN32
#include <usb.h> #include <hid.h> #include <stdio.h> #include <string.h> #include <float.h> #include "m_pd.h"
/* * TODO: rename read, get, set messages so they make sense * TODO: make size output work well */
/* * BUG: for some reason it skips one of the button bits */
/*------------------------------------------------------------------------------ * INCLUDE KLUDGE */
/* NOTE: included from libusb/usbi.h. UGLY, i know, but so is libusb! * this struct doesn't seem to be defined in usb.h, only prototyped */ struct usb_dev_handle { int fd; struct usb_bus *bus; struct usb_device *device; int config; int interface; int altsetting; void *impl_info; };
/*------------------------------------------------------------------------------ * GLOBAL VARIABLES */
/* count the number of instances of this object so that certain free() * functions can be called only after the final instance is detroyed. */ t_int usbhid_instance_count;
#define HID_ID_MAX 32 char *hid_id[HID_ID_MAX]; /* FIXME: 32 devices MAX */ t_int hid_id_count;
/* this array is for keeping track of whether each device has been read in * each cycle */ char usbhid_device_read_status[HID_ID_MAX];
/*------------------------------------------------------------------------------ * CLASS DEF */
typedef struct _usbhid { t_object x_obj; /* usbhid types */ HIDInterface *x_hidinterface; hid_return x_hid_return; /* internal state */ unsigned short vendor_id; // idVendor for current device unsigned short product_id; // idProduct for current device unsigned short debug_level; // control debug messages to the console t_int x_device_number; t_int x_read_element_count; t_int *x_read_elements; t_int x_write_element_count; t_int *x_write_elements; t_int report_size; // size in bytes of the HID report /* output */ t_atom *output; // holder for a list of atoms to be outputted t_int output_count; // number of atoms in in x->output t_outlet *x_data_outlet; t_outlet *x_status_outlet; } t_usbhid;
/*------------------------------------------------------------------------------ * LOCAL DEFINES */
#define USBHID_MAJOR_VERSION 0 #define USBHID_MINOR_VERSION 0
static t_class *usbhid_class;
/* for USB strings */ #define STRING_BUFFER_LENGTH 256
#define SEND_PACKET_LENGTH 1 #define RECEIVE_PACKET_LENGTH 6 #define PATH_LENGTH 3
/*------------------------------------------------------------------------------ * SUPPORT FUNCTIONS */
/* add one new atom to the list to be outputted */ static void add_atom_to_output(t_usbhid *x, t_atom *new_atom) { t_atom *new_atom_list;
new_atom_list = (t_atom *)getbytes((x->output_count + 1) * sizeof(t_atom)); memcpy(new_atom_list, x->output, x->output_count * sizeof(t_atom)); freebytes(x->output, x->output_count * sizeof(t_atom)); x->output = new_atom_list; memcpy(x->output + x->output_count, new_atom, sizeof(t_atom)); ++(x->output_count); }
static void add_symbol_to_output(t_usbhid *x, t_symbol *s) { t_atom *temp_atom = getbytes(sizeof(t_atom)); SETSYMBOL(temp_atom, s); add_atom_to_output(x,temp_atom); freebytes(temp_atom,sizeof(t_atom)); } static void add_float_to_output(t_usbhid *x, t_float f) { t_atom *temp_atom = getbytes(sizeof(t_atom)); SETFLOAT(temp_atom, f); add_atom_to_output(x,temp_atom); freebytes(temp_atom,sizeof(t_atom)); }
static void reset_output(t_usbhid *x) { if(x->output) { freebytes(x->output, x->output_count * sizeof(t_atom)); x->output = NULL; x->output_count = 0; } }
static t_int init_libhid(t_usbhid *x) { if (! hid_is_initialised() ) { x->x_hid_return = hid_init(); if(x->x_hid_return != HID_RET_SUCCESS) { error("[usbhid] hid_init failed with return code %d\n", x->x_hid_return); } } return(x->x_hid_return); }
/* * This function is used in a HIDInterfaceMatcher to iterate thru all of the * HID devices on the USB bus */ static bool device_iterator (struct usb_dev_handle const* usbdev, void* custom, unsigned int length) { bool ret = false; t_int i; char current_dev_path[10];
/* only here to prevent the unused warning */ /* TODO remove */ length = *((unsigned long*)custom);
/* Obtain the device's full path */ sprintf(current_dev_path, "%s/%s", usbdev->bus->dirname, usbdev->device->filename);
/* Check if we already saw this dev */ for ( i = 0 ; ( hid_id[i] != NULL ) ; i++ ) { if (!strcmp(hid_id[i], current_dev_path ) ) break; }
/* Append device to the list if needed */ if (hid_id[i] == NULL) { hid_id[i] = (char *) malloc(strlen(usbdev->device->filename) + strlen(usbdev->bus->dirname) ); sprintf(hid_id[i], "%s/%s", usbdev->bus->dirname, usbdev->device->filename); } else /* device already seen */ { return false; }
/* Filter non HID device */ if ( (usbdev->device->descriptor.bDeviceClass == 0) /* Class defined at interface level */ && usbdev->device->config && usbdev->device->config->interface->altsetting->bInterfaceClass == USB_CLASS_HID) { post("bus %s device %s: %d %d", usbdev->bus->dirname, usbdev->device->filename, usbdev->device->descriptor.idVendor, usbdev->device->descriptor.idProduct); ret = true; } else { ret = false; }
return ret; }
/* -------------------------------------------------------------------------- */ /* This function is used in a HIDInterfaceMatcher in order to match devices by * serial number. */ /* static bool match_serial_number(struct usb_dev_handle* usbdev, void* custom, unsigned int length) */ /* { */ /* bool ret; */ /* char* buffer = (char*)malloc(length); */ /* usb_get_string_simple(usbdev, usb_device(usbdev)->descriptor.iSerialNumber, */ /* buffer, length); */ /* ret = strncmp(buffer, (char*)custom, length) == 0; */ /* free(buffer); */ /* return ret; */ /* } */
/* -------------------------------------------------------------------------- */ /* static bool get_device_by_number(struct usb_dev_handle* usbdev, */ /* void* custom, */ /* unsigned int length) */ /* { */ /* bool ret; */ /* return ret; */ /* } */
/* -------------------------------------------------------------------------- */ static t_int* make_hid_path(t_int element_count, t_int argc, t_atom *argv) { t_int i; t_int *return_array = NULL; post("element_count %d",element_count); return_array = (t_int *) getbytes(sizeof(t_int) * element_count); for(i=0; i < element_count; ++i) { /* * A usbhid path component is 32 bits, the high 16 bits identify the usage page, * and the low 16 bits the item number. */ return_array[i] = (atom_getintarg(i*2,argc,argv) << 16) + atom_getintarg(i*2+1,argc,argv); /* TODO: print error if a symbol is found in the data list */ } return return_array; }
static t_int get_device_string(HIDInterface *hidif, char *device_string) { int length; t_int ret = 0; char buffer[STRING_BUFFER_LENGTH];
if ( !hid_is_opened(hidif) ) return(0);
if (hidif->device->descriptor.iManufacturer) { length = usb_get_string_simple(hidif->dev_handle, hidif->device->descriptor.iManufacturer, buffer, STRING_BUFFER_LENGTH); if (length > 0) { strncat(device_string, buffer, STRING_BUFFER_LENGTH - strlen(device_string)); strncat(device_string, " ",1); ret = 1; } else { post("(unable to fetch manufacturer string)"); } } if (hidif->device->descriptor.iProduct) { length = usb_get_string_simple(hidif->dev_handle, hidif->device->descriptor.iProduct, buffer, STRING_BUFFER_LENGTH); if (length > 0) { strncat(device_string, buffer, STRING_BUFFER_LENGTH - strlen(device_string)); strncat(device_string, " ",1); ret = 1; } else { post("(unable to fetch product string)"); } }
if (hidif->device->descriptor.iSerialNumber) { length = usb_get_string_simple(hidif->dev_handle, hidif->device->descriptor.iSerialNumber, buffer, STRING_BUFFER_LENGTH); if (length > 0) strncat(device_string, buffer, STRING_BUFFER_LENGTH - strlen(device_string)); else post("(unable to fetch product string)"); } return ret; }
/*------------------------------------------------------------------------------ * IMPLEMENTATION */
/* -------------------------------------------------------------------------- */ static void usbhid_close(t_usbhid *x) { if(x->debug_level) post("usbhid_close"); t_int ret; char string_buffer[STRING_BUFFER_LENGTH];
if ( hid_is_opened(x->x_hidinterface) ) { ret = get_device_string(x->x_hidinterface,string_buffer); x->x_hid_return = hid_close(x->x_hidinterface); if (x->x_hid_return == HID_RET_SUCCESS) { if (ret) post("[usbhid]: closed %s",string_buffer); else post("[usbhid]: closed device"); reset_output(x); add_float_to_output(x,0); outlet_anything(x->x_status_outlet, gensym("open"), x->output_count, x->output); } else { error("[usbhid] could not close %d, error #%d",x->x_device_number,x->x_hid_return); } } }
/* -------------------------------------------------------------------------- */ static void usbhid_open(t_usbhid *x, t_symbol *vendor_id_hex, t_symbol *product_id_hex) { if(x->debug_level) post("usbhid_open"); char string_buffer[STRING_BUFFER_LENGTH];
if( init_libhid(x) != HID_RET_SUCCESS ) return;
/* convert hex symbols to ints */ x->vendor_id = (unsigned short) strtol(vendor_id_hex->s_name, NULL, 16); x->product_id = (unsigned short) strtol(product_id_hex->s_name, NULL, 16); if( hid_is_opened(x->x_hidinterface) ) { if( (x->vendor_id == x->x_hidinterface->device->descriptor.idVendor) && (x->product_id == x->x_hidinterface->device->descriptor.idProduct)) { post("[usbhid] device already opened"); return; } else { usbhid_close(x); } }
if( !hid_is_opened(x->x_hidinterface) ) { HIDInterfaceMatcher matcher = { x->vendor_id, x->product_id, NULL, NULL, 0 }; x->x_hid_return = hid_force_open(x->x_hidinterface, 0, &matcher, 3); if (x->x_hid_return == HID_RET_SUCCESS) { if (get_device_string(x->x_hidinterface,string_buffer)) post("[usbhid]: opened %s",string_buffer); reset_output(x); add_float_to_output(x,1); outlet_anything(x->x_status_outlet, gensym("open"), x->output_count, x->output); } else { error("[usbhid] hid_force_open failed with return code %d\n", x->x_hid_return); } } }
/* -------------------------------------------------------------------------- */ static void usbhid_set(t_usbhid *x, t_float length_arg) { if(x->debug_level) post("usbhid_set"); int packet_bytes = (int)length_arg; char packet[packet_bytes];
if ( !hid_is_opened(x->x_hidinterface) ) { error("[usbhid] device not open, can't set data"); return; } x->x_hid_return = hid_set_output_report(x->x_hidinterface, x->x_write_elements, x->x_write_element_count, packet, length_arg); if (x->x_hid_return != HID_RET_SUCCESS) { error("[usbhid] hid_get_input_report failed with return code %d\n", x->x_hid_return); reset_output(x); add_float_to_output(x, x->x_hid_return); outlet_anything(x->x_status_outlet, gensym("setError"), x->output_count, x->output); } }
/* -------------------------------------------------------------------------- */ static void usbhid_get(t_usbhid *x, t_float length_arg) { if(x->debug_level) post("usbhid_get"); int i; int packet_bytes = (int)length_arg; char packet[packet_bytes];
if ( !hid_is_opened(x->x_hidinterface) ) { error("[usbhid] device not open, can't get data"); return; } x->x_hid_return = hid_get_input_report(x->x_hidinterface, NULL, x->x_read_element_count, packet, length_arg); if (x->x_hid_return != HID_RET_SUCCESS) { error("[usbhid] hid_get_input_report failed with return code %d\n", x->x_hid_return); reset_output(x); add_float_to_output(x, x->x_hid_return); outlet_anything(x->x_status_outlet, gensym("getError"), x->output_count, x->output); }
reset_output(x); for(i=0; i<packet_bytes; ++i) add_float_to_output(x,packet[i]); outlet_list(x->x_data_outlet, &s_list, x->output_count, x->output); post("x->x_read_elements %d",x->x_read_elements); }
/* -------------------------------------------------------------------------- */ /* reinit libhid to get update the list of attached devices */ static void usbhid_refresh(t_usbhid *x) { x->x_hid_return = hid_cleanup(); if (x->x_hid_return != HID_RET_SUCCESS) error("[usbhid] hid_cleanup failed with return code %d\n", x->x_hid_return); if( init_libhid(x) != HID_RET_SUCCESS ) return; }
/* -------------------------------------------------------------------------- */ /* set the HID packet for which elements to read */ static void usbhid_set_read(t_usbhid *x, int argc, t_atom *argv) { if(x->debug_level) post("usbhid_set_read"); t_int i;
x->x_read_element_count = argc / 2; x->x_read_elements = make_hid_path(x->x_read_element_count, argc, argv); post("x_read_element_count %d",x->x_read_element_count); for(i=0;i<x->x_read_element_count;++i) post("x_read_elements %d: %d",i,x->x_read_elements[i]); }
/* -------------------------------------------------------------------------- */ /* convert a list to a HID packet and set it */ /* set the HID packet for which elements to write */ static void usbhid_set_descriptor(t_usbhid *x, int argc, t_atom *argv) { if(x->debug_level) post("usbhid_descriptor"); /* int const PATH_IN[PATH_LENGTH] = { 0xffa00001, 0xffa00002, 0xffa10003 }; */ // int const PATH_OUT[3] = { 0x00010002, 0x00010001, 0x00010030 }; t_int i;
x->x_write_element_count = argc / 2; x->x_write_elements = make_hid_path(x->x_write_element_count, argc, argv); post("x_write_element_count %d",x->x_write_element_count); for(i=0;i<x->x_write_element_count;++i) post("x_write_elements %d: %d",i,x->x_write_elements[i]); }
/* -------------------------------------------------------------------------- */ static void usbhid_get_descriptor(t_usbhid *x) { if(x->debug_level) post("usbhid_get"); unsigned int i = 0; t_int input_size = 0; t_int output_size = 0; t_int feature_size = 0;
if (!hid_is_opened(x->x_hidinterface)) { error("[usbget] cannot dump tree of unopened HIDinterface."); } else { post("[usbhid] parse tree of HIDInterface %s:\n", x->x_hidinterface->id); reset_output(x); while (HIDParse(x->x_hidinterface->hid_parser, x->x_hidinterface->hid_data)) { add_symbol_to_output(x, gensym("path")); switch(x->x_hidinterface->hid_data->Type) { case 0x80: add_symbol_to_output(x, gensym("input")); input_size = input_size + x->x_hidinterface->hid_data->Size; break; case 0x90: add_symbol_to_output(x, gensym("output")); output_size = output_size + x->x_hidinterface->hid_data->Size; break; case 0xb0: add_symbol_to_output(x, gensym("feature")); feature_size = feature_size + x->x_hidinterface->hid_data->Size; break; default: add_symbol_to_output(x, gensym("UNKNOWN_TYPE")); } add_float_to_output(x, x->x_hidinterface->hid_data->Size); add_float_to_output(x, x->x_hidinterface->hid_data->Offset); for (i = 0; i < x->x_hidinterface->hid_data->Path.Size; ++i) { add_symbol_to_output(x, gensym("usage")); add_float_to_output(x, x->x_hidinterface->hid_data->Path.Node[i].UPage); add_float_to_output(x, x->x_hidinterface->hid_data->Path.Node[i].Usage); post("page: 0x%04x\t%d\t\tusage: 0x%04x\t%d", x->x_hidinterface->hid_data->Path.Node[i].UPage, x->x_hidinterface->hid_data->Path.Node[i].UPage, x->x_hidinterface->hid_data->Path.Node[i].Usage, x->x_hidinterface->hid_data->Path.Node[i].Usage); } post("type: 0x%02x\n", x->x_hidinterface->hid_data->Type); add_symbol_to_output(x, gensym("logical")); add_float_to_output(x, x->x_hidinterface->hid_data->LogMin); add_float_to_output(x, x->x_hidinterface->hid_data->LogMax); } add_symbol_to_output(x, gensym("totalSize")); add_float_to_output(x, input_size); add_float_to_output(x, output_size); add_float_to_output(x, feature_size); outlet_anything(x->x_status_outlet, gensym("device"), x->output_count, x->output); } }
/* -------------------------------------------------------------------------- */ static void usbhid_descriptor(t_usbhid *x, t_symbol *s, int argc, t_atom *argv) { if(s == gensym("descriptor")) // get rid of unused s warning { if(argc) usbhid_set_descriptor(x,argc,argv); else usbhid_get_descriptor(x); } }
/* -------------------------------------------------------------------------- */ static void usbhid_print(t_usbhid *x) { if(x->debug_level) post("usbhid_print"); t_int i; char string_buffer[STRING_BUFFER_LENGTH]; /* t_atom event_data[3]; */
for ( i = 0 ; ( hid_id[i] != NULL ) ; i++ ) { if( hid_id[i] != NULL ) post("hid_id[%d]: %s",i,hid_id[i]); } if(get_device_string(x->x_hidinterface,string_buffer)) post("%s is currently open",string_buffer);
x->x_hid_return = hid_dump_tree(stdout, x->x_hidinterface); if (x->x_hid_return != HID_RET_SUCCESS) { fprintf(stderr, "hid_dump_tree failed with return code %d\n", x->x_hid_return); return; } /* SETSYMBOL(event_data, gensym(type)); /* type */ */ /* SETSYMBOL(event_data + 1, gensym(code)); /* code */ */ /* SETSYMBOL(event_data + 2, value); /* value */ */ // outlet_list(x->x_status_outlet, &s_list, }
/* -------------------------------------------------------------------------- */ static void usbhid_reset(t_usbhid *x) { if(x->debug_level) post("usbhid_reset"); hid_reset_HIDInterface(x->x_hidinterface); }
/* -------------------------------------------------------------------------- */ static void usbhid_debug(t_usbhid *x, t_float f) { x->debug_level = f; switch(x->debug_level) { case 0: hid_set_usb_debug(0); hid_set_debug(HID_DEBUG_NONE); break; case 1: hid_set_usb_debug(0); hid_set_debug(HID_DEBUG_ERRORS); break; case 2: hid_set_usb_debug(0); hid_set_debug(HID_DEBUG_ERRORS | HID_DEBUG_WARNINGS); break; case 3: hid_set_usb_debug(0); hid_set_debug(HID_DEBUG_ERRORS | HID_DEBUG_WARNINGS | HID_DEBUG_NOTICES); break; case 4: hid_set_usb_debug(0); hid_set_debug(HID_DEBUG_NOTRACES); break; case 5: hid_set_usb_debug(0); hid_set_debug(HID_DEBUG_ALL); break; default: hid_set_usb_debug(x->debug_level - 5); hid_set_debug(HID_DEBUG_ALL); break; } }
/* -------------------------------------------------------------------------- */ static void usbhid_free(t_usbhid* x) { if(x->debug_level) post("usbhid_free"); usbhid_close(x);
freebytes(x->x_read_elements,sizeof(t_int) * x->x_read_element_count); freebytes(x->x_write_elements,sizeof(t_int) * x->x_write_element_count);
if(x->debug_level) post("[usbhid] freeing instance %d",usbhid_instance_count); hid_delete_HIDInterface(&(x->x_hidinterface)); if(usbhid_instance_count <= 1) { post("[usbhid] freeing last instance"); x->x_hid_return = hid_cleanup(); if (x->x_hid_return != HID_RET_SUCCESS) error("[usbhid] hid_cleanup failed with return code %d\n", x->x_hid_return); }
usbhid_instance_count--; }
/* -------------------------------------------------------------------------- */ static void *usbhid_new(t_float f) { t_int i; HIDInterfaceMatcher matcher; t_usbhid *x = (t_usbhid *)pd_new(usbhid_class); if(x->debug_level) post("usbhid_new"); /* only display the version when the first instance is loaded */ if(!usbhid_instance_count) post("[usbhid] %d.%d, written by Hans-Christoph Steiner hans@eds.org", USBHID_MAJOR_VERSION, USBHID_MINOR_VERSION); /* 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);
/* turn off the flood of libhid debug messages by default */ hid_set_debug(HID_DEBUG_NONE); hid_set_debug_stream(stdout); hid_set_usb_debug(0); /* data init */ x->output = NULL; x->output_count = 0; for (i = 0 ; i < HID_ID_MAX ; i++) hid_id[i] = NULL; x->x_hidinterface = hid_new_HIDInterface(); matcher.vendor_id = HID_ID_MATCH_ANY; matcher.product_id = HID_ID_MATCH_ANY; matcher.matcher_fn = device_iterator; x->x_device_number = f;
/* Open the device and save settings. If there is an error, return the object * anyway, so that the inlets and outlets are created, thus not breaking the * patch. */ /* if (usbhid_open(x,f)) */ /* error("[usbhid] device %d did not open",(t_int)f); */
usbhid_instance_count++;
return (x); }
void usbhid_setup(void) { usbhid_class = class_new(gensym("usbhid"), (t_newmethod)usbhid_new, (t_method)usbhid_free, sizeof(t_usbhid), CLASS_DEFAULT, A_DEFFLOAT, NULL); /* add inlet datatype methods */ // class_addbang(usbhid_class,(t_method) usbhid_bang);
/* add inlet message methods */ class_addmethod(usbhid_class,(t_method) usbhid_print,gensym("print"),0); class_addmethod(usbhid_class,(t_method) usbhid_reset,gensym("reset"),0); class_addmethod(usbhid_class,(t_method) usbhid_refresh,gensym("refresh"),0); class_addmethod(usbhid_class,(t_method) usbhid_debug,gensym("debug"), A_DEFFLOAT,0); class_addmethod(usbhid_class,(t_method) usbhid_descriptor,gensym("descriptor"), A_GIMME,0); class_addmethod(usbhid_class,(t_method) usbhid_set,gensym("set"), A_DEFFLOAT,0); class_addmethod(usbhid_class,(t_method) usbhid_get,gensym("get"), A_DEFFLOAT,0); class_addmethod(usbhid_class,(t_method) usbhid_open,gensym("open"), A_DEFSYM,A_DEFSYM,0); class_addmethod(usbhid_class,(t_method) usbhid_close,gensym("close"),0); }
#endif /* NOT _WIN32 */
--- NEW FILE: usbhid.libs --- -lusb -lhid