[PD-cvs] externals/io/hidio hidio.h, 1.15, 1.16 hidio_darwin.c, 1.8, 1.9 hidio_windows.c, 1.3, 1.4

Hans-Christoph Steiner eighthave at users.sourceforge.net
Tue Jan 2 21:40:51 CET 2007


Update of /cvsroot/pure-data/externals/io/hidio
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1463

Modified Files:
	hidio.h hidio_darwin.c hidio_windows.c 
Log Message:
Olaf's first code for windows

Index: hidio.h
===================================================================
RCS file: /cvsroot/pure-data/externals/io/hidio/hidio.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -C2 -d -r1.15 -r1.16
*** hidio.h	2 Jan 2007 05:37:06 -0000	1.15
--- hidio.h	2 Jan 2007 20:40:49 -0000	1.16
***************
*** 195,200 ****
  
  /* cross-platform force feedback functions */
! extern void hidio_ff_autocenter(t_hidio *x, t_float value);
! extern void hidio_ff_gain(t_hidio *x, t_float value);
  extern t_int hidio_ff_motors(t_hidio *x, t_float value);
  extern t_int hidio_ff_continue(t_hidio *x);
--- 195,200 ----
  
  /* cross-platform force feedback functions */
! extern t_int hidio_ff_autocenter(t_hidio *x, t_float value);
! extern t_int hidio_ff_gain(t_hidio *x, t_float value);
  extern t_int hidio_ff_motors(t_hidio *x, t_float value);
  extern t_int hidio_ff_continue(t_hidio *x);

Index: hidio_darwin.c
===================================================================
RCS file: /cvsroot/pure-data/externals/io/hidio/hidio_darwin.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** hidio_darwin.c	2 Jan 2007 05:37:06 -0000	1.8
--- hidio_darwin.c	2 Jan 2007 20:40:49 -0000	1.9
***************
*** 284,288 ****
  /* ============================================================================== */
  
- /*
  // temp hack for measuring latency
  double calculate_event_latency( uint64_t endTime, uint64_t startTime )
--- 284,287 ----
***************
*** 298,302 ****
  	   {
             //convert to seconds (multiply by 1e-6 to get miliseconds)
!            conversion = 1e-6 * (double) info.numer / (double) info.denom;
         }
     }
--- 297,301 ----
  	   {
             //convert to seconds (multiply by 1e-6 to get miliseconds)
!            conversion = 1e-3 * (double) info.numer / (double) info.denom;
         }
     }
***************
*** 678,683 ****
  //			 current_element->name->s_name, current_element->value, 
  //			 current_element->previous_value);
- //		debug_post(LOG_DEBUG,"timestamp: %u %u", event.timestamp.hi, event.timestamp.lo);
  		timestamp =  * (uint64_t *) &(event.timestamp);
  		now =  mach_absolute_time();
  /*
--- 677,683 ----
  //			 current_element->name->s_name, current_element->value, 
  //			 current_element->previous_value);
  		timestamp =  * (uint64_t *) &(event.timestamp);
+ 		difference = calculate_event_latency(timestamp,0);
+ 		debug_post(LOG_DEBUG,"timestamp: %llu %llu", timestamp, difference);
  		now =  mach_absolute_time();
  /*

Index: hidio_windows.c
===================================================================
RCS file: /cvsroot/pure-data/externals/io/hidio/hidio_windows.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** hidio_windows.c	2 Jan 2007 05:37:07 -0000	1.3
--- hidio_windows.c	2 Jan 2007 20:40:49 -0000	1.4
***************
*** 1,7 ****
! #ifdef _WIN32
  /*
!  *  Microsoft Windows DDK HID support for Pd [hidio] object
   *
!  *  Copyright (c) 2004 Hans-Christoph All rights reserved.
   *
   *   This program is free software; you can redistribute it and/or modify
--- 1,7 ----
! #ifdef _WINDOWS
  /*
!  *  Microsoft Windows DDK HID support for Pd/Max [hidio] object
   *
!  *  Copyright (c) 2006 Olaf Matthes. All rights reserved.
   *
   *   This program is free software; you can redistribute it and/or modify
***************
*** 26,29 ****
--- 26,35 ----
  #include <stdio.h>
  #include <setupapi.h> 
+ 
+ /*
+  * Please note that this file needs the Microsoft Driver Developent Kit (DDK)
+  * to be installed in order to compile!
+  */
+ 
  #ifdef _MSC_VER
  #include <hidsdi.h> 
***************
*** 31,34 ****
--- 37,41 ----
  #include <ddk/hidsdi.h> 
  #endif /* _MSC_VER */
+ 
  #include "hidio.h"
  
***************
*** 36,44 ****
  #define DEBUG(x) x 
  
  /*==============================================================================
   *  GLOBAL VARS
   *======================================================================== */
  
