sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

hid.cpp (9327B)


      1 //=================== Copyright Valve Corporation, All rights reserved. =======
      2 //
      3 // Purpose: A wrapper around both the libusb and hidraw versions of HIDAPI
      4 //
      5 //          The libusb version doesn't support Bluetooth, but not all Linux
      6 //          distributions allow access to /dev/hidraw*
      7 //
      8 //          This merges the two, at a small performance cost, until distributions
      9 //          have granted access to /dev/hidraw*
     10 //
     11 //=============================================================================
     12 
     13 #define NAMESPACE HIDRAW
     14 #include "../hidapi/hidapi.h"
     15 #undef NAMESPACE
     16 #undef HIDAPI_H__
     17 
     18 #define NAMESPACE HIDUSB
     19 #include "../hidapi/hidapi.h"
     20 #undef NAMESPACE
     21 #undef HIDAPI_H__
     22 
     23 #include "../hidapi/hidapi.h"
     24 
     25 #include "../../../public/tier1/utlvector.h"
     26 #include "../../../public/tier1/utlhashmap.h"
     27 
     28 
     29 template <class T>
     30 void CopyHIDDeviceInfo( T *pSrc, struct hid_device_info *pDst )
     31 {
     32 	pDst->path = pSrc->path ? strdup( pSrc->path ) : NULL;
     33 	pDst->vendor_id = pSrc->vendor_id;
     34 	pDst->product_id = pSrc->product_id;
     35 	pDst->serial_number = pSrc->serial_number ? wcsdup( pSrc->serial_number ) : NULL;
     36 	pDst->release_number = pSrc->release_number;
     37 	pDst->manufacturer_string = pSrc->manufacturer_string ? wcsdup( pSrc->manufacturer_string ) : NULL;
     38 	pDst->product_string = pSrc->product_string ? wcsdup( pSrc->product_string ) : NULL;
     39 	pDst->usage_page = pSrc->usage_page;
     40 	pDst->usage = pSrc->usage;
     41 	pDst->interface_number = pSrc->interface_number;
     42 	pDst->next = NULL;
     43 }
     44 
     45 extern "C"
     46 {
     47 
     48 enum EHIDAPIType
     49 {
     50 	k_EHIDAPIUnknown,
     51 	k_EHIDAPIRAW,
     52 	k_EHIDAPIUSB
     53 };
     54 
     55 static CUtlHashMap<uintptr_t, EHIDAPIType> s_hashDeviceToAPI;
     56 
     57 static EHIDAPIType GetAPIForDevice( hid_device *pDevice )
     58 {
     59 	int iIndex = s_hashDeviceToAPI.Find( (uintptr_t)pDevice );
     60 	if ( iIndex != -1 )
     61 	{
     62 		return s_hashDeviceToAPI[ iIndex ];
     63 	}
     64 	return k_EHIDAPIUnknown;
     65 }
     66 
     67 struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
     68 {
     69 	struct HIDUSB::hid_device_info *usb_devs = HIDUSB::hid_enumerate( vendor_id, product_id );
     70 	struct HIDUSB::hid_device_info *usb_dev;
     71 	struct HIDRAW::hid_device_info *raw_devs = HIDRAW::hid_enumerate( vendor_id, product_id );
     72 	struct HIDRAW::hid_device_info *raw_dev;
     73 	struct hid_device_info *devs = NULL, *last = NULL, *new_dev;
     74 
     75 	for ( usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next )
     76 	{
     77 		bool bFound = false;
     78 		for ( raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next )
     79 		{
     80 			if ( usb_dev->vendor_id == raw_dev->vendor_id && usb_dev->product_id == raw_dev->product_id )
     81 			{
     82 				bFound = true;
     83 				break;
     84 			}
     85 		}
     86 
     87 //printf("%s USB device VID/PID 0x%.4x/0x%.4x, %ls %ls\n", bFound ? "Found matching" : "Added new", usb_dev->vendor_id, usb_dev->product_id, usb_dev->manufacturer_string, usb_dev->product_string );
     88 
     89 		if ( !bFound )
     90 		{
     91 			new_dev = new struct hid_device_info;
     92 			CopyHIDDeviceInfo( usb_dev, new_dev );
     93 
     94 			if ( last )
     95 			{
     96 				last->next = new_dev;
     97 			}
     98 			else
     99 			{
    100 				devs = new_dev;
    101 			}
    102 			last = new_dev;
    103 		}
    104 	}
    105 	HIDUSB::hid_free_enumeration( usb_devs );
    106 
    107 	for ( raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next )
    108 	{
    109 		new_dev = new struct hid_device_info;
    110 		CopyHIDDeviceInfo( raw_dev, new_dev );
    111 		new_dev->next = NULL;
    112 
    113 		if ( last )
    114 		{
    115 			last->next = new_dev;
    116 		}
    117 		else
    118 		{
    119 			devs = new_dev;
    120 		}
    121 		last = new_dev;
    122 	}
    123 	HIDRAW::hid_free_enumeration( raw_devs );
    124 
    125 	return devs;
    126 }
    127 
    128 void  HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
    129 {
    130 	while ( devs )
    131 	{
    132 		struct hid_device_info *next = devs->next;
    133 		free( devs->path );
    134 		free( devs->serial_number );
    135 		free( devs->manufacturer_string );
    136 		free( devs->product_string );
    137 		delete devs;
    138 		devs = next;
    139 	}
    140 }
    141 
    142 HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
    143 {
    144 	hid_device *pDevice = NULL;
    145 	if ( ( pDevice = (hid_device *)HIDRAW::hid_open( vendor_id, product_id, serial_number ) ) != NULL )
    146 	{
    147 		s_hashDeviceToAPI.Insert( (uintptr_t)pDevice, k_EHIDAPIRAW );
    148 		return pDevice;
    149 	}
    150 	if ( ( pDevice = (hid_device *)HIDUSB::hid_open( vendor_id, product_id, serial_number ) ) != NULL )
    151 	{
    152 		s_hashDeviceToAPI.Insert( (uintptr_t)pDevice, k_EHIDAPIUSB );
    153 		return pDevice;
    154 	}
    155 	return NULL;
    156 }
    157 
    158 HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bExclusive)
    159 {
    160 	hid_device *pDevice = NULL;
    161 	if ( ( pDevice = (hid_device *)HIDRAW::hid_open_path( path, bExclusive ) ) != NULL )
    162 	{
    163 		s_hashDeviceToAPI.Insert( (uintptr_t)pDevice, k_EHIDAPIRAW );
    164 		return pDevice;
    165 	}
    166 	if ( ( pDevice = (hid_device *)HIDUSB::hid_open_path( path, bExclusive ) ) != NULL )
    167 	{
    168 		s_hashDeviceToAPI.Insert( (uintptr_t)pDevice, k_EHIDAPIUSB );
    169 		return pDevice;
    170 	}
    171 	return NULL;
    172 }
    173 
    174 int  HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length)
    175 {
    176 	switch ( GetAPIForDevice( device ) )
    177 	{
    178 	case k_EHIDAPIRAW:
    179 		return HIDRAW::hid_write( (HIDRAW::hid_device*)device, data, length );
    180 	case k_EHIDAPIUSB:
    181 		return HIDUSB::hid_write( (HIDUSB::hid_device*)device, data, length );
    182 	default:
    183 		return -1;
    184 	} 
    185 }
    186 
    187 int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds)
    188 {
    189 	switch ( GetAPIForDevice( device ) )
    190 	{
    191 	case k_EHIDAPIRAW:
    192 		return HIDRAW::hid_read_timeout( (HIDRAW::hid_device*)device, data, length, milliseconds );
    193 	case k_EHIDAPIUSB:
    194 		return HIDUSB::hid_read_timeout( (HIDUSB::hid_device*)device, data, length, milliseconds );
    195 	default:
    196 		return -1;
    197 	} 
    198 }
    199 
    200 int  HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length)
    201 {
    202 	switch ( GetAPIForDevice( device ) )
    203 	{
    204 	case k_EHIDAPIRAW:
    205 		return HIDRAW::hid_read( (HIDRAW::hid_device*)device, data, length );
    206 	case k_EHIDAPIUSB:
    207 		return HIDUSB::hid_read( (HIDUSB::hid_device*)device, data, length );
    208 	default:
    209 		return -1;
    210 	} 
    211 }
    212 
    213 int  HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock)
    214 {
    215 	switch ( GetAPIForDevice( device ) )
    216 	{
    217 	case k_EHIDAPIRAW:
    218 		return HIDRAW::hid_set_nonblocking( (HIDRAW::hid_device*)device, nonblock );
    219 	case k_EHIDAPIUSB:
    220 		return HIDUSB::hid_set_nonblocking( (HIDUSB::hid_device*)device, nonblock );
    221 	default:
    222 		return -1;
    223 	} 
    224 }
    225 
    226 int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length)
    227 {
    228 	switch ( GetAPIForDevice( device ) )
    229 	{
    230 	case k_EHIDAPIRAW:
    231 		return HIDRAW::hid_send_feature_report( (HIDRAW::hid_device*)device, data, length );
    232 	case k_EHIDAPIUSB:
    233 		return HIDUSB::hid_send_feature_report( (HIDUSB::hid_device*)device, data, length );
    234 	default:
    235 		return -1;
    236 	} 
    237 }
    238 
    239 int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length)
    240 {
    241 	switch ( GetAPIForDevice( device ) )
    242 	{
    243 	case k_EHIDAPIRAW:
    244 		return HIDRAW::hid_get_feature_report( (HIDRAW::hid_device*)device, data, length );
    245 	case k_EHIDAPIUSB:
    246 		return HIDUSB::hid_get_feature_report( (HIDUSB::hid_device*)device, data, length );
    247 	default:
    248 		return -1;
    249 	} 
    250 }
    251 
    252 void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device)
    253 {
    254 	switch ( GetAPIForDevice( device ) )
    255 	{
    256 	case k_EHIDAPIRAW:
    257 		HIDRAW::hid_close( (HIDRAW::hid_device*)device );
    258 		break;
    259 	case k_EHIDAPIUSB:
    260 		HIDUSB::hid_close( (HIDUSB::hid_device*)device );
    261 		break;
    262 	default:
    263 		break;
    264 	} 
    265 	s_hashDeviceToAPI.Remove( (uintptr_t)device );
    266 }
    267 
    268 int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen)
    269 {
    270 	switch ( GetAPIForDevice( device ) )
    271 	{
    272 	case k_EHIDAPIRAW:
    273 		return HIDRAW::hid_get_manufacturer_string( (HIDRAW::hid_device*)device, string, maxlen );
    274 	case k_EHIDAPIUSB:
    275 		return HIDUSB::hid_get_manufacturer_string( (HIDUSB::hid_device*)device, string, maxlen );
    276 	default:
    277 		return -1;
    278 	} 
    279 }
    280 
    281 int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen)
    282 {
    283 	switch ( GetAPIForDevice( device ) )
    284 	{
    285 	case k_EHIDAPIRAW:
    286 		return HIDRAW::hid_get_product_string( (HIDRAW::hid_device*)device, string, maxlen );
    287 	case k_EHIDAPIUSB:
    288 		return HIDUSB::hid_get_product_string( (HIDUSB::hid_device*)device, string, maxlen );
    289 	default:
    290 		return -1;
    291 	}
    292 }
    293 
    294 int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen)
    295 {
    296 	switch ( GetAPIForDevice( device ) )
    297 	{
    298 	case k_EHIDAPIRAW:
    299 		return HIDRAW::hid_get_serial_number_string( (HIDRAW::hid_device*)device, string, maxlen );
    300 	case k_EHIDAPIUSB:
    301 		return HIDUSB::hid_get_serial_number_string( (HIDUSB::hid_device*)device, string, maxlen );
    302 	default:
    303 		return -1;
    304 	}
    305 }
    306 
    307 int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen)
    308 {
    309 	switch ( GetAPIForDevice( device ) )
    310 	{
    311 	case k_EHIDAPIRAW:
    312 		return HIDRAW::hid_get_indexed_string( (HIDRAW::hid_device*)device, string_index, string, maxlen );
    313 	case k_EHIDAPIUSB:
    314 		return HIDUSB::hid_get_indexed_string( (HIDUSB::hid_device*)device, string_index, string, maxlen );
    315 	default:
    316 		return -1;
    317 	}
    318 }
    319 
    320 HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device)
    321 {
    322 	switch ( GetAPIForDevice( device ) )
    323 	{
    324 	case k_EHIDAPIRAW:
    325 		return HIDRAW::hid_error( (HIDRAW::hid_device*)device );
    326 	case k_EHIDAPIUSB:
    327 		return HIDUSB::hid_error( (HIDUSB::hid_device*)device );
    328 	default:
    329 		return NULL;
    330 	} 
    331 }
    332 
    333 }