From 42b8d84dc8bbf41b7dcdecf8cdc1ad0ac285cba6 Mon Sep 17 00:00:00 2001 From: Olaf Matthes Date: Mon, 4 Dec 2006 20:23:28 +0000 Subject: *** empty log message *** svn path=/trunk/externals/olafmatt/; revision=6616 --- hidin/hidin.c | 746 ----------------------------------------------------- hidin/hidin.h | 146 ----------- hidin/winNT_usb.c | 752 ------------------------------------------------------ 3 files changed, 1644 deletions(-) delete mode 100644 hidin/hidin.c delete mode 100644 hidin/hidin.h delete mode 100644 hidin/winNT_usb.c diff --git a/hidin/hidin.c b/hidin/hidin.c deleted file mode 100644 index fe9a79c..0000000 --- a/hidin/hidin.c +++ /dev/null @@ -1,746 +0,0 @@ -/* hidin.c - read in data from USB HID device */ -/* Copyright 2003 Olaf Matthes, see README for a detailed licence */ - -/* - 'hidin' is used to read in data from any HID (human interface device) connected - to the computers USB port(s). - However, it does not work with mice or keyboards ('could not open' error)! - - Needs the Windows Driver Development Kit (DDK) to compile! - - */ - -#define REQUEST_NOTHING 0 -#define REQUEST_READ 1 -#define REQUEST_QUIT 2 - -#include "m_pd.h" -#define SETSYM SETSYMBOL - -#include -#include -#include -#include -#include -#include "pthread.h" - -#include "hidin.h" - -static char *hidin_version = "hidin v1.0test2, Human Interface Device on USB, (c) 2003-2004 Olaf Matthes"; - -static t_class *hidin_class; - -typedef struct _hidin -{ - t_object x_obj; - t_outlet *x_outlet; /* outlet for received data */ - t_outlet *x_devout; /* outlet for list of devices */ - long x_interval; /* interval in ms to read */ - long *x_data; /* data read from the interface */ - long *x_prev_data; /* data we read the time bofore */ - void *x_qelem; /* qelem for outputing the results */ - long x_device; /* the HID device number we're connecting to */ - short x_elements; /* number of elements (i.e. buttons, axes...)*/ - - /* HID specific */ - t_hid_device *x_hid; /* a struct containing all the needed stuff about the HID device */ - - /* tread stuff */ - long x_requestcode; /* pending request from parent to I/O thread */ - pthread_mutex_t x_mutex; - pthread_cond_t x_requestcondition; - pthread_cond_t x_answercondition; - pthread_t x_thread; -} t_hidin; - - -/* Prototypes and short descriptions */ - -#ifndef PD -static void *hidin_output(t_hidin *x); -static void *hidin_doit(void *z); -static void hidin_tick(t_hidin *x); -static void hidin_clock_reset(t_hidin *x); -static void hidin_int(t_hidin *x, long l); -/* what/when to read */ -static void hidin_interval(t_hidin *x, long l); /* set time interval for reading ports */ -/* direct response to user */ -static void hidin_show(t_hidin *x); -static void hidin_start(t_hidin *x); -static void hidin_stop(t_hidin *x); -static void hidin_bang(t_hidin *x); -static void hidin_open(t_hidin *x, long l); -/* helper functions */ -static void hidin_alloc(t_hidin *x, short elem); -/* standard Max/MSP related stuff */ -static void *hidin_new(t_symbol *s, short argc, t_atom *argv); -static void hidin_free(t_hidin *x); -static void hidin_info(t_hidin *x, void *p, void *c); -static void hidin_assist(t_hidin *x, void *b, long m, long a, char *s); -void main(void); -#endif - - -/* ------------------- general support routines --------------------- */ - -static void thread_post(t_hidin *x, char *p) -{ - post("hidin: %s", p); -} - -/* --------------------- data I/O support stuff --------------------- */ - -/* output values using qelem */ -static void *hidin_output(t_hidin *x) -{ - int i; - static t_atom list[2]; /* output list format is: '(int) (int)' */ - long d; - - pthread_mutex_lock(&x->x_mutex); - /* check every element for new value */ - for (i = 0; i < x->x_elements; i++) - { - d = x->x_data[i]; - if (d != x->x_prev_data[i]) - { - SETFLOAT(list, (t_float)i+1); - SETFLOAT(list+1, (t_float)d); - outlet_list(x->x_outlet, NULL, 2, list); - x->x_prev_data[i] = d; - } - } - pthread_cond_signal(&x->x_requestcondition); /* request previous state again */ - pthread_mutex_unlock(&x->x_mutex); - return NULL; -} - -static void hidin_parse_input(t_hidin *x) -{ - ULONG i, j; - PUSAGE pUsage; - t_hid_data *inputData; - - unpackReport(x->x_hid->inputReportBuffer, x->x_hid->caps.InputReportByteLength, HidP_Input, - x->x_hid->inputData, x->x_hid->inputDataLength, x->x_hid->ppd); - - inputData = x->x_hid->inputData; - - for (j = 0; j < x->x_hid->inputDataLength; j++) - { - if (inputData->IsButtonData) // state of buttons changed - { - // post("Usage Page: 0x%x, Usages: ", inputData->UsagePage); - - // set all buttons to zero - for (i = 0; i < inputData->ButtonData.MaxUsageLength; i++) - x->x_data[i + x->x_hid->caps.NumberInputValueCaps] = 0; - - for (i = 0, pUsage = inputData->ButtonData.Usages; - i < inputData->ButtonData.MaxUsageLength; - i++, pUsage++) - { - if (0 == *pUsage) - { - break; // A usage of zero is a non button. - } - else - { - x->x_data[*pUsage + x->x_hid->caps.NumberInputValueCaps - 1] = 1; - } - } - } - else // values changed - { - /* post("Usage Page: 0x%x, Usage: 0x%x, Scaled: %d Value: %d", - inputData->UsagePage, - inputData->ValueData.Usage, - inputData->ValueData.ScaledValue, - inputData->ValueData.Value); */ - // x->x_data[j - x->x_hid->caps.NumberInputButtonCaps] = inputData->ValueData.ScaledValue; - x->x_data[j - x->x_hid->caps.NumberInputButtonCaps] = inputData->ValueData.Value; - } - inputData++; - } -} - -/* - * this is the actual code that reads from the file handle to the HID device. - * it's a second thread to avoid audio dropouts because it might take some time - * for the read call to complete. - */ -static void *hidin_doit(void *z) -{ - t_hidin *x = (t_hidin *)z; - int i, interval; - long bytes; - long ret; - - if (x->x_hid->event == 0) - { - x->x_hid->event = CreateEvent(NULL, TRUE, FALSE, ""); - } - - /* prepare overlapped structute */ - x->x_hid->overlapped.Offset = 0; - x->x_hid->overlapped.OffsetHigh = 0; - x->x_hid->overlapped.hEvent = x->x_hid->event; - - pthread_mutex_lock(&x->x_mutex); - while (1) - { - if (x->x_requestcode == REQUEST_NOTHING) - { - pthread_cond_signal(&x->x_answercondition); - pthread_cond_wait(&x->x_requestcondition, &x->x_mutex); - } - else if (x->x_requestcode == REQUEST_READ) - { - interval = x->x_interval; - if (x->x_device != -1) - { - pthread_mutex_unlock(&x->x_mutex); - - /* read in data from device */ - bytes = readHidOverlapped(x->x_hid); - - ret = WaitForSingleObject(x->x_hid->event, interval); - - pthread_mutex_lock(&x->x_mutex); - if (ret == WAIT_OBJECT_0) /* hey, we got signalled ! => data */ - { - hidin_parse_input(x); /* parse received data */ - clock_delay(x->x_qelem, 0); /* we don't have qelems on PD ;-( */ - /* wait for the data output to complete */ - pthread_cond_wait(&x->x_requestcondition, &x->x_mutex); - } - else /* if no data, cancel read */ - { - if (!CancelIo(x->x_hid->device) && (x->x_device != -1)) - thread_post(x, "-- error cancelling read"); - } - if (!ResetEvent(x->x_hid->event)) - thread_post(x, "-- error resetting event"); - - pthread_cond_signal(&x->x_answercondition); - } - else - { - /* if device is closed don't try to read and don't alter - the request code, stay in current state of operation */ - pthread_cond_signal(&x->x_answercondition); - pthread_cond_wait(&x->x_requestcondition, &x->x_mutex); - } - } - else if (x->x_requestcode == REQUEST_QUIT) - { - x->x_requestcode = REQUEST_NOTHING; - pthread_cond_signal(&x->x_answercondition); - break; - } - else /* error if we get here! */ - { - error("hidin: -- internal error, please report to !"); - } - } - pthread_mutex_unlock(&x->x_mutex); - return (0); -} - -/* - * set the update interval time in ms - */ -static void hidin_interval(t_hidin *x, t_floatarg l) -{ - int n = (int)l; - - pthread_mutex_lock(&x->x_mutex); - if (n >= 2) - { - x->x_interval = n; - post("hidin: >> interval: polling every %d msec", n); - } - else post("hidin: -- interval: wrong parameter value (minimum 2)"); - pthread_mutex_unlock(&x->x_mutex); -} - -/* - * print the actual config on the console window - * LATER reduce to the absolute minimum, this is just for easier debugging! - */ -static void hidin_show(t_hidin *x) -{ - pthread_mutex_lock(&x->x_mutex); - if (x->x_device == -1) - { - post("hidin: -- no open HID device"); - } - else - { - post("hidin: ****** HID device %d ******", x->x_device); - post("hidin: ** usage page: %X", x->x_hid->caps.UsagePage); - post("hidin: ** input report byte length: %d", x->x_hid->caps.InputReportByteLength); - post("hidin: ** output report byte length: %d", x->x_hid->caps.OutputReportByteLength); - post("hidin: ** feature report byte length: %d", x->x_hid->caps.FeatureReportByteLength); - post("hidin: ** number of link collection nodes: %d", x->x_hid->caps.NumberLinkCollectionNodes); - post("hidin: ** number of input button caps: %d", x->x_hid->caps.NumberInputButtonCaps); - post("hidin: ** number of inputValue caps: %d", x->x_hid->caps.NumberInputValueCaps); - post("hidin: ** number of inputData indices: %d", x->x_hid->caps.NumberInputDataIndices); - post("hidin: ** number of output button caps: %d", x->x_hid->caps.NumberOutputButtonCaps); - post("hidin: ** number of output value caps: %d", x->x_hid->caps.NumberOutputValueCaps); - post("hidin: ** number of output data indices: %d", x->x_hid->caps.NumberOutputDataIndices); - post("hidin: ** number of feature button caps: %d", x->x_hid->caps.NumberFeatureButtonCaps); - post("hidin: ** number of feature value caps: %d", x->x_hid->caps.NumberFeatureValueCaps); - post("hidin: ** number of feature data indices: %d", x->x_hid->caps.NumberFeatureDataIndices); - } - pthread_mutex_unlock(&x->x_mutex); -} - -/* - * start / stop reading - */ -static void hidin_int(t_hidin *x, t_floatarg l) -{ - pthread_mutex_lock(&x->x_mutex); - if (l) - { - x->x_requestcode = REQUEST_READ; - pthread_cond_signal(&x->x_requestcondition); - } - else - { - x->x_requestcode = REQUEST_NOTHING; - pthread_cond_signal(&x->x_requestcondition); - } - pthread_mutex_unlock(&x->x_mutex); -} - - /* start reading */ -static void hidin_start(t_hidin *x) -{ - pthread_mutex_lock(&x->x_mutex); - x->x_requestcode = REQUEST_READ; - pthread_cond_signal(&x->x_requestcondition); - pthread_mutex_unlock(&x->x_mutex); -} - - /* stop reading */ -static void hidin_stop(t_hidin *x) -{ - pthread_mutex_lock(&x->x_mutex); - x->x_requestcode = REQUEST_NOTHING; - pthread_cond_signal(&x->x_requestcondition); - pthread_mutex_unlock(&x->x_mutex); -} - - /* get list of devices */ -static void hidin_bang(t_hidin *x) -{ - t_atom list[2]; - int numdev, i; - - pthread_mutex_lock(&x->x_mutex); - // check for connected devices - numdev = findHidDevices(); - post("hidin: ** found %d devices on your system", numdev); - - SETFLOAT(list, -1); - SETSYM(list+1, gensym("None")); - outlet_list(x->x_devout, NULL, 2, list); - for (i = 0; i < numdev; i++) - { - SETFLOAT(list, i + 1); - SETSYM(list+1, findDeviceName(i)); - outlet_list(x->x_devout, NULL, 2, list); - } - pthread_mutex_unlock(&x->x_mutex); -} - -/* - * allocate memory for output data (according to number of elements) - */ -static void hidin_alloc(t_hidin *x, short elem) -{ - int i; - - if (x->x_device != -1) - { - // free memory in case we already have some - if (x->x_data && x->x_elements > 0) - { - freebytes(x->x_data, (short)(x->x_elements * sizeof(long))); - } - if (x->x_prev_data && x->x_elements > 0) - { - freebytes(x->x_prev_data, (short)(x->x_elements * sizeof(long))); - } - - if (elem > 0) - { - // allocate memory to new size - x->x_data = (long *)getbytes((short)(elem * sizeof(long))); - x->x_prev_data = (long *)getbytes((short)(elem * sizeof(long))); - if (!x->x_data || !x->x_prev_data) - { - post("hidin: -- out of memory"); - x->x_elements = 0; - return; - } - // set newly allocated memory to zero - for (i = 0; i < elem; i++) - { - x->x_data[i] = 0; - x->x_prev_data[i] = 0; - } - } - x->x_elements = elem; - } -} - -/* - * init the device data structures - */ -static void hidin_initdevice(t_hidin *x) -{ - int i; - short numElements; - short numValues; - short numCaps; - PHIDP_BUTTON_CAPS buttonCaps; - PHIDP_VALUE_CAPS valueCaps; - USAGE usage; - t_hid_data *data; - - // get device info and show some printout - getDeviceInfo(x->x_hid->device); - - // read in device's capabilities and allocate memory accordingly - getDeviceCapabilities(x->x_hid); - - // allocate memory for input field - x->x_hid->inputReportBuffer = (char*)getbytes((short)(x->x_hid->caps.InputReportByteLength*sizeof(char))); - - // allocate memory for input info - x->x_hid->inputButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS)getbytes((short)(x->x_hid->caps.NumberInputButtonCaps * sizeof(HIDP_BUTTON_CAPS))); - x->x_hid->inputValueCaps = valueCaps = (PHIDP_VALUE_CAPS)getbytes((short)(x->x_hid->caps.NumberInputValueCaps * sizeof(HIDP_VALUE_CAPS))); - - // - // Have the HidP_X functions fill in the capability structure arrays. - // - - numCaps = x->x_hid->caps.NumberInputButtonCaps; - - HidP_GetButtonCaps (HidP_Input, - buttonCaps, - &numCaps, - x->x_hid->ppd); - - numCaps = x->x_hid->caps.NumberInputValueCaps; - - HidP_GetValueCaps (HidP_Input, - valueCaps, - &numCaps, - x->x_hid->ppd); - // - // Depending on the device, some value caps structures may represent more - // than one value. (A range). In the interest of being verbose, over - // efficient, we will expand these so that we have one and only one - // struct _HID_DATA for each value. - // - // To do this we need to count up the total number of values are listed - // in the value caps structure. For each element in the array we test - // for range if it is a range then UsageMax and UsageMin describe the - // usages for this range INCLUSIVE. - // - - numValues = 0; - for (i = 0; i < x->x_hid->caps.NumberInputValueCaps; i++, valueCaps++) - { - if (valueCaps->IsRange) - { - numValues += valueCaps->Range.UsageMax - valueCaps->Range.UsageMin + 1; - } - else - { - numValues++; - } - } - valueCaps = x->x_hid->inputValueCaps; - - numElements = x->x_hid->caps.NumberInputValueCaps + - x->x_hid->caps.NumberInputButtonCaps * x->x_hid->caps.NumberInputDataIndices; - - post("hidin: >> device has %i input elements", numElements); - hidin_alloc(x, (short)(numElements)); // allocate memory for all these elements - - x->x_hid->inputDataLength = numValues + x->x_hid->caps.NumberInputButtonCaps; - - x->x_hid->inputData = data = (t_hid_data *)getbytes((short)(x->x_hid->inputDataLength * sizeof(t_hid_data))); - - // - // Fill in the button data - // - - for (i = 0; - i < x->x_hid->caps.NumberInputButtonCaps; - i++, data++, buttonCaps++) - { - data->IsButtonData = TRUE; - data->Status = HIDP_STATUS_SUCCESS; - data->UsagePage = buttonCaps->UsagePage; - if (buttonCaps->IsRange) - { - data->ButtonData.UsageMin = buttonCaps -> Range.UsageMin; - data->ButtonData.UsageMax = buttonCaps -> Range.UsageMax; - } - else - { - data -> ButtonData.UsageMin = data -> ButtonData.UsageMax = buttonCaps -> NotRange.Usage; - } - - data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength( - HidP_Input, - buttonCaps->UsagePage, - x->x_hid->ppd); - data->ButtonData.Usages = (PUSAGE) - calloc (data->ButtonData.MaxUsageLength, sizeof (USAGE)); - - data->ReportID = buttonCaps -> ReportID; - } - - // - // Fill in the value data - // - - for (i = 0; i < numValues; i++, valueCaps++) - { - if (valueCaps->IsRange) - { - for (usage = valueCaps->Range.UsageMin; - usage <= valueCaps->Range.UsageMax; - usage++) - { - data->IsButtonData = FALSE; - data->Status = HIDP_STATUS_SUCCESS; - data->UsagePage = valueCaps->UsagePage; - data->ValueData.Usage = usage; - data->ReportID = valueCaps->ReportID; - data++; - } - } - else - { - data->IsButtonData = FALSE; - data->Status = HIDP_STATUS_SUCCESS; - data->UsagePage = valueCaps->UsagePage; - data->ValueData.Usage = valueCaps->NotRange.Usage; - data->ReportID = valueCaps->ReportID; - data++; - } - } - - // getFeature(x->x_hid); -} - -static void hidin_doopen(t_hidin *x, long deviceID) -{ - short elements; // number of elements of HID device - long oldrequest; - - pthread_mutex_lock(&x->x_mutex); - oldrequest = x->x_requestcode; - x->x_requestcode = REQUEST_NOTHING; - pthread_cond_signal(&x->x_requestcondition); - pthread_cond_wait(&x->x_answercondition, &x->x_mutex); - - // close old device if any - if (x->x_device != -1) - { - CloseHandle(x->x_hid->device); - - // free allocated memory - freebytes(x->x_hid->inputData, (short)(x->x_hid->inputDataLength * sizeof(t_hid_data))); - freebytes(x->x_hid->inputButtonCaps, (short)(x->x_hid->caps.NumberInputButtonCaps * sizeof(HIDP_BUTTON_CAPS))); - freebytes(x->x_hid->inputValueCaps, (short)(x->x_hid->caps.NumberInputValueCaps * sizeof(HIDP_VALUE_CAPS))); - freebytes(x->x_hid->inputReportBuffer, (short)(x->x_hid->caps.InputReportByteLength * sizeof(char))); - x->x_hid->caps.InputReportByteLength = 0; - } - - if (deviceID != -1) - { - // open new device - x->x_hid->device = connectDeviceNumber(deviceID); - - if (x->x_hid->device != INVALID_HANDLE_VALUE) - { - x->x_device = deviceID; - hidin_initdevice(x); - } - else // open failed... - { - hidin_alloc(x, 0); // free data memory - x->x_device = -1; - } - } - else - { - hidin_alloc(x, 0); // free data memory - post("hidin: << device closed"); - x->x_device = -1; - } - - x->x_requestcode = oldrequest; /* set back to old requestcode */ - pthread_cond_signal(&x->x_requestcondition); /* go on again */ - pthread_mutex_unlock(&x->x_mutex); -} - -/* - * select & open device to use - */ -static void hidin_open(t_hidin *x, t_floatarg l) -{ - long device = (long)l - 1; /* get new internal device number */ - hidin_doopen(x, device); -} - -/* - * close open device - */ -static void hidin_close(t_hidin *x) -{ - if (x->x_device != -1) - hidin_doopen(x, -1); -} - -/* - * the object's new function - */ -static void *hidin_new(t_symbol *s, short argc, t_atom *argv) -{ - int i, k, n; - int deviceID, intv; - - t_hidin *x; - - deviceID = -1; /* default HID device number: none */ - intv = 10; /* read every 10 ms */ - - if (argc >= 1 && argv->a_type == A_FLOAT) /* just one argument (long): device ID */ - { - deviceID = (int)(argv[0].a_w.w_float - 1); - if (argc >= 2 && argv[1].a_type == A_FLOAT) /* second argument (long): interval */ - { - intv = (int)argv[1].a_w.w_float; - } - } - - x = (t_hidin*)pd_new(hidin_class); - - // zero out the struct, to be careful - if (x) - { - for (i = sizeof(t_object); i < sizeof(t_hidin); i++) - ((char*)x)[i] = 0; - } - - x->x_outlet = outlet_new(&x->x_obj, gensym("list")); // outputs received data - x->x_devout = outlet_new(&x->x_obj, gensym("list")); // outputs list of devices - - x->x_qelem = clock_new(x, (t_method)hidin_output); - - pthread_mutex_init(&x->x_mutex, 0); - pthread_cond_init(&x->x_requestcondition, 0); - pthread_cond_init(&x->x_answercondition, 0); - - x->x_requestcode = REQUEST_NOTHING; - - x->x_interval = intv; - x->x_device = -1; - x->x_elements = 0; - x->x_data = NULL; - x->x_prev_data = NULL; - - // allocate memory for the t_hid_device struct - x->x_hid = (t_hid_device *)getbytes(sizeof(t_hid_device)); - - // create I/O thread - pthread_create(&x->x_thread, 0, hidin_doit, x); - - if (deviceID != -1) - hidin_doopen(x, deviceID); - - return (x); -} - -static void hidin_free(t_hidin *x) -{ - void *threadrtn; - t_atom atom; - - // close the HID device - hidin_doopen(x, -1); - - // stop IO thread - pthread_mutex_lock(&x->x_mutex); - x->x_requestcode = REQUEST_QUIT; - pthread_cond_signal(&x->x_requestcondition); - startpost("hidin: >> stopping HID I/O thread..."); - SETSYMBOL(&atom, gensym("signalling...")); - while (x->x_requestcode != REQUEST_NOTHING) - { - postatom(1, &atom); - pthread_cond_signal(&x->x_requestcondition); - pthread_cond_wait(&x->x_answercondition, &x->x_mutex); - } - pthread_mutex_unlock(&x->x_mutex); - if (pthread_join(x->x_thread, &threadrtn)) - error("shoutcast_free: join failed"); - SETSYMBOL(&atom, gensym("done.")); - postatom(1, &atom); - endpost(); - - freebytes(x->x_hid, sizeof(t_hid_device)); - - clock_free(x->x_qelem); - - pthread_cond_destroy(&x->x_requestcondition); - pthread_cond_destroy(&x->x_answercondition); - pthread_mutex_destroy(&x->x_mutex); -} - -/* - * the object's info function - */ -static void hidin_info(t_hidin *x) -{ - post(hidin_version); - pthread_mutex_lock(&x->x_mutex); - if (x->x_device != -1) - { - post("hidin: ** using device #%d: \"%s\"", x->x_device + 1, - findDeviceName(x->x_device)->s_name); - post("hidin: ** device has %d values and %d buttons", - x->x_hid->caps.NumberInputValueCaps, - x->x_hid->caps.NumberInputButtonCaps * x->x_hid->caps.NumberInputDataIndices); - // getDeviceInfo(x->x_hid->device); - } - else post("hidin: -- no open device"); - pthread_mutex_unlock(&x->x_mutex); -} - -void hidin_setup(void) -{ - hidin_class = class_new(gensym("hidin"),(t_newmethod)hidin_new, (t_method)hidin_free, - sizeof(t_hidin), 0, A_GIMME, 0); - class_addbang(hidin_class, (t_method)hidin_bang); - class_addfloat(hidin_class, (t_method)hidin_int); - class_addmethod(hidin_class, (t_method)hidin_start, gensym("start"), 0); - class_addmethod(hidin_class, (t_method)hidin_stop, gensym("stop"), 0); - class_addmethod(hidin_class, (t_method)hidin_show, gensym("show"), 0); - class_addmethod(hidin_class, (t_method)hidin_info, gensym("print"), 0); - class_addmethod(hidin_class, (t_method)hidin_open, gensym("open"), A_FLOAT, 0); - class_addmethod(hidin_class, (t_method)hidin_close, gensym("close"), 0); - class_addmethod(hidin_class, (t_method)hidin_interval, gensym("interval"), A_FLOAT, 0); - post(hidin_version); -} - diff --git a/hidin/hidin.h b/hidin/hidin.h deleted file mode 100644 index 5e88451..0000000 --- a/hidin/hidin.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - - hidin.h - headers and declarationd for the 'hidin' external - -*/ - -#ifndef hidin_H -#define hidin_H - -#include -#include -#include -#include -#include -#ifdef _MSC_VER -#include "hidusage.h" -#include "hidsdi.h" -#else -#include -#include -#endif - -// -// A structure to hold the steady state data received from the hid device. -// Each time a read packet is received we fill in this structure. -// Each time we wish to write to a hid device we fill in this structure. -// This structure is here only for convenience. Most real applications will -// have a more efficient way of moving the hid data to the read, write, and -// feature routines. -// -typedef struct _hid_data -{ - BOOLEAN IsButtonData; - UCHAR Reserved; - USAGE UsagePage; // The usage page for which we are looking. - ULONG Status; // The last status returned from the accessor function - // when updating this field. - ULONG ReportID; // ReportID for this given data structure - BOOLEAN IsDataSet; // Variable to track whether a given data structure - // has already been added to a report structure - - union { - struct { - ULONG UsageMin; // Variables to track the usage minimum and max - ULONG UsageMax; // If equal, then only a single usage - ULONG MaxUsageLength; // Usages buffer length. - PUSAGE Usages; // list of usages (buttons ``down'' on the device. - - } ButtonData; - struct { - USAGE Usage; // The usage describing this value; - USHORT Reserved; - - ULONG Value; - LONG ScaledValue; - } ValueData; - }; -} t_hid_data; - -typedef struct _hid_device -{ - PCHAR devicePath; - HANDLE device; // A file handle to the hid device. - HANDLE event; - OVERLAPPED overlapped; - - BOOL openedForRead; - BOOL openedForWrite; - BOOL openedOverlapped; - BOOL openedExclusive; - - PHIDP_PREPARSED_DATA ppd; // The opaque parser info describing this device - HIDP_CAPS caps; // The Capabilities of this hid device. - HIDD_ATTRIBUTES attributes; - char *inputReportBuffer; - t_hid_data *inputData; // array of hid data structures - ULONG inputDataLength; // Num elements in this array. - PHIDP_BUTTON_CAPS inputButtonCaps; - PHIDP_VALUE_CAPS inputValueCaps; - - char *outputReportBuffer; - t_hid_data *outputData; - ULONG outputDataLength; - PHIDP_BUTTON_CAPS outputButtonCaps; - PHIDP_VALUE_CAPS outputValueCaps; - - char *featureReportBuffer; - t_hid_data *featureData; - ULONG featureDataLength; - PHIDP_BUTTON_CAPS featureButtonCaps; - PHIDP_VALUE_CAPS featureValueCaps; -} t_hid_device; - - -/* - * displays the vendor and product ID and the version - * number for the given device handle - */ -void getDeviceInfo(HANDLE deviceHandle); - -/* - * find number of attached HID devices - */ -int findHidDevices(); - -/* - * find name of attached HID devices - */ -t_symbol *findDeviceName(DWORD deviceID); - -/* - * connects to the hid device specified through a number - * returns a handle to the device (x->x_hid.device) - */ -HANDLE connectDeviceNumber(DWORD i); - -/* Connects to the USB HID described by the combination of vendor id, product id - If the attribute is null, it will connect to first device satisfying the remaining - attributes. */ -HANDLE connectDeviceName(DWORD *vendorID, DWORD *productID, DWORD *versionNumber); - -/* - * get hid device capabilities (and display them) - * also instantiates the x->x_hid.caps field and - * allocates the memory we'll need to use this device - */ -void getDeviceCapabilities(t_hid_device *hid); - - - -/* - * read input data from hid device and display them - */ -int readHid(t_hid_device *hidDevice); - -int readHidOverlapped(t_hid_device *hidDevice); - -BOOLEAN getFeature(t_hid_device *HidDevice); - -BOOLEAN unpackReport(PCHAR ReportBuffer, USHORT ReportBufferLength, HIDP_REPORT_TYPE ReportType, - t_hid_data *Data, ULONG DataLength, PHIDP_PREPARSED_DATA Ppd); - -BOOLEAN packReport(PCHAR ReportBuffer, USHORT ReportBufferLength, HIDP_REPORT_TYPE ReportType, - t_hid_data *Data, ULONG DataLength, PHIDP_PREPARSED_DATA Ppd); - -#endif // hidin_H diff --git a/hidin/winNT_usb.c b/hidin/winNT_usb.c deleted file mode 100644 index 0e361b7..0000000 --- a/hidin/winNT_usb.c +++ /dev/null @@ -1,752 +0,0 @@ -/* - hidin USB HID support stuff for Windows 2000 / XP - - Written by Olaf Matthes - - This file contains the implementation for connecting to USB HID - (Human Interface Device) devices. It provides several functions - to open devices and to query information and capabilities. - -*/ - -#ifdef PD -#include "m_pd.h" /* we need this because we want to print() to the PD console */ -#include -#else -#include "ext.h" /* we need this because we want to print() to the Max window */ -#endif -#include "hidin.h" - - -/* - * get information for a given device (HANDLE) - * - */ - -void getDeviceInfo(HANDLE deviceHandle) -{ - HIDD_ATTRIBUTES deviceAttributes; - PWCHAR deviceName; - ULONG length = 256; - - if(deviceHandle == INVALID_HANDLE_VALUE) - { - post("hidin: -- couldn't get device info due to an invalid handle"); - return; - } - - if (!HidD_GetAttributes (deviceHandle, &deviceAttributes)) - { - post("hidin: -- failed to get attributes"); - return; - } - else - { - // post("hidin: ** VendorID: 0x%x", deviceAttributes.VendorID); - // post("hidin: ** ProductID: 0x%x", deviceAttributes.ProductID); - // post("hidin: ** VersionNumber: 0x%x", deviceAttributes.VersionNumber); - } - - deviceName = (PWCHAR)getbytes((short)(length)); - if(!HidD_GetProductString (deviceHandle, deviceName, length)) - { - freebytes(deviceName, (short)(length)); - return; - } - else - { - char name[256]; - int i = 0; - wcstombs(name, deviceName, length); - post("hidin: >> opening device: \"%s\"", name); - freebytes(deviceName, (short)(length)); - } - return; -} - -/* - * find name of attached HID devices - */ -t_symbol *findDeviceName(DWORD deviceID) -{ - HANDLE deviceHandle; - PWCHAR deviceName; - ULONG length = 256; - char name[256]; // this will be the return value - int i = 0; - - deviceHandle = connectDeviceNumber(deviceID); - - if(deviceHandle != INVALID_HANDLE_VALUE) - { - deviceName = (PWCHAR)getbytes((short)(length)); - if(!HidD_GetProductString (deviceHandle, deviceName, length)) - { - freebytes(deviceName, (short)(length)); - sprintf(name, "Unknown (Device #%d)", deviceID + 1); - return gensym(name); - } - else - { - wcstombs(name, deviceName, length); - freebytes(deviceName, (short)(length)); - } - - CloseHandle(deviceHandle); - - return gensym(name); - } - return gensym("Unsupported Device"); -} - -/* - * find number of attached HID devices - */ -int findHidDevices() -{ - HDEVINFO hardwareDeviceInfo; - SP_INTERFACE_DEVICE_DATA deviceInfoData; - ULONG i; - BOOLEAN done; - GUID hidGuid; - PSP_INTERFACE_DEVICE_DETAIL_DATA functionClassDeviceData = NULL; - ULONG predictedLength = 0; - ULONG requiredLength = 0; - ULONG NumberDevices = 0; - - HidD_GetHidGuid (&hidGuid); - - // - // Open a handle to the plug and play dev node. - // - hardwareDeviceInfo = SetupDiGetClassDevs ( &hidGuid, - NULL, // Define no enumerator (global) - NULL, // Define no - (DIGCF_PRESENT | // Only Devices present - DIGCF_DEVICEINTERFACE)); // Function class devices. - - // - // Take a wild guess to start - // - - NumberDevices = 4; - done = FALSE; - deviceInfoData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA); - - i=0; - while (!done) - { - NumberDevices *= 2; - - for (; i < NumberDevices; i++) - { - if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo, - 0, // No care about specific PDOs - &hidGuid, - i, - &deviceInfoData)) - { - // - // allocate a function class device data structure to receive the - // goods about this particular device. - // - - SetupDiGetDeviceInterfaceDetail ( - hardwareDeviceInfo, - &deviceInfoData, - NULL, // probing so no output buffer yet - 0, // probing so output buffer length of zero - &requiredLength, - NULL); // not interested in the specific dev-node - - - predictedLength = requiredLength; - - functionClassDeviceData = malloc (predictedLength); - if (functionClassDeviceData) - { - functionClassDeviceData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA); - } - else - { - SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); - return 0; - } - - // - // Retrieve the information from Plug and Play. - // - - if (! SetupDiGetDeviceInterfaceDetail ( - hardwareDeviceInfo, - &deviceInfoData, - functionClassDeviceData, - predictedLength, - &requiredLength, - NULL)) - { - SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); - return 0; - } - // - // get name of device - // - // HidDevices[i] = getbytes(1024 * sizeof(char)); - } - else - { - if (ERROR_NO_MORE_ITEMS == GetLastError()) - { - done = TRUE; - break; - } - } - } - } - - SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); - - return (i); // return number of devices -} - - -/* - * connect to Ith USB device (count starting with 0) - */ - -HANDLE connectDeviceNumber(DWORD deviceIndex) -{ - GUID hidGUID; - HDEVINFO hardwareDeviceInfoSet; - SP_DEVICE_INTERFACE_DATA deviceInterfaceData; - PSP_INTERFACE_DEVICE_DETAIL_DATA deviceDetail; - ULONG requiredSize; - HANDLE deviceHandle = INVALID_HANDLE_VALUE; - DWORD result; - - //Get the HID GUID value - used as mask to get list of devices - HidD_GetHidGuid (&hidGUID); - - //Get a list of devices matching the criteria (hid interface, present) - hardwareDeviceInfoSet = SetupDiGetClassDevs (&hidGUID, - NULL, // Define no enumerator (global) - NULL, // Define no - (DIGCF_PRESENT | // Only Devices present - DIGCF_DEVICEINTERFACE)); // Function class devices. - - deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); - - //Go through the list and get the interface data - result = SetupDiEnumDeviceInterfaces (hardwareDeviceInfoSet, - NULL, //infoData, - &hidGUID, //interfaceClassGuid, - deviceIndex, - &deviceInterfaceData); - - /* Failed to get a device - possibly the index is larger than the number of devices */ - if (result == FALSE) - { - SetupDiDestroyDeviceInfoList (hardwareDeviceInfoSet); - post("hidin: -- failed to get specified device number"); - return INVALID_HANDLE_VALUE; - } - - //Get the details with null values to get the required size of the buffer - SetupDiGetDeviceInterfaceDetail (hardwareDeviceInfoSet, - &deviceInterfaceData, - NULL, //interfaceDetail, - 0, //interfaceDetailSize, - &requiredSize, - 0); //infoData)) - - //Allocate the buffer - deviceDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(requiredSize); - deviceDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); - - //Fill the buffer with the device details - if (!SetupDiGetDeviceInterfaceDetail (hardwareDeviceInfoSet, - &deviceInterfaceData, - deviceDetail, - requiredSize, - &requiredSize, - NULL)) - { - SetupDiDestroyDeviceInfoList (hardwareDeviceInfoSet); - free (deviceDetail); - post("hidin: -- failed to get device info"); - return INVALID_HANDLE_VALUE; - } - -#if 1 - //Open file on the device (read only) - deviceHandle = CreateFile - (deviceDetail->DevicePath, - GENERIC_READ, - FILE_SHARE_READ|FILE_SHARE_WRITE, - (LPSECURITY_ATTRIBUTES)NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); -#else - //Open file on the device (read & write) - deviceHandle = CreateFile - (deviceDetail->DevicePath, - GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, - (LPSECURITY_ATTRIBUTES)NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, // was 0 - NULL); -#endif - - if(deviceHandle == INVALID_HANDLE_VALUE) - { - int err = GetLastError(); - LPVOID lpMsgBuf; - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); - post("hidin: -- could not get device #%i: %s", deviceIndex + 1, (LPCTSTR)lpMsgBuf); - if(err == ERROR_ACCESS_DENIED) - post("hidin: -- can not read from mouse and keyboard"); - LocalFree(lpMsgBuf); - } - - SetupDiDestroyDeviceInfoList (hardwareDeviceInfoSet); - free (deviceDetail); - return deviceHandle; -} - -/* - * connect to USB device specified through VendorID, ProductID and VersionNumber - * - */ - -HANDLE connectDeviceName(DWORD *vendorID, DWORD *productID, DWORD *versionNumber) -{ - HANDLE deviceHandle = INVALID_HANDLE_VALUE; - DWORD index = 0; - HIDD_ATTRIBUTES deviceAttributes; - BOOL matched = FALSE; - - while (!matched && (deviceHandle = connectDeviceNumber(index)) != INVALID_HANDLE_VALUE) - { - if (!HidD_GetAttributes (deviceHandle, &deviceAttributes)) - return INVALID_HANDLE_VALUE; - - if ((vendorID == 0 || deviceAttributes.VendorID == *vendorID) && - (productID == 0 || deviceAttributes.ProductID == *productID) && - (versionNumber == 0 || deviceAttributes.VersionNumber == *versionNumber)) - return deviceHandle; /* matched */ - - CloseHandle (deviceHandle); /* not a match - close and try again */ - - index++; - } - - return INVALID_HANDLE_VALUE; -} - - -/* - * get device capabilities - * - */ -void getDeviceCapabilities(t_hid_device *hid) -{ - // Get the Capabilities structure for the device. - PHIDP_PREPARSED_DATA preparsedData; - HIDP_CAPS capabilities; - - if(hid->device == INVALID_HANDLE_VALUE) - { - post("hidin: -- couldn't get device capabilities due to an invalid handle"); - return; - } - - /* - API function: HidD_GetPreparsedData - Returns: a pointer to a buffer containing the information about the device's capabilities. - Requires: A handle returned by CreateFile. - There's no need to access the buffer directly, - but HidP_GetCaps and other API functions require a pointer to the buffer. - */ - - HidD_GetPreparsedData(hid->device, &preparsedData); - - /* get the device attributes */ - // HidD_GetAttributes (hid->device, &hid->attributes); - - /* - API function: HidP_GetCaps - Learn the device's capabilities. - For standard devices such as joysticks, you can find out the specific - capabilities of the device. - For a custom device, the software will probably know what the device is capable of, - and the call only verifies the information. - Requires: the pointer to the buffer returned by HidD_GetPreparsedData. - Returns: a Capabilities structure containing the information. - */ - - HidP_GetCaps(preparsedData, &capabilities); - - // Display the capabilities - - hid->caps = capabilities; - hid->ppd = preparsedData; - // No need for PreparsedData any more, so free the memory it's using. - // HidD_FreePreparsedData(preparsedData); -} - -/* - * Given a struct _hid_device, obtain a read report and unpack the values - * into the InputData array. - */ -int readHid(t_hid_device *hidDevice) -{ - long value = 0, ret; - long bytesRead; - - if(!ReadFile(hidDevice->device, - hidDevice->inputReportBuffer, - hidDevice->caps.InputReportByteLength, - &bytesRead, - NULL)) - { - int err = GetLastError(); - LPVOID lpMsgBuf; - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); - post("hidin: -- could not read from device: %s", (LPCTSTR)lpMsgBuf); - LocalFree(lpMsgBuf); - return 0; - } - // we need: bytesRead == hidDevice->caps.InputReportByteLength - - return bytesRead; -} - -/* - * Given a struct _hid_device, obtain a read report and unpack the values - * into the InputData array. - */ -int readHidOverlapped(t_hid_device *hidDevice) -{ - long value = 0, ret; - long bytesRead; - - if(!ReadFile(hidDevice->device, - hidDevice->inputReportBuffer, - hidDevice->caps.InputReportByteLength, - &bytesRead, - (LPOVERLAPPED) &hidDevice->overlapped)) - { - return 0; - } - return bytesRead; -} - - - -BOOLEAN getFeature (t_hid_device *HidDevice) -/*++ -RoutineDescription: - Given a struct _HID_DEVICE, fill in the feature data structures with - all features on the device. May issue multiple HidD_GetFeature() calls to - deal with multiple report IDs. ---*/ -{ - ULONG Index; - t_hid_data *pData; - BOOLEAN FeatureStatus; - BOOLEAN Status; - - /* - // As with writing data, the IsDataSet value in all the structures should be - // set to FALSE to indicate that the value has yet to have been set - */ - - pData = HidDevice->featureData; - - for (Index = 0; Index < HidDevice->featureDataLength; Index++, pData++) - { - pData->IsDataSet = FALSE; - } - - /* - // Next, each structure in the HID_DATA buffer is filled in with a value - // that is retrieved from one or more calls to HidD_GetFeature. The - // number of calls is equal to the number of reportIDs on the device - */ - - Status = TRUE; - pData = HidDevice->featureData; - - for (Index = 0; Index < HidDevice->featureDataLength; Index++, pData++) - { - /* - // If a value has yet to have been set for this structure, build a report - // buffer with its report ID as the first byte of the buffer and pass - // it in the HidD_GetFeature call. Specifying the report ID in the - // first specifies which report is actually retrieved from the device. - // The rest of the buffer should be zeroed before the call - */ - - if (!pData->IsDataSet) - { - memset(HidDevice->featureReportBuffer, 0x00, HidDevice->caps.FeatureReportByteLength); - - HidDevice->featureReportBuffer[0] = (UCHAR) pData -> ReportID; - - FeatureStatus = HidD_GetFeature (HidDevice->device, - HidDevice->featureReportBuffer, - HidDevice->caps.FeatureReportByteLength); - - /* - // If the return value is TRUE, scan through the rest of the HID_DATA - // structures and fill whatever values we can from this report - */ - - - if (FeatureStatus) - { - FeatureStatus = unpackReport ( HidDevice->featureReportBuffer, - HidDevice->caps.FeatureReportByteLength, - HidP_Feature, - HidDevice->featureData, - HidDevice->featureDataLength, - HidDevice->ppd); - } - - Status = Status && FeatureStatus; - } - } - - return (Status); -} - - -BOOLEAN -unpackReport ( - PCHAR ReportBuffer, - USHORT ReportBufferLength, - HIDP_REPORT_TYPE ReportType, - t_hid_data *Data, - ULONG DataLength, - PHIDP_PREPARSED_DATA Ppd -) -/*++ -Routine Description: - Given ReportBuffer representing a report from a HID device where the first - byte of the buffer is the report ID for the report, extract all the HID_DATA - in the Data list from the given report. ---*/ -{ - ULONG numUsages; // Number of usages returned from GetUsages. - ULONG i; - UCHAR reportID; - ULONG Index; - ULONG nextUsage; - - reportID = ReportBuffer[0]; - - for (i = 0; i < DataLength; i++, Data++) - { - if (reportID == Data->ReportID) - { - if (Data->IsButtonData) - { - numUsages = Data->ButtonData.MaxUsageLength; - - Data->Status = HidP_GetUsages (ReportType, - Data->UsagePage, - 0, // All collections - Data->ButtonData.Usages, - &numUsages, - Ppd, - ReportBuffer, - ReportBufferLength); - - - // - // Get usages writes the list of usages into the buffer - // Data->ButtonData.Usages newUsage is set to the number of usages - // written into this array. - // A usage cannot not be defined as zero, so we'll mark a zero - // following the list of usages to indicate the end of the list of - // usages - // - // NOTE: One anomaly of the GetUsages function is the lack of ability - // to distinguish the data for one ButtonCaps from another - // if two different caps structures have the same UsagePage - // For instance: - // Caps1 has UsagePage 07 and UsageRange of 0x00 - 0x167 - // Caps2 has UsagePage 07 and UsageRange of 0xe0 - 0xe7 - // - // However, calling GetUsages for each of the data structs - // will return the same list of usages. It is the - // responsibility of the caller to set in the HID_DEVICE - // structure which usages actually are valid for the - // that structure. - // - - /* - // Search through the usage list and remove those that - // correspond to usages outside the define ranged for this - // data structure. - */ - - for (Index = 0, nextUsage = 0; Index < numUsages; Index++) - { - if (Data->ButtonData.UsageMin <= Data->ButtonData.Usages[Index] && - Data -> ButtonData.Usages[Index] <= Data->ButtonData.UsageMax) - { - Data->ButtonData.Usages[nextUsage++] = Data->ButtonData.Usages[Index]; - - } - } - - if (nextUsage < Data -> ButtonData.MaxUsageLength) - { - Data->ButtonData.Usages[nextUsage] = 0; - } - } - else - { - Data->Status = HidP_GetUsageValue ( - ReportType, - Data->UsagePage, - 0, // All Collections. - Data->ValueData.Usage, - &Data->ValueData.Value, - Ppd, - ReportBuffer, - ReportBufferLength); - - Data->Status = HidP_GetScaledUsageValue ( - ReportType, - Data->UsagePage, - 0, // All Collections. - Data->ValueData.Usage, - &Data->ValueData.ScaledValue, - Ppd, - ReportBuffer, - ReportBufferLength); - } - Data->IsDataSet = TRUE; - } - } - return (TRUE); -} - - -BOOLEAN -packReport ( - PCHAR ReportBuffer, - USHORT ReportBufferLength, - HIDP_REPORT_TYPE ReportType, - t_hid_data *Data, - ULONG DataLength, - PHIDP_PREPARSED_DATA Ppd - ) -/*++ -Routine Description: - This routine takes in a list of HID_DATA structures (DATA) and builds - in ReportBuffer the given report for all data values in the list that - correspond to the report ID of the first item in the list. - - For every data structure in the list that has the same report ID as the first - item in the list will be set in the report. Every data item that is - set will also have it's IsDataSet field marked with TRUE. - - A return value of FALSE indicates an unexpected error occurred when setting - a given data value. The caller should expect that assume that no values - within the given data structure were set. - - A return value of TRUE indicates that all data values for the given report - ID were set without error. ---*/ -{ - ULONG numUsages; // Number of usages to set for a given report. - ULONG i; - ULONG CurrReportID; - - /* - // All report buffers that are initially sent need to be zero'd out - */ - - memset (ReportBuffer, (UCHAR) 0, ReportBufferLength); - - /* - // Go through the data structures and set all the values that correspond to - // the CurrReportID which is obtained from the first data structure - // in the list - */ - - CurrReportID = Data -> ReportID; - - for (i = 0; i < DataLength; i++, Data++) - { - /* - // There are two different ways to determine if we set the current data - // structure: - // 1) Store the report ID were using and only attempt to set those - // data structures that correspond to the given report ID. This - // example shows this implementation. - // - // 2) Attempt to set all of the data structures and look for the - // returned status value of HIDP_STATUS_INVALID_REPORT_ID. This - // error code indicates that the given usage exists but has a - // different report ID than the report ID in the current report - // buffer - */ - - if (Data -> ReportID == CurrReportID) - { - if (Data->IsButtonData) - { - numUsages = Data->ButtonData.MaxUsageLength; - Data->Status = HidP_SetUsages (ReportType, - Data->UsagePage, - 0, // All collections - Data->ButtonData.Usages, - &numUsages, - Ppd, - ReportBuffer, - ReportBufferLength); - } - else - { - Data->Status = HidP_SetUsageValue (ReportType, - Data->UsagePage, - 0, // All Collections. - Data->ValueData.Usage, - Data->ValueData.Value, - Ppd, - ReportBuffer, - ReportBufferLength); - } - - if (HIDP_STATUS_SUCCESS != Data->Status) - { - return FALSE; - } - } - } - - /* - // At this point, all data structures that have the same ReportID as the - // first one will have been set in the given report. Time to loop - // through the structure again and mark all of those data structures as - // having been set. - */ - - for (i = 0; i < DataLength; i++, Data++) - { - if (CurrReportID == Data -> ReportID) - { - Data -> IsDataSet = TRUE; - } - } - return (TRUE); -} - -- cgit v1.2.1