! extern t_int hidio_instance_count;
  
  /*==============================================================================
--- 43,123 ----
  #define DEBUG(x) x 
  
+ #define debug_post(d, p) post(p)
+ 
+ typedef struct _hid_data
+ {
+    BOOLEAN			IsButtonData;
+    unsigned char	Reserved;
+    USAGE			UsagePage;   // The usage page for which we are looking.
+    unsigned long	Status;      // The last status returned from the accessor function
+                             // when updating this field.
+    unsigned long	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
+ 	  {
+          unsigned long	UsageMin;       // Variables to track the usage minimum and max
+          unsigned long	UsageMax;       // If equal, then only a single usage
+          unsigned long	MaxUsageLength; // Usages buffer length.
+          PUSAGE			Usages;         // list of usages (buttons ``down'' on the device.
+ 
+       } ButtonData;
+       struct
+ 	  {
+          USAGE			Usage; // The usage describing this value;
+          unsigned short	Reserved;
+ 
+          unsigned long	Value;
+          long			ScaledValue;
+       } ValueData;
+    };
+ } t_hid_data;
+ 
+ typedef struct _hid_device
+ {   
+     char                 *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
+     unsigned long        inputDataLength; // Num elements in this array.
+     PHIDP_BUTTON_CAPS    inputButtonCaps;
+     PHIDP_VALUE_CAPS     inputValueCaps;
+ 
+     char                 *outputReportBuffer;
+     t_hid_data           *outputData;
+     unsigned long        outputDataLength;
+     PHIDP_BUTTON_CAPS    outputButtonCaps;
+     PHIDP_VALUE_CAPS     outputValueCaps;
+ 
+     char                 *featureReportBuffer;
+     t_hid_data           *featureData;
+     unsigned long        featureDataLength;
+     PHIDP_BUTTON_CAPS    featureButtonCaps;
+     PHIDP_VALUE_CAPS     featureValueCaps;
+ } t_hid_device;
+ 
+ 
  /*==============================================================================
   *  GLOBAL VARS
   *======================================================================== */
  
! extern t_int hidio_instance_count; // in hidio.c
! 
! /* store device pointers so I don't have to query them all the time */
! // t_hid_devinfo device_pointer[MAX_DEVICES];
  
  /*==============================================================================
***************
*** 53,57 ****
--- 132,257 ----
   */
  
+ /* ============================================================================== */
+ /* 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 EXIT_SUCCESS;
+ }
+ 
+ 
+ /* 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 EXIT_SUCCESS;
+ }
  
  
***************
*** 60,81 ****
  /* ============================================================================== */
  
  void hidio_build_element_list(t_hidio *x) 
  {
! 	
  }
  
! static void hidio_print_element_list(t_hidio *x)
  {
  	debug_post(LOG_DEBUG,"hidio_print_element_list");
  
- 
  	return EXIT_SUCCESS;	
  }
  
