aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlaf Matthes <olafmatt@users.sourceforge.net>2006-12-04 20:23:28 +0000
committerOlaf Matthes <olafmatt@users.sourceforge.net>2006-12-04 20:23:28 +0000
commit42b8d84dc8bbf41b7dcdecf8cdc1ad0ac285cba6 (patch)
treecb3c28f81118142b1c9c69e43b8864938bb3618a
parent1cad159b52a49d14027b23676da5d73fb5142b9d (diff)
*** empty log message ***
svn path=/trunk/externals/olafmatt/; revision=6616
-rw-r--r--hidin/hidin.c746
-rw-r--r--hidin/hidin.h146
-rw-r--r--hidin/winNT_usb.c752
3 files changed, 0 insertions, 1644 deletions
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 <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#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)<port> (int)<value>' */
- 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 <olaf.matthes@gmx.de>!");
- }
- }
- 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 <windows.h>
-#include <basetyps.h>
-#include <stdlib.h>
-#include <wtypes.h>
-#include <setupapi.h>
-#ifdef _MSC_VER
-#include "hidusage.h"
-#include "hidsdi.h"
-#else
-#include <ddk/hidusage.h>
-#include <ddk/hidsdi.h>
-#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 <olaf.matthes@gmx.de>
-
- 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 <stdio.h>
-#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);
-}
-