From c71b92fd92572f60914bb39fd485c4331aa8caf6 Mon Sep 17 00:00:00 2001 From: Olaf Matthes Date: Wed, 3 Jan 2007 11:07:20 +0000 Subject: more orless working Windows code, needs to be adapted to work with global element[][] array svn path=/trunk/externals/io/hidio/; revision=7158 --- hidio_windows.c | 1282 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 828 insertions(+), 454 deletions(-) diff --git a/hidio_windows.c b/hidio_windows.c index 25623e9..896422d 100644 --- a/hidio_windows.c +++ b/hidio_windows.c @@ -24,59 +24,59 @@ #include #include #include -#include - -/* - * Please note that this file needs the Microsoft Driver Developent Kit (DDK) - * to be installed in order to compile! - */ +#include + +/* + * Please note that this file needs the Microsoft Driver Developent Kit (DDK) + * to be installed in order to compile! + */ #ifdef _MSC_VER #include #else #include -#endif /* _MSC_VER */ +#endif /* _MSC_VER */ #include "hidio.h" //#define DEBUG(x) -#define DEBUG(x) x - -#define debug_print(d, p) post(p) - -typedef struct _hid_device_ -{ - HANDLE fh; /* file handle to the hid device */ - OVERLAPPED overlapped; - - 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; - unsigned long inputDataLength; // Num elements in this array. - PHIDP_BUTTON_CAPS inputButtonCaps; - PHIDP_VALUE_CAPS inputValueCaps; - - char *outputReportBuffer; - unsigned long outputDataLength; - PHIDP_BUTTON_CAPS outputButtonCaps; - PHIDP_VALUE_CAPS outputValueCaps; - - char *featureReportBuffer; - unsigned long featureDataLength; - PHIDP_BUTTON_CAPS featureButtonCaps; - PHIDP_VALUE_CAPS featureValueCaps; -} t_hid_device; +#define DEBUG(x) x + +#define debug_print(d, p) post(p) + +typedef struct _hid_device_ +{ + HANDLE fh; /* file handle to the hid device */ + OVERLAPPED overlapped; + + 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; + unsigned long inputDataLength; // Num elements in this array. + PHIDP_BUTTON_CAPS inputButtonCaps; + PHIDP_VALUE_CAPS inputValueCaps; + + char *outputReportBuffer; + unsigned long outputDataLength; + PHIDP_BUTTON_CAPS outputButtonCaps; + PHIDP_VALUE_CAPS outputValueCaps; + + char *featureReportBuffer; + unsigned long featureDataLength; + PHIDP_BUTTON_CAPS featureButtonCaps; + PHIDP_VALUE_CAPS featureValueCaps; +} t_hid_device; /*============================================================================== * GLOBAL VARS *======================================================================== */ -extern t_int hidio_instance_count; // in hidio.h - -/* store device pointers so I don't have to query them all the time */ -// t_hid_devinfo device_pointer[MAX_DEVICES]; +extern t_int hidio_instance_count; // in hidio.h + +/* store device pointers so I don't have to query them all the time */ +// t_hid_devinfo device_pointer[MAX_DEVICES]; /*============================================================================== * FUNCTION PROTOTYPES @@ -89,293 +89,628 @@ extern t_int hidio_instance_count; // in hidio.h *============================================================================== */ -/* ============================================================================== */ -/* WINDOWS DDK HID SPECIFIC REALLY LOW-LEVEL STUFF */ -/* ============================================================================== */ - -/* count devices by looking into the registry */ -short _hid_count_devices(void) -{ - short i, gNumDevices = 0; - long ret; - - HKEY hKey; - long DeviceNameLen, KeyNameLen; - char KeyName[MAXPDSTRING]; - char DeviceName[MAXPDSTRING]; - - /* Search in Windows Registry for enumerated HID devices */ - if ((ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\hidusb\\Enum", 0, KEY_QUERY_VALUE, &hKey)) != ERROR_SUCCESS) - { - error("hidio: failed to get list of HID devices from registry"); - return -1; - } - - for (i = 0; i < MAX_DEVICES + 3; i++) /* there are three entries that are no devices */ - { - DeviceNameLen = 80; - KeyNameLen = 100; - ret = RegEnumValue(hKey, i, KeyName, &KeyNameLen, NULL, NULL, DeviceName, &DeviceNameLen); - if (ret == ERROR_SUCCESS) - { - if (!strncmp(KeyName, "Count", 5)) - { - /* this is the number of devices as HEX DWORD */ - continue; - } - else if (!strncmp(DeviceName, "USB\\Vid", 7)) - { - /* we found a device, DeviceName contains the path */ - // post("device #%d: %s = %s", gNumDevices, KeyName, DeviceName); - gNumDevices++; - continue; - } - } - else if (ret == ERROR_NO_MORE_ITEMS) /* no more entries in registry */ - { - break; - } - else /* any other error while looking into registry */ - { - char errbuf[MAXPDSTRING]; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, ret, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - errbuf, MAXPDSTRING, NULL); - error("hidio: $s", errbuf); - break; - } - } - RegCloseKey(hKey); - return gNumDevices; /* return number of devices */ -} - -/* get device path for a HID specified by number */ -static short _hid_get_device_path(short device_number, char **path, short length) -{ - GUID guid; - HDEVINFO DeviceInfo; - SP_DEVICE_INTERFACE_DATA DeviceInterface; - PSP_INTERFACE_DEVICE_DETAIL_DATA DeviceDetail; - unsigned long iSize; - - HidD_GetHidGuid(&guid); - - DeviceInfo = SetupDiGetClassDevs(&guid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); - - DeviceInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); - - if (!SetupDiEnumDeviceInterfaces(DeviceInfo, NULL, &guid, device_number, &DeviceInterface)) - { - SetupDiDestroyDeviceInfoList(DeviceInfo); - return -1; - } - - SetupDiGetDeviceInterfaceDetail( DeviceInfo, &DeviceInterface, NULL, 0, &iSize, 0 ); - - DeviceDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(iSize); - DeviceDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); - - if (SetupDiGetDeviceInterfaceDetail(DeviceInfo, &DeviceInterface, DeviceDetail, iSize, &iSize, NULL)) - { - if (!*path && !length) /* we got no memory passed in, allocate some */ - { /* WARNING: caller has to free this memory!! */ - *path = (char *)getbytes((short)(strlen(DeviceDetail->DevicePath) * sizeof(char))); - } - /* copy path */ - strcpy(*path, DeviceDetail->DevicePath); - } - free(DeviceDetail); - - SetupDiDestroyDeviceInfoList(DeviceInfo); - return 0; -} - - -/* get capabilities (usage page & usage ID) of an already opened device */ -static short _hid_get_capabilities(HANDLE fd, HIDP_CAPS *capabilities) -{ - PHIDP_PREPARSED_DATA preparsedData; - - if (fd == INVALID_HANDLE_VALUE) - { - error("hidio: couldn't get device capabilities due to an invalid handle"); - return -1; - } - - /* returns and allocates a buffer with device info */ - HidD_GetPreparsedData(fd, &preparsedData); - - /* get capabilities of device from above buffer */ - HidP_GetCaps(preparsedData, capabilities); - - /* no need for PreparsedData any more, so free the memory it's using */ - HidD_FreePreparsedData(preparsedData); - return 0; -} - +/* ============================================================================== */ +/* WINDOWS DDK HID SPECIFIC REALLY LOW-LEVEL STUFF */ +/* ============================================================================== */ +/* + * connect to Ith USB device (count starting with 0) + */ + +static 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); + error("%s: failed to get specified device number", CLASS_NAME); + 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); + error("%s: failed to get device info", CLASS_NAME); + return INVALID_HANDLE_VALUE; + } + + /* 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, + NULL); + + if (deviceHandle == INVALID_HANDLE_VALUE) + { + int err = GetLastError(); + LPVOID lpMsgBuf; + if (err == ERROR_ACCESS_DENIED) + { + /* error("%s: can not read from mouse and keyboard", CLASS_NAME); */ + return INVALID_HANDLE_VALUE; + } + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); + error("%s: could not get device #%i: %s (%d)", CLASS_NAME, deviceIndex + 1, (LPCTSTR)lpMsgBuf, err); + LocalFree(lpMsgBuf); + } + + SetupDiDestroyDeviceInfoList (hardwareDeviceInfoSet); + free (deviceDetail); + return deviceHandle; +} + +static long _hidio_read(t_hid_device *self) +{ + unsigned long ret, err = 0; + long bytes = 0; + + if (!ReadFile(self->fh, self->inputReportBuffer, self->caps.InputReportByteLength, &bytes, (LPOVERLAPPED)&self->overlapped)) + { + if (ERROR_IO_PENDING != (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); + error("%s: read: %s", CLASS_NAME, (LPCTSTR)lpMsgBuf); + LocalFree(lpMsgBuf); + return -1; + } + } + + ret = WaitForSingleObject(self->overlapped.hEvent, 0); + + if (ret == WAIT_OBJECT_0) /* hey, we got signalled ! => data */ + { + return bytes; + } + else /* if no data, cancel read */ + { + if (!CancelIo(self->fh) && (self->fh != INVALID_HANDLE_VALUE)) + return -1; /* CancelIo() failed */ + } + if (!ResetEvent(self->overlapped.hEvent)) + return -1; /* ResetEvent() failed */ + + return bytes; +} + +/* count devices by looking into the registry */ +short _hid_count_devices(void) +{ + short i, gNumDevices = 0; + long ret; + + HKEY hKey; + long DeviceNameLen, KeyNameLen; + char KeyName[MAXPDSTRING]; + char DeviceName[MAXPDSTRING]; + + /* Search in Windows Registry for enumerated HID devices */ + if ((ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\hidusb\\Enum", 0, KEY_QUERY_VALUE, &hKey)) != ERROR_SUCCESS) + { + error("hidio: failed to get list of HID devices from registry"); + return EXIT_FAILURE; + } + + for (i = 0; i < MAX_DEVICES + 3; i++) /* there are three entries that are no devices */ + { + DeviceNameLen = 80; + KeyNameLen = 100; + ret = RegEnumValue(hKey, i, KeyName, &KeyNameLen, NULL, NULL, DeviceName, &DeviceNameLen); + if (ret == ERROR_SUCCESS) + { + if (!strncmp(KeyName, "Count", 5)) + { + /* this is the number of devices as HEX DWORD */ + continue; + } + else if (!strncmp(DeviceName, "USB\\Vid", 7)) + { + /* we found a device, DeviceName contains the path */ + // post("device #%d: %s = %s", gNumDevices, KeyName, DeviceName); + gNumDevices++; + continue; + } + } + else if (ret == ERROR_NO_MORE_ITEMS) /* no more entries in registry */ + { + break; + } + else /* any other error while looking into registry */ + { + char errbuf[MAXPDSTRING]; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, ret, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + errbuf, MAXPDSTRING, NULL); + error("hidio: $s", errbuf); + break; + } + } + RegCloseKey(hKey); + return gNumDevices; /* return number of devices */ +} + +/* get device path for a HID specified by number */ +static short _hid_get_device_path(short device_number, char **path, short length) +{ + GUID guid; + HDEVINFO DeviceInfo; + SP_DEVICE_INTERFACE_DATA DeviceInterface; + PSP_INTERFACE_DEVICE_DETAIL_DATA DeviceDetail; + unsigned long iSize; + + HidD_GetHidGuid(&guid); + + DeviceInfo = SetupDiGetClassDevs(&guid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); + + DeviceInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + if (!SetupDiEnumDeviceInterfaces(DeviceInfo, NULL, &guid, device_number, &DeviceInterface)) + { + SetupDiDestroyDeviceInfoList(DeviceInfo); + return EXIT_FAILURE; + } + + SetupDiGetDeviceInterfaceDetail( DeviceInfo, &DeviceInterface, NULL, 0, &iSize, 0 ); + + DeviceDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(iSize); + DeviceDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); + + if (SetupDiGetDeviceInterfaceDetail(DeviceInfo, &DeviceInterface, DeviceDetail, iSize, &iSize, NULL)) + { + if (!*path && !length) /* we got no memory passed in, allocate some */ + { /* WARNING: caller has to free this memory!! */ + *path = (char *)getbytes((short)(strlen(DeviceDetail->DevicePath) * sizeof(char))); + } + /* copy path */ + strcpy(*path, DeviceDetail->DevicePath); + } + free(DeviceDetail); + + SetupDiDestroyDeviceInfoList(DeviceInfo); + return 0; +} + + +/* get capabilities (usage page & usage ID) of an already opened device */ +static short _hid_get_capabilities(HANDLE fd, HIDP_CAPS *capabilities) +{ + PHIDP_PREPARSED_DATA preparsedData; + + if (fd == INVALID_HANDLE_VALUE) + { + error("hidio: couldn't get device capabilities due to an invalid handle"); + return EXIT_FAILURE; + } + + /* returns and allocates a buffer with device info */ + HidD_GetPreparsedData(fd, &preparsedData); + + /* get capabilities of device from above buffer */ + HidP_GetCaps(preparsedData, capabilities); + + /* no need for PreparsedData any more, so free the memory it's using */ + HidD_FreePreparsedData(preparsedData); + return 0; +} + /* ============================================================================== */ /* WINDOWS DDK HID SPECIFIC SUPPORT FUNCTIONS */ /* ============================================================================== */ -short get_device_number_by_id(unsigned short vendor_id, unsigned short product_id) +short get_device_number_by_id(unsigned short vendor_id, unsigned short product_id) +{ + return EXIT_FAILURE; +} + +short get_device_number_from_usage(short device_number, + unsigned short usage_page, + unsigned short usage) +{ + HANDLE fd = INVALID_HANDLE_VALUE; + HIDP_CAPS capabilities; + char path[MAX_PATH]; + char *pp = (char *)path; + short ret, i; + short device_count = _hid_count_devices(); + + for (i = device_number; i < device_count; i++) + { + /* get path for specified device number */ + ret = _hid_get_device_path(i, &pp, MAX_PATH); + if (ret == -1) + { + return EXIT_FAILURE; + } + else + { + /* open file on the device (read & write, no overlapp) */ + fd = CreateFile(path, + GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, + (LPSECURITY_ATTRIBUTES)NULL, + OPEN_EXISTING, + 0, + NULL); + if (fd == INVALID_HANDLE_VALUE) + { + return EXIT_FAILURE; + } + + /* get the capabilities */ + _hid_get_capabilities(fd, &capabilities); + + /* check whether they match with what we want */ + if (capabilities.UsagePage == usage_page && capabilities.Usage == usage) + { + CloseHandle(fd); + return i; + } + CloseHandle(fd); + } + } + return EXIT_FAILURE; +} + + +/* + * This function is needed to translate the USB HID relative flag into the + * [hidio]/linux style events + */ +static void convert_axis_to_symbols(t_hid_element *new_element, int array_index) +{ + if (new_element->relative) + { + new_element->type = ps_relative; + new_element->name = relative_symbols[array_index]; + } + else + { + new_element->type = ps_absolute; + new_element->name = absolute_symbols[array_index]; + } +} + +static void get_usage_symbols(unsigned short usage_page, unsigned short usage, t_hid_element *new_element) +{ + char buffer[MAXPDSTRING]; + + switch (usage_page) + { + case HID_USAGE_PAGE_GENERIC: + switch (usage) + { + case HID_USAGE_GENERIC_X: convert_axis_to_symbols(new_element, 0); break; + case HID_USAGE_GENERIC_Y: convert_axis_to_symbols(new_element, 1); break; + case HID_USAGE_GENERIC_Z: convert_axis_to_symbols(new_element, 2); break; + case HID_USAGE_GENERIC_RX: convert_axis_to_symbols(new_element, 3); break; + case HID_USAGE_GENERIC_RY: convert_axis_to_symbols(new_element, 4); break; + case HID_USAGE_GENERIC_RZ: convert_axis_to_symbols(new_element, 5); break; + case HID_USAGE_GENERIC_SLIDER: convert_axis_to_symbols(new_element, 6); break; + case HID_USAGE_GENERIC_DIAL: convert_axis_to_symbols(new_element, 7); break; + case HID_USAGE_GENERIC_WHEEL: convert_axis_to_symbols(new_element, 8); break; + case HID_USAGE_GENERIC_HATSWITCH: + // TODO: this is still a mystery how to handle, due to USB HID vs. Linux input.h + new_element->type = ps_absolute; + new_element->name = absolute_symbols[9]; /* hatswitch */ + break; + default: + new_element->type = gensym("DESKTOP"); + snprintf(buffer, sizeof(buffer), "DESKTOP%ld", usage); + new_element->name = gensym(buffer); + } + break; + case HID_USAGE_PAGE_SIMULATION: + switch (usage) + { + case HID_USAGE_SIMULATION_RUDDER: + new_element->type = ps_absolute; + new_element->name = absolute_symbols[5]; /* rz */ + break; + case HID_USAGE_SIMULATION_THROTTLE: + new_element->type = ps_absolute; + new_element->name = absolute_symbols[6]; /* slider */ + break; + default: + new_element->type = gensym("SIMULATION"); + snprintf(buffer, sizeof(buffer), "SIMULATION%ld", usage); + new_element->name = gensym(buffer); + } + break; + case HID_USAGE_PAGE_KEYBOARD: + new_element->type = ps_key; + if( (usage > -1) && + (usage < KEY_ARRAY_MAX) ) + new_element->name = key_symbols[usage]; + else /* PowerBook ADB keyboard reports 0xffffffff */ + new_element->name = key_symbols[0]; + break; + case HID_USAGE_PAGE_BUTTON: + new_element->type = ps_button; + new_element->name = button_symbols[usage]; + break; + case HID_USAGE_PAGE_LED: + new_element->type = ps_led; + new_element->name = led_symbols[usage]; + break; + case HID_USAGE_PAGE_DIGITIZER: /* no sure whether this is the right for PID in OS X */ + new_element->type = ps_pid; + new_element->name = pid_symbols[usage]; + break; + default: + /* the rest are "vendor defined" so no translation table is possible */ + snprintf(buffer, sizeof(buffer), "0x%04x", (unsigned int) usage_page); + new_element->type = gensym(buffer); + snprintf(buffer, sizeof(buffer), "0x%04x", (unsigned int) usage); + new_element->name = gensym(buffer); + } +} + +static void hidio_build_element_list(t_hidio *x) { - return -1; -} - -short get_device_number_from_usage(short device_number, - unsigned short usage_page, - unsigned short usage) -{ - HANDLE fd = INVALID_HANDLE_VALUE; - HIDP_CAPS capabilities; - char path[MAX_PATH]; - char *pp = (char *)path; - short ret, i; - short device_count = _hid_count_devices(); - - for (i = device_number; i < device_count; i++) - { - /* get path for specified device number */ - ret = _hid_get_device_path(i, &pp, MAX_PATH); - if (ret == -1) - { - return -1; - } - else - { - /* open file on the device (read & write, no overlapp) */ - fd = CreateFile(path, - GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, - (LPSECURITY_ATTRIBUTES)NULL, - OPEN_EXISTING, - 0, - NULL); - if (fd == INVALID_HANDLE_VALUE) - { - return -1; - } - - /* get the capabilities */ - _hid_get_capabilities(fd, &capabilities); - - /* check whether they match with what we want */ - if (capabilities.UsagePage == usage_page && capabilities.Usage == usage) - { - CloseHandle(fd); - return i; - } - CloseHandle(fd); - } - } - return -1; -} - - -void hidio_build_element_list(t_hidio *x) -{ - t_hid_device *self = (t_hid_device *)x->x_hid_device; - char type_name[256]; - char usage_name[256]; - - t_hid_element *current_element; - t_hid_element *new_element = NULL; - HIDP_CAPS capabilities; - short i; - - element_count[x->x_device_number] = 0; - if (self->fh != INVALID_HANDLE_VALUE) - { - /* now get device capabilities */ - _hid_get_capabilities(self->fh, &capabilities); - - /* for every possible element check what we got */ - for (i = 0; i < capabilities.NumberInputDataIndices; i++) - { -#if 0 - for (j = 0; j < capabilities.NumberInputButtonCaps; j++) - { - new_element = getbytes(sizeof(t_hid_element)); - if ((i == EV_ABS) && (test_bit(j, abs_bitmask))) - { - /* this means that the bit is set in the axes list */ - if(ioctl(self->fh, EVIOCGABS(j), &abs_features)) - perror("evdev EVIOCGABS ioctl"); - new_element->min = abs_features.minimum; - new_element->max = abs_features.maximum; - } - else - { - new_element->min = 0; - new_element->max = 0; - } - if(test_bit(j, element_bitmask[i])) - { - new_element->linux_type = i; /* the int from linux/input.h */ - new_element->type = gensym(ev[i] ? ev[i] : "?"); /* the symbol */ - new_element->linux_code = j; - if((i == EV_KEY) && (j >= BTN_MISC) && (j < KEY_OK) ) - { - new_element->name = hidio_convert_linux_buttons_to_numbers(j); - } - else - { - new_element->name = gensym(event_names[i][j] ? event_names[i][j] : "?"); - } - if( i == EV_REL ) - new_element->relative = 1; - else - new_element->relative = 0; - - /* fill in the t_hid_element struct here */ - post("x->x_device_number: %d element_count[]: %d", - x->x_device_number, element_count[x->x_device_number]); - post("usage_page/usage_id: %d/%d type/name: %s/%s max: %d min: %d ", - new_element->usage_page, new_element->usage_id, - new_element->type->s_name, new_element->name->s_name, - new_element->max, new_element->min); - post("\tpolled: %d relative: %d", - new_element->polled, new_element->relative); - element[x->x_device_number][element_count[x->x_device_number]] = new_element; - ++element_count[x->x_device_number]; - } - } - } -#endif - } - } + t_hid_device *self = (t_hid_device *)x->x_hid_device; + + t_hid_element *new_element = NULL; + unsigned short numButtons = 0; + unsigned short numValues = 0; + unsigned short numelem; /* total number of elements */ + unsigned short numCaps; + unsigned long i; + PHIDP_BUTTON_CAPS buttonCaps; + PHIDP_VALUE_CAPS valueCaps; + USAGE usage; + + element_count[x->x_device_number] = 0; + if (self->fh != INVALID_HANDLE_VALUE) + { + /* now get device capabilities */ + HidD_GetPreparsedData(self->fh, &self->ppd); + HidP_GetCaps(self->ppd, &self->caps); + + /* allocate memory for input and output reports */ + /* these buffers get used for sending and receiving */ + self->inputReportBuffer = (char *)getbytes((short)(self->caps.InputReportByteLength * sizeof(char))); + self->outputReportBuffer = (char *)getbytes((short)(self->caps.OutputReportByteLength * sizeof(char))); + self->featureReportBuffer = (char *)getbytes((short)(self->caps.FeatureReportByteLength * sizeof(char))); + + /* allocate memory for input info */ + self->inputButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS)getbytes((short)(self->caps.NumberInputButtonCaps * sizeof(HIDP_BUTTON_CAPS))); + self->inputValueCaps = valueCaps = (PHIDP_VALUE_CAPS)getbytes((short)(self->caps.NumberInputValueCaps * sizeof(HIDP_VALUE_CAPS))); + + + /* get capapbilities for buttons and values from device */ + numCaps = self->caps.NumberInputButtonCaps; + HidP_GetButtonCaps (HidP_Input, + buttonCaps, + &numCaps, + self->ppd); + + numCaps = self->caps.NumberInputValueCaps; + HidP_GetValueCaps (HidP_Input, + valueCaps, + &numCaps, + self->ppd); + + /* number of elements is number of values (axes) plus number of buttons */ +#if 1 + for (i = 0; i < self->caps.NumberInputValueCaps; i++, valueCaps++) + { + if (valueCaps->IsRange) + numValues += valueCaps->Range.UsageMax - valueCaps->Range.UsageMin + 1; + else + numValues++; + } + for (i = 0; i < self->caps.NumberInputButtonCaps; i++, buttonCaps++) + { + if (buttonCaps->IsRange) + numButtons += buttonCaps->Range.UsageMax - buttonCaps->Range.UsageMin + 1; + else + numButtons++; + } + numelem = numValues + numButtons; + + valueCaps = self->inputValueCaps; + buttonCaps = self->inputButtonCaps; +#else + /* maybe this could be done as well? works with my gamepad at least */ + numelem = HidP_MaxDataListLength(HidP_Input, self->ppd); + + HidP_MaxUsageListLength(HidP_Input, 0, self->ppd); +#endif + + /* now look through the reported capabilities of the devcie and fill in the elements struct */ + for (i = 0; i < self->caps.NumberInputButtonCaps; i++, buttonCaps++) + { + if (buttonCaps->IsRange) + { + for (usage = buttonCaps->Range.UsageMin; usage <= buttonCaps->Range.UsageMax; usage++) + { + new_element = getbytes(sizeof(t_hid_element)); + new_element->usage_page = buttonCaps->UsagePage; + new_element->usage_id = usage; + new_element->relative = !buttonCaps->IsAbsolute; /* buttons always are absolute, no? */ + new_element->min = 0; + new_element->max = 1; + new_element->instance = 0; + + get_usage_symbols(new_element->usage_page, new_element->usage_id, new_element); +#ifdef PD + SETSYMBOL(new_element->output_message, new_element->name); + SETFLOAT(new_element->output_message + 1, new_element->instance); +#else /* Max */ + atom_setsym(new_element->output_message, new_element->name); + atom_setlong(new_element->output_message + 1, (long)new_element->instance); +#endif /* PD */ + element[x->x_device_number][element_count[x->x_device_number]] = new_element; + ++element_count[x->x_device_number]; + } + } + else + { + new_element = getbytes(sizeof(t_hid_element)); + new_element->usage_page = buttonCaps->UsagePage; + new_element->usage_id = buttonCaps->NotRange.Usage; + new_element->relative = !buttonCaps->IsAbsolute; /* buttons always are absolute, no? */ + new_element->min = 0; + new_element->max = 1; + new_element->instance = 0; + + get_usage_symbols(new_element->usage_page, new_element->usage_id, new_element); +#ifdef PD + SETSYMBOL(new_element->output_message, new_element->name); + SETFLOAT(new_element->output_message + 1, new_element->instance); +#else /* Max */ + atom_setsym(new_element->output_message, new_element->name); + atom_setlong(new_element->output_message + 1, (long)new_element->instance); +#endif /* PD */ + element[x->x_device_number][element_count[x->x_device_number]] = new_element; + ++element_count[x->x_device_number]; + } + } + /* get value data */ + for (i = 0; i < numValues; i++, valueCaps++) + { + if (valueCaps->IsRange) + { + for (usage = valueCaps->Range.UsageMin; usage <= valueCaps->Range.UsageMax; usage++) + { + new_element = getbytes(sizeof(t_hid_element)); + new_element->usage_page = valueCaps->UsagePage; + new_element->usage_id = usage; + new_element->relative = !valueCaps->IsAbsolute; + new_element->min = valueCaps->LogicalMin; + new_element->max = valueCaps->LogicalMax; + new_element->instance = 0; + + get_usage_symbols(new_element->usage_page, new_element->usage_id, new_element); +#ifdef PD + SETSYMBOL(new_element->output_message, new_element->name); + SETFLOAT(new_element->output_message + 1, new_element->instance); +#else /* Max */ + atom_setsym(new_element->output_message, new_element->name); + atom_setlong(new_element->output_message + 1, (long)new_element->instance); +#endif /* PD */ + element[x->x_device_number][element_count[x->x_device_number]] = new_element; + ++element_count[x->x_device_number]; + } + } + else + { + new_element = getbytes(sizeof(t_hid_element)); + new_element->usage_page = valueCaps->UsagePage; + new_element->usage_id = valueCaps->NotRange.Usage; + new_element->relative = !valueCaps->IsAbsolute; + new_element->min = valueCaps->LogicalMin; + new_element->max = valueCaps->LogicalMax; + new_element->instance = 0; + + get_usage_symbols(new_element->usage_page, new_element->usage_id, new_element); +#ifdef PD + SETSYMBOL(new_element->output_message, new_element->name); + SETFLOAT(new_element->output_message + 1, new_element->instance); +#else /* Max */ + atom_setsym(new_element->output_message, new_element->name); + atom_setlong(new_element->output_message + 1, (long)new_element->instance); +#endif /* PD */ + element[x->x_device_number][element_count[x->x_device_number]] = new_element; + ++element_count[x->x_device_number]; + } + } + } } t_int hidio_print_element_list(t_hidio *x) { - t_hid_device *self = (t_hid_device *)x->x_hid_device; - - debug_print(LOG_DEBUG,"hidio_print_element_list"); - - return (0); + t_hid_device *self = (t_hid_device *)x->x_hid_device; + t_hid_element *current_element; + int i; + + debug_print(LOG_DEBUG,"hidio_print_element_list"); + + post("[hidio] found %d elements:", element_count[x->x_device_number]); + post("\n TYPE\tCODE\t#\tEVENT NAME"); + post("-----------------------------------------------------------"); + for (i = 0; i < element_count[x->x_device_number]; i++) + { + current_element = element[x->x_device_number][i]; + post(" %s\t%s\t%d", current_element->type->s_name, + current_element->name->s_name,(int) current_element->instance); + } + post(""); + + return EXIT_SUCCESS; } t_int hidio_print_device_list(t_hidio *x) { - t_hid_device *self = (t_hid_device *)x->x_hid_device; + t_hid_device *self = (t_hid_device *)x->x_hid_device; struct _GUID GUID; SP_INTERFACE_DEVICE_DATA DeviceInterfaceData; - struct - { - DWORD cbSize; - char DevicePath[MAX_PATH]; + struct + { + DWORD cbSize; + char DevicePath[MAX_PATH]; } FunctionClassDeviceData; HIDD_ATTRIBUTES HIDAttributes; SECURITY_ATTRIBUTES SecurityAttributes; int i; HANDLE PnPHandle, HIDHandle; ULONG BytesReturned; - int Success, ManufacturerName, ProductName; + int Success, ManufacturerName, ProductName; PWCHAR widestring[MAXPDSTRING]; char ManufacturerBuffer[MAXPDSTRING]; char ProductBuffer[MAXPDSTRING]; const char NotSupplied[] = "NULL"; - DWORD lastError = 0; + DWORD lastError = 0; /* Initialize the GUID array and setup the security attributes for Win2000 */ HidD_GetHidGuid(&GUID); @@ -392,18 +727,18 @@ t_int hidio_print_device_list(t_hidio *x) error("[hidio] ERROR: Could not attach to PnP node"); return (t_int) GetLastError(); } - - post(""); + + post(""); /* Lets look for a maximum of 32 Devices */ - for (i = 0; i < MAX_DEVICES; i++) + for (i = 0; i < MAX_DEVICES; i++) { /* Initialize our data */ DeviceInterfaceData.cbSize = sizeof(DeviceInterfaceData); /* Is there a device at this table entry */ Success = SetupDiEnumDeviceInterfaces(PnPHandle, NULL, &GUID, i, &DeviceInterfaceData); - if (Success) + if (Success) { /* There is a device here, get it's name */ FunctionClassDeviceData.cbSize = 5; @@ -416,7 +751,7 @@ t_int hidio_print_device_list(t_hidio *x) error("[hidio] ERROR: Could not find the system name for device %d",i); return GetLastError(); } - /* Can now open this device */ + /* Can now open this device */ HIDHandle = CreateFile(FunctionClassDeviceData.DevicePath, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, @@ -436,31 +771,31 @@ t_int hidio_print_device_list(t_hidio *x) return GetLastError(); } ManufacturerName = HidD_GetManufacturerString(HIDHandle, widestring, MAXPDSTRING); - wcstombs(ManufacturerBuffer, (const unsigned short *)widestring, MAXPDSTRING); - ProductName = HidD_GetProductString(HIDHandle, widestring, MAXPDSTRING); - wcstombs(ProductBuffer, (const unsigned short *)widestring, MAXPDSTRING); + wcstombs(ManufacturerBuffer, (const unsigned short *)widestring, MAXPDSTRING); + ProductName = HidD_GetProductString(HIDHandle, widestring, MAXPDSTRING); + wcstombs(ProductBuffer, (const unsigned short *)widestring, MAXPDSTRING); /* And display it! */ - post("__________________________________________________"); - post("Device %d: '%s' '%s' version %d", i, - ManufacturerName ? ManufacturerBuffer : NotSupplied, ProductName ? ProductBuffer : NotSupplied, - HIDAttributes.VersionNumber); - post(" vendorID: 0x%04x productID: 0x%04x", - HIDAttributes.VendorID, HIDAttributes.ProductID); - + post("__________________________________________________"); + post("Device %d: '%s' '%s' version %d", i, + ManufacturerName ? ManufacturerBuffer : NotSupplied, ProductName ? ProductBuffer : NotSupplied, + HIDAttributes.VersionNumber); + post(" vendorID: 0x%04x productID: 0x%04x", + HIDAttributes.VendorID, HIDAttributes.ProductID); + CloseHandle(HIDHandle); } // if (SetupDiEnumDeviceInterfaces . . } // for (i = 0; i < 32; i++) - SetupDiDestroyDeviceInfoList(PnPHandle); - + SetupDiDestroyDeviceInfoList(PnPHandle); + post(""); - - return 0; + + return EXIT_SUCCESS; } void hidio_output_device_name(t_hidio *x, char *manufacturer, char *product) { - t_hid_device *self = (t_hid_device *)x->x_hid_device; + t_hid_device *self = (t_hid_device *)x->x_hid_device; char *device_name; t_symbol *device_name_symbol; @@ -470,11 +805,11 @@ void hidio_output_device_name(t_hidio *x, char *manufacturer, char *product) strcat( device_name, manufacturer ); strcat ( device_name, " "); strcat( device_name, product ); -// outlet_anything( x->x_status_outlet, gensym( device_name ),0,NULL ); +// outlet_anything( x->x_status_outlet, gensym( device_name ),0,NULL ); #ifdef PD - outlet_symbol( x->x_status_outlet, gensym( device_name ) ); -#else - outlet_anything( x->x_status_outlet, gensym( device_name ),0,NULL ); + outlet_symbol( x->x_status_outlet, gensym( device_name ) ); +#else + outlet_anything( x->x_status_outlet, gensym( device_name ),0,NULL ); #endif } @@ -483,183 +818,222 @@ void hidio_output_device_name(t_hidio *x, char *manufacturer, char *product) /* ------------------------------------------------------------------------------ */ /* cross-platform force feedback functions */ -void hidio_ff_autocenter( t_hidio *x, t_float value ) +t_int hidio_ff_autocenter( t_hidio *x, t_float value ) { - t_hid_device *self = (t_hid_device *)x->x_hid_device; + t_hid_device *self = (t_hid_device *)x->x_hid_device; + return EXIT_SUCCESS; } -void hidio_ff_gain( t_hidio *x, t_float value ) +t_int hidio_ff_gain( t_hidio *x, t_float value ) { - t_hid_device *self = (t_hid_device *)x->x_hid_device; + t_hid_device *self = (t_hid_device *)x->x_hid_device; + return EXIT_SUCCESS; } -void hidio_ff_motors( t_hidio *x, t_float value ) +t_int hidio_ff_motors( t_hidio *x, t_float value ) { - t_hid_device *self = (t_hid_device *)x->x_hid_device; + t_hid_device *self = (t_hid_device *)x->x_hid_device; + return EXIT_SUCCESS; } -void hidio_ff_continue( t_hidio *x ) +t_int hidio_ff_continue( t_hidio *x ) { - t_hid_device *self = (t_hid_device *)x->x_hid_device; + t_hid_device *self = (t_hid_device *)x->x_hid_device; + return EXIT_SUCCESS; } -void hidio_ff_pause( t_hidio *x ) +t_int hidio_ff_pause( t_hidio *x ) { - t_hid_device *self = (t_hid_device *)x->x_hid_device; + t_hid_device *self = (t_hid_device *)x->x_hid_device; + return EXIT_SUCCESS; } -void hidio_ff_reset( t_hidio *x ) +t_int hidio_ff_reset( t_hidio *x ) { - t_hid_device *self = (t_hid_device *)x->x_hid_device; + t_hid_device *self = (t_hid_device *)x->x_hid_device; + return EXIT_SUCCESS; } -void hidio_ff_stopall( t_hidio *x ) +t_int hidio_ff_stopall( t_hidio *x ) { - t_hid_device *self = (t_hid_device *)x->x_hid_device; + t_hid_device *self = (t_hid_device *)x->x_hid_device; + return EXIT_SUCCESS; } // these are just for testing... -void hidio_ff_fftest ( t_hidio *x, t_float value) +t_int hidio_ff_fftest ( t_hidio *x, t_float value) { - t_hid_device *self = (t_hid_device *)x->x_hid_device; + t_hid_device *self = (t_hid_device *)x->x_hid_device; + return EXIT_SUCCESS; } void hidio_ff_print( t_hidio *x ) { - t_hid_device *self = (t_hid_device *)x->x_hid_device; + t_hid_device *self = (t_hid_device *)x->x_hid_device; } /* ============================================================================== */ /* Pd [hidio] FUNCTIONS */ /* ============================================================================== */ -void hidio_platform_specific_info(t_hidio *x) -{ - t_hid_device *self = (t_hid_device *)x->x_hid_device; - //debug_print(LOG_DEBUG,"hidio_platform_specific_info"); -} - +void hidio_platform_specific_info(t_hidio *x) +{ + t_hid_device *self = (t_hid_device *)x->x_hid_device; + //debug_print(LOG_DEBUG,"hidio_platform_specific_info"); +} + void hidio_get_events(t_hidio *x) { - t_hid_device *self = (t_hid_device *)x->x_hid_device; - long bytesRead; - - debug_print(LOG_DEBUG,"hidio_get_events"); -#if 0 - while (1) - { - if (!ReadFile(current_device->device, - current_device->inputReportBuffer, - current_device->caps.InputReportByteLength, - &bytesRead, - NULL)) - { - debug_error(x,LOG_ERR,"[hidio]: failed to read from device %d", x->x_device_number); - return; - } - - if (bytesRead) - { - debug_error(x,LOG_INFO,"[hidio]: got event from device %d", x->x_device_number); - } - else /* no more data to read */ - { - break; - } - } -#endif + t_hid_device *self = (t_hid_device *)x->x_hid_device; + t_hid_element *current_element = NULL; + long bytesRead; + + debug_print(LOG_DEBUG,"hidio_get_events"); + + while (_hidio_read(self) > 0) + { + unsigned long i; + unsigned long size, length; + unsigned short *usages; + + for (i = 0; i < element_count[x->x_device_number]; i++) + { + current_element = element[x->x_device_number][i]; + + /* first try getting value data */ + if (HIDP_STATUS_SUCCESS == HidP_GetUsageValue(HidP_Input, current_element[i].usage_page, 0, current_element[i].usage_id, ¤t_element[i].value, + self->ppd, self->inputReportBuffer, self->caps.InputReportByteLength)) + { + continue; + } + /* now try getting scaled value data */ + if (HIDP_STATUS_SUCCESS == HidP_GetScaledUsageValue(HidP_Input, current_element[i].usage_page, 0, current_element[i].usage_id, ¤t_element[i].value, + self->ppd, self->inputReportBuffer, self->caps.InputReportByteLength)) + { + continue; + } + + /* ask Windows how many usages we might expect at max. */ + length = size = HidP_MaxUsageListLength(HidP_Input, current_element[i].usage_page, self->ppd); + if (size) + { + /* uh, can't I alloc this memory in advance? but we might have several button usages on + different usage pages, so I'd have to figure out the largest one */ + usages = (unsigned short *)getbytes((short)(size * sizeof(unsigned short))); + /* finally try getting button data */ + if (HIDP_STATUS_SUCCESS == HidP_GetUsages(HidP_Input, current_element[i].usage_page, 0, usages, &length, + self->ppd, self->inputReportBuffer, self->caps.InputReportByteLength)) + { + unsigned long j; + + current_element[i].value = 0; + + for (j = 0; j < length, usages[j] != 0; j++) + { + if (current_element[i].usage_id == usages[j]) + { + current_element[i].value = 1; + break; + } + } + } + freebytes(usages, (short)(size * sizeof(unsigned short))); + } + } + } } t_int hidio_open_device(t_hidio *x, short device_number) -{ - t_hid_device *self = (t_hid_device *)x->x_hid_device; - short ret; - char path[MAX_PATH]; - char *pp = (char *)path; - short device_count = -1; - - debug_print(LOG_DEBUG,"hidio_open_device"); - - device_count = _hid_count_devices(); - - if (device_number > device_count) - { - debug_error(x,LOG_ERR,"[hidio]: device %d is not a valid device (%d)\n", device_number, device_count); - return 1; - } - - /* get path for specified device number */ - ret = _hid_get_device_path(device_number, &pp, MAX_PATH); - if (ret == -1) - { - debug_error(x,LOG_ERR,"[hidio]: could not obtain path for device %d\n", device_number); - return 1; - } - else - { - /* open file on the device (read & write, no overlapp) */ - self->fh = CreateFile(path, - GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, - (LPSECURITY_ATTRIBUTES)NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); - if (self->fh == INVALID_HANDLE_VALUE) - { - debug_error(x,LOG_ERR,"[hidio]: failed to open device %d at %s\n", device_number, path); - return 1; - } - /* LATER get the real device name here instead of displaying the path */ - post ("[hidio] opened device %d: %s", device_number, path); - - post("pre hidio_build_element_list"); - hidio_build_element_list(x); - } - return 0; +{ + t_hid_device *self = (t_hid_device *)x->x_hid_device; + + if (device_number >= 0) + { + // open new device + self->fh = connectDeviceNumber(device_number); + + if (self->fh != INVALID_HANDLE_VALUE) + { + hidio_build_element_list(x); + + /* prepare overlapped structure */ + self->overlapped.Offset = 0; + self->overlapped.OffsetHigh = 0; + self->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, ""); + + return EXIT_SUCCESS; + } + else + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } t_int hidio_close_device(t_hidio *x) { - t_hid_device *self = (t_hid_device *)x->x_hid_device; - t_int result = 0; - + t_hid_device *self = (t_hid_device *)x->x_hid_device; + debug_print(LOG_DEBUG, "hidio_close_device"); - - if (x->x_device_number > -1) - { - if (self->fh != INVALID_HANDLE_VALUE) - { - CloseHandle(self->fh); - self->fh = INVALID_HANDLE_VALUE; - } - } - - return (result); + + if (x->x_device_number > -1) + { + if (self->fh != INVALID_HANDLE_VALUE) + { + unsigned long i; + + CloseHandle(self->fh); + self->fh = INVALID_HANDLE_VALUE; + + /* free element list */ + for (i = 0; i < element_count[x->x_device_number]; i++); + freebytes(element[x->x_device_number][i], sizeof(t_hid_element)); + element_count[x->x_device_number] = 0; + + /* free allocated memory */ + if (self->inputButtonCaps) + freebytes(self->inputButtonCaps, (short)(self->caps.NumberInputButtonCaps * sizeof(HIDP_BUTTON_CAPS))); + if (self->inputValueCaps) + freebytes(self->inputValueCaps, (short)(self->caps.NumberInputValueCaps * sizeof(HIDP_VALUE_CAPS))); + + /* free report buffers */ + if (self->inputReportBuffer) + freebytes(self->inputReportBuffer, (short)(self->caps.InputReportByteLength * sizeof(char))); + if (self->outputReportBuffer) + freebytes(self->outputReportBuffer, (short)(self->caps.OutputReportByteLength * sizeof(char))); + if (self->featureReportBuffer) + freebytes(self->featureReportBuffer, (short)(self->caps.FeatureReportByteLength * sizeof(char))); + + /* free preparsed data */ + if (self->ppd) + HidD_FreePreparsedData(self->ppd); + } + } + + return EXIT_SUCCESS; } void hidio_build_device_list(void) -{ - debug_print(LOG_DEBUG,"hidio_build_device_list"); +{ + debug_print(LOG_DEBUG,"hidio_build_device_list"); } void hidio_print(t_hidio *x) { - t_hid_device *self = (t_hid_device *)x->x_hid_device; - + t_hid_device *self = (t_hid_device *)x->x_hid_device; + hidio_print_device_list(x); if (x->x_device_open) @@ -671,27 +1045,27 @@ void hidio_print(t_hidio *x) void hidio_platform_specific_free(t_hidio *x) -{ - t_hid_device *self = (t_hid_device *)x->x_hid_device; +{ + t_hid_device *self = (t_hid_device *)x->x_hid_device; debug_print(LOG_DEBUG,"hidio_platform_specific_free"); - - if (self) - freebytes(self, sizeof(t_hid_device)); + + if (self) + freebytes(self, sizeof(t_hid_device)); } -void *hidio_platform_specific_new(t_hidio *x) -{ - t_hid_device *self; - - debug_print(LOG_DEBUG,"hidio_platform_specific_new"); - - /* alloc memory for our instance */ - self = (t_hid_device *)getbytes(sizeof(t_hid_device)); - self->fh = INVALID_HANDLE_VALUE; - - return (void *)self; /* return void pointer to our data struct */ -} +void *hidio_platform_specific_new(t_hidio *x) +{ + t_hid_device *self; + + debug_print(LOG_DEBUG,"hidio_platform_specific_new"); + + /* alloc memory for our instance */ + self = (t_hid_device *)getbytes(sizeof(t_hid_device)); + self->fh = INVALID_HANDLE_VALUE; + + return (void *)self; /* return void pointer to our data struct */ +} #endif /* _WINDOWS */ -- cgit v1.2.1