static void build_joystick_list(joy_hid_device_array_t *dev_array) { int i; int num_devices = dev_array->num_internal_devices; CFArrayRef devices = dev_array->internal_devices; joy_hid_device_t *d = dev_array->devices; for ( i = 0; i < num_devices ; i++ ) { IOHIDDeviceRef dev = ( IOHIDDeviceRef ) CFArrayGetValueAtIndex( devices, i ); if(is_joystick(dev)) { long vendor_id = 0; IOHIDDevice_GetLongProperty( dev, CFSTR( kIOHIDVendorIDKey ), &vendor_id ); long product_id = 0; IOHIDDevice_GetLongProperty( dev, CFSTR( kIOHIDProductIDKey ), &product_id ); CFStringRef product_key; product_key = IOHIDDeviceGetProperty( dev, CFSTR( kIOHIDProductKey ) ); char *product_name = "N/A"; if(product_key) { char buffer[256]; if(CFStringGetCString(product_key, buffer, 256, kCFStringEncodingUTF8)) { product_name = strdup(buffer); } } d->internal_device = dev; d->vendor_id = (int)vendor_id; d->product_id = (int)product_id; d->serial = 0; /* will be filled in later */ d->product_name = product_name; d++; } } }
int main( int argc, const char * argv[] ) { Boolean initialized = FALSE; if (( argc != 4 ) && ( argc != 5 )) { printf ( "usage: Dream Cheeky Notifier R G B [A]\n\tRGB values should be 0-31. A is an optional parameter on whether to do the LED activation sequence. Anything larger than 0 is YES, default is 0 (activate).\n\n"); exit ( -1 ); } char r = (int)strtol ( argv[1], NULL, 10 ); char g = (int)strtol ( argv[2], NULL, 10 ); char b = (int)strtol ( argv[3], NULL, 10 ); if ( argc == 5 ) { initialized = TRUE; } if ((r < 0) || (r > 31) || (g < 0) || (g > 31) || (b < 0) || (b > 31)) { printf("RGB values must be within 0-31."); exit -1; } // create a IO HID Manager reference IOHIDManagerRef tIOHIDManagerRef = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone ); // Create a device matching dictionary CFDictionaryRef matchingCFDictRef = hu_CreateMatchingDictionaryUsagePageUsage( TRUE, kHIDPage_GenericDesktop, 0x10 ); // set the HID device matching dictionary IOHIDManagerSetDeviceMatching( tIOHIDManagerRef, matchingCFDictRef ); if ( matchingCFDictRef ) { CFRelease( matchingCFDictRef ); } // Now open the IO HID Manager reference IOReturn tIOReturn = IOHIDManagerOpen( tIOHIDManagerRef, kIOHIDOptionsTypeNone ); // and copy out its devices CFSetRef deviceCFSetRef = IOHIDManagerCopyDevices( tIOHIDManagerRef ); // how many devices in the set? CFIndex deviceIndex, deviceCount = CFSetGetCount( deviceCFSetRef ); // allocate a block of memory to extact the device ref's from the set into IOHIDDeviceRef * tIOHIDDeviceRefs = malloc( sizeof( IOHIDDeviceRef ) * deviceCount ); // now extract the device ref's from the set CFSetGetValues( deviceCFSetRef, (const void **) tIOHIDDeviceRefs ); // before we get into the device loop we'll setup our element matching dictionary (Note: we don't do element matching anymore) matchingCFDictRef = hu_CreateMatchingDictionaryUsagePageUsage( FALSE, 0, 0 ); for ( deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++ ) { // if this isn't the notifier device... TODO: let's detect via vendor/product ids instead long vendor_id = 0; IOHIDDevice_GetLongProperty(tIOHIDDeviceRefs[deviceIndex], CFSTR(kIOHIDVendorIDKey), &vendor_id); long product_id = 0; IOHIDDevice_GetLongProperty(tIOHIDDeviceRefs[deviceIndex], CFSTR(kIOHIDProductIDKey), &product_id); if ((vendor_id != 0x1D34 ) || (product_id != 0x0004 )) { printf(" skipping device %p.\n", tIOHIDDeviceRefs[deviceIndex] ); continue; // ...skip it } printf( " device = %p.\n", tIOHIDDeviceRefs[deviceIndex] ); unsigned char report[8]; if (initialized == FALSE) { report[0] = 0x1F; // turn on LEDs report[1] = 0x02; report[2] = 0x00; report[3] = 0x5F; report[4] = 0x00; report[5] = 0x00; report[6] = 0x1A; report[7] = 0x03; // Note: We don't use the returned value here, so the compiler might throw a warning. IOReturn tIOReturn = IOHIDDeviceSetReport( tIOHIDDeviceRefs[deviceIndex], // IOHIDDeviceRef for the HID device kIOHIDReportTypeInput, // IOHIDReportType for the report (input, output, feature) 0, // CFIndex for the report ID report, // address of report buffer 8); // length of the report initialized = TRUE; } report[0] = r; // set brightness on LEDs to r, g, & b report[1] = g; report[2] = b; report[3] = 0x00; report[4] = 0x00; report[5] = 0x00; report[6] = 0x1A; report[7] = 0x05; tIOReturn = IOHIDDeviceSetReport( tIOHIDDeviceRefs[deviceIndex], // IOHIDDeviceRef for the HID device kIOHIDReportTypeInput, // IOHIDReportType for the report (input, output, feature) 0, // CFIndex for the report ID report, // address of report buffer 8); // length of the report next_device: ; continue; } if ( tIOHIDManagerRef ) { CFRelease( tIOHIDManagerRef ); } if ( matchingCFDictRef ) { CFRelease( matchingCFDictRef ); } Oops: ; return -1; } /* main */
IOHIDTransactionRef IOHIDDevice_GetTransaction( IOHIDDeviceRef inIOHIDDeviceRef ) { IOHIDTransactionRef result = 0; ( void ) IOHIDDevice_GetLongProperty( inIOHIDDeviceRef, CFSTR( kIOHIDDevice_TransactionKey ), ( long * ) &result ); return result; }
uint32_t IOHIDDevice_GetPrimaryUsagePage( IOHIDDeviceRef inIOHIDDeviceRef ) { long result = 0; ( void ) IOHIDDevice_GetLongProperty( inIOHIDDeviceRef, CFSTR( kIOHIDPrimaryUsagePageKey ), &result ); return result; }
uint32_t IOHIDDevice_GetUsage( IOHIDDeviceRef inIOHIDDeviceRef ) { uint32_t result = 0; ( void ) IOHIDDevice_GetLongProperty( inIOHIDDeviceRef, CFSTR( kIOHIDDeviceUsageKey ), ( long * ) &result ); return result; } // IOHIDDevice_GetUsage
long IOHIDDevice_GetLocationID( IOHIDDeviceRef inIOHIDDeviceRef ) { long result = 0; ( void ) IOHIDDevice_GetLongProperty( inIOHIDDeviceRef, CFSTR( kIOHIDLocationIDKey ), &result ); return result; } // IOHIDDevice_GetLocationID
long IOHIDDevice_GetVersionNumber( IOHIDDeviceRef inIOHIDDeviceRef ) { long result = 0; ( void ) IOHIDDevice_GetLongProperty( inIOHIDDeviceRef, CFSTR( kIOHIDVersionNumberKey ), &result ); return result; }