Atlas - hid.cpp
Home / ext / SDL2 / src / hidapi / linux Lines: 2 | Size: 9327 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]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 29template <class T> 30void 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 45extern "C" 46{ 47 48enum EHIDAPIType 49{ 50 k_EHIDAPIUnknown, 51 k_EHIDAPIRAW, 52 k_EHIDAPIUSB 53}; 54 55static CUtlHashMap<uintptr_t, EHIDAPIType> s_hashDeviceToAPI; 56 57static 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 67struct 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 128void 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 142HID_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 158HID_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 174int 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 187int 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 200int 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 213int 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 226int 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 239int 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 252void 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 268int 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 281int 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 294int 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 307int 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 320HID_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} 334[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.