! static t_int hidio_print_device_list(t_hidio *x) 
  {
  	struct _GUID GUID;
  	SP_INTERFACE_DEVICE_DATA DeviceInterfaceData;
! 	struct {DWORD cbSize; char DevicePath[256];} FunctionClassDeviceData;
  	HIDD_ATTRIBUTES HIDAttributes;
  	SECURITY_ATTRIBUTES SecurityAttributes;
--- 260,407 ----
  /* ============================================================================== */
  
+ short get_device_number_by_id(unsigned short vendor_id, unsigned short product_id)
+ {
+ 	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) 
  {
! 	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 (x->x_fd != INVALID_HANDLE_VALUE)
! 	{
! 		/* now get device capabilities */
! 		_hid_get_capabilities(x->x_fd, &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(x->x_fd, 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_int hidio_print_element_list(t_hidio *x)
  {
  	debug_post(LOG_DEBUG,"hidio_print_element_list");
  
  	return EXIT_SUCCESS;	
  }
  
! t_int hidio_print_device_list(t_hidio *x) 
  {
  	struct _GUID GUID;
  	SP_INTERFACE_DEVICE_DATA DeviceInterfaceData;
! 	struct
! 	{
! 		DWORD cbSize;
! 		char DevicePath[MAX_PATH];
! 	} FunctionClassDeviceData;
  	HIDD_ATTRIBUTES HIDAttributes;
  	SECURITY_ATTRIBUTES SecurityAttributes;
***************
*** 84,94 ****
  	ULONG BytesReturned;
  	int Success, ManufacturerName, ProductName;
! 	char ManufacturerBuffer[256];
! 	char ProductBuffer[256];
  	const char NotSupplied[] = "NULL";
  	DWORD lastError = 0;
  
! #if 0
! // Initialize the GUID array and setup the security attributes for Win2000
  	HidD_GetHidGuid(&GUID);
  	SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
--- 410,420 ----
  	ULONG BytesReturned;
  	int Success, ManufacturerName, ProductName;
! 	PWCHAR widestring[MAXPDSTRING];
! 	char ManufacturerBuffer[MAXPDSTRING];
! 	char ProductBuffer[MAXPDSTRING];
  	const char NotSupplied[] = "NULL";
  	DWORD lastError = 0;
  
! 	/* Initialize the GUID array and setup the security attributes for Win2000 */
  	HidD_GetHidGuid(&GUID);
  	SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
***************
*** 96,100 ****
  	SecurityAttributes.bInheritHandle = FALSE;
  
! // Get a handle for the Plug and Play node and request currently active devices
  	PnPHandle = SetupDiGetClassDevs(&GUID, NULL, NULL, 
  											  DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
--- 422,426 ----
  	SecurityAttributes.bInheritHandle = FALSE;
  
! 	/* Get a handle for the Plug and Play node and request currently active devices */
  	PnPHandle = SetupDiGetClassDevs(&GUID, NULL, NULL, 
  											  DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
***************
*** 102,118 ****
  	if ((int)PnPHandle == -1) 
  	{ 
! 		error("[hidio] ERROR: Could not attach to PnP node\n"); 
! 		return (t_int) GetLastError(); 
  	}
  
! // Lets look for a maximum of 32 Devices
! 	for (i = 0; i < 32; 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) {
! // There is a device here, get it's name
  			FunctionClassDeviceData.cbSize = 5;
  			Success = SetupDiGetDeviceInterfaceDetail(PnPHandle, 
--- 428,448 ----
  	if ((int)PnPHandle == -1) 
  	{ 
! 		error("[hidio] ERROR: Could not attach to PnP node");
! 		return (t_int) GetLastError();
  	}
  
! 	post("");
! 
! 	/* Lets look for a maximum of 32 Devices */
! 	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)
! 		{
! 			/* There is a device here, get it's name */
  			FunctionClassDeviceData.cbSize = 5;
  			Success = SetupDiGetDeviceInterfaceDetail(PnPHandle, 
***************
*** 122,129 ****
  			if (!Success) 
  			{ 
! 				error("[hidio] ERROR: Could not find the system name for device %d\n",i); 
  				return GetLastError();
  			}
! // Can now open this device
  			HIDHandle = CreateFile(FunctionClassDeviceData.DevicePath, 
  										  0, 
--- 452,459 ----
  			if (!Success) 
  			{ 
! 				error("[hidio] ERROR: Could not find the system name for device %d",i); 
  				return GetLastError();
  			}
! 			/* Can now open this device */
  			HIDHandle = CreateFile(FunctionClassDeviceData.DevicePath, 
  										  0, 
***************
*** 133,157 ****
  			if (HIDHandle == INVALID_HANDLE_VALUE) 
  			{
! 				error("[hidio] ERROR: Could not open HID #%d, Errorcode = %d\n", i, (int)lastError);
  				return lastError;
  			}
  			
! // Get the information about this HID
  			Success = HidD_GetAttributes(HIDHandle, &HIDAttributes);
  			if (!Success) 
  			{ 
! 				error("[hidio] ERROR: Could not get HID attributes\n"); 
  				return GetLastError(); 
  			}
! 			ManufacturerName = HidD_GetManufacturerString(HIDHandle, ManufacturerBuffer, 256);
! 			ProductName = HidD_GetProductString(HIDHandle, ProductBuffer, 256);
! // And display it!
! 			post("[hidio]: Device %d: %s %s\n",i,
! 				  ManufacturerName ? ManufacturerBuffer : NotSupplied,
! 				  ProductName ? ProductBuffer : NotSupplied);
! 			post("\tVenderID = %4.4x, Name = ", HIDAttributes.VendorID);
! 			post("%s\n", ManufacturerName ? ManufacturerBuffer : NotSupplied);
! 			post("\tProductID = %4.4x, Name = ", HIDAttributes.ProductID);
! 			post("%s\n", ProductName ? ProductBuffer : NotSupplied);
  
  			CloseHandle(HIDHandle);
--- 463,489 ----
  			if (HIDHandle == INVALID_HANDLE_VALUE) 
  			{
! 				error("[hidio] ERROR: Could not open HID #%d, Errorcode = %d", i, (int)lastError);
  				return lastError;
  			}
  			
! 			/* Get the information about this HID */
  			Success = HidD_GetAttributes(HIDHandle, &HIDAttributes);
  			if (!Success) 
  			{ 
! 				error("[hidio] ERROR: Could not get HID attributes"); 
  				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);
! 
! 			/* 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);
  
  			CloseHandle(HIDHandle);
***************
*** 159,163 ****
  	} // for (i = 0; i < 32; i++)
  	SetupDiDestroyDeviceInfoList(PnPHandle);
! #endif
  	return EXIT_SUCCESS;
  }
--- 491,497 ----
  	} // for (i = 0; i < 32; i++)
  	SetupDiDestroyDeviceInfoList(PnPHandle);
! 
! 	post("");
! 
  	return EXIT_SUCCESS;
  }
***************
*** 175,179 ****
--- 509,517 ----
  	strcat( device_name, product );
  //	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 );
+ #endif
  }
  
***************
*** 241,254 ****
  /* ============================================================================== */
  
  void hidio_get_events(t_hidio *x)
  {
! 	//debug_post(LOG_DEBUG,"hidio_get_events");
  }
  
  
! t_int hidio_open_device(t_hidio *x, t_int device_number)
  {
  	debug_post(LOG_DEBUG,"hidio_open_device");
  
  	return EXIT_SUCCESS;
  }
--- 579,663 ----
  /* ============================================================================== */
  
+ void hidio_platform_specific_info(t_hidio *x)
+ {
+ 	//debug_post(LOG_DEBUG,"hidio_platform_specific_info");
+ }
+ 
  void hidio_get_events(t_hidio *x)
  {
! 	long bytesRead;
! 
! 	debug_post(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_int hidio_open_device(t_hidio *x, short device_number)
  {
+ 	short ret;
+ 	char path[MAX_PATH];
+ 	char *pp = (char *)path;
+ 	short device_count = -1;
+ 
  	debug_post(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 EXIT_FAILURE;
+ 	}
+ 
+ 	/* 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 EXIT_FAILURE;
+ 	}
+ 	else
+ 	{
+ 		/* open file on the device (read & write, no overlapp) */
+ 		x->x_fd = CreateFile(path,
+ 							 GENERIC_READ|GENERIC_WRITE,
+ 							 FILE_SHARE_READ|FILE_SHARE_WRITE,
+ 							 (LPSECURITY_ATTRIBUTES)NULL,
+ 							 OPEN_EXISTING,
+ 							 FILE_FLAG_OVERLAPPED,
+ 							 NULL);
+ 		if (x->x_fd == INVALID_HANDLE_VALUE)
+ 		{
+ 			debug_error(x,LOG_ERR,"[hidio]: failed to open device %d at %s\n", device_number, path);
+ 			return EXIT_FAILURE;
+ 		}
+ 		/* 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 EXIT_SUCCESS;
  }
***************
*** 257,292 ****
  t_int hidio_close_device(t_hidio *x)
  {
! 	debug_post(LOG_DEBUG,"hidio_close_device");
  
! 	return EXIT_SUCCESS;
  }
  
  
! void hidio_build_device_list(t_hidio *x)
  {
  	debug_post(LOG_DEBUG,"hidio_build_device_list");
- 	
- /*
-  * The Windows DDK "hid.dll" has to be loaded manually because Windows gets
-  * confused by this object, which is also named "hid.dll".  This is the first
-  * platform-specific function called in hid.c, so that's why this is happening
-  * here.
-  */
- 	TCHAR hidDllPath[MAX_PATH];
- 	UINT hidDllPathLength;
- 	HMODULE hModule = NULL;
- 
- 	hidDllPathLength = GetSystemDirectory(hidDllPath, MAX_PATH);
- 	if( !hidDllPathLength  )
- 	{
- 		error("[hidio] ERROR: cannot get SystemRoot");
- 	}
- 	strcat(hidDllPath,"\\hid.dll");
- 	post("hidDllPath: %s",hidDllPath);
- 	hModule = LoadLibrary(hidDllPath);
- 	if ( !hModule )
- 	{
- 		error("[hidio] ERROR: couldn't load %s: error %d",hidDllPath,GetLastError());
- 	}
  }
  
--- 666,689 ----
  t_int hidio_close_device(t_hidio *x)
  {
! 	t_int result = 0;
  
! 	debug_post(LOG_DEBUG, "hidio_close_device");
! 	
! 	if (x->x_device_number > -1)
! 	{
! 		if (x->x_fd != INVALID_HANDLE_VALUE)
! 		{
! 			CloseHandle(x->x_fd);
! 			x->x_fd = INVALID_HANDLE_VALUE;
! 		}
! 	}
! 
! 	return (result);
  }
  
  
! void hidio_build_device_list(void)
  {
  	debug_post(LOG_DEBUG,"hidio_build_device_list");
  }
  
***************
*** 296,300 ****
  	hidio_print_device_list(x);
  	
! 	if(x->x_device_open) 
  	{
  		hidio_print_element_list(x);
--- 693,697 ----
  	hidio_print_device_list(x);
  	
! 	if (x->x_device_open) 
  	{
  		hidio_print_element_list(x);
***************
*** 319,321 ****
  
  
! #endif  /* _WIN32 */
--- 716,718 ----
  
  
! #endif  /* _WINDOWS */





More information about the Pd-cvs mailing list