void setKeyboard(struct __IOHIDDevice *device, CFDictionaryRef keyboardDictionary, LedState changes[]) { CFStringRef deviceNameRef = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)); if (!deviceNameRef) return; const char * deviceName = CFStringGetCStringPtr(deviceNameRef, kCFStringEncodingUTF8); if (nameMatch && fnmatch(nameMatch, deviceName, 0) != 0) return; if (verbose) printf("\n \"%s\" ", deviceName); CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device, keyboardDictionary, kIOHIDOptionsTypeNone); if (elements) { for (CFIndex elementIndex = 0; elementIndex < CFArrayGetCount(elements); elementIndex++) { IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, elementIndex); if (element && kHIDPage_LEDs == IOHIDElementGetUsagePage(element)) { uint32_t led = IOHIDElementGetUsage(element); if (led >= maxLeds) break; // Get current keyboard led status IOHIDValueRef currentValue = 0; if (IOHIDDeviceGetValue(device, element, ¤tValue) == kIOReturnSuccess && IOHIDValueGetLength(currentValue) < 3) { long current = IOHIDValueGetIntegerValue(currentValue); CFRelease(currentValue); // Should we try to set the led? if (changes[led] != NoChange && changes[led] != current) { IOHIDValueRef newValue = IOHIDValueCreateWithIntegerValue(kCFAllocatorDefault, element, 0, changes[led]); if (newValue) { IOReturn changeResult = IOHIDDeviceSetValue(device, element, newValue); // Was the change successful? if (kIOReturnSuccess == changeResult && verbose) { printf("%s%s ", stateSymbol[changes[led]], ledNames[led - 1]); } CFRelease(newValue); } } else if (verbose) { printf("%s%s ", stateSymbol[current], ledNames[led - 1]); } } } } CFRelease(elements); } if (verbose) printf("\n"); }
static void onDeviceValueChanged(void * context, IOReturn result, void * sender, IOHIDValueRef value) { struct Gamepad_device * deviceRecord; struct Gamepad_devicePrivate * hidDeviceRecord; IOHIDElementRef element; IOHIDElementCookie cookie; unsigned int axisIndex, buttonIndex; static mach_timebase_info_data_t timebaseInfo; if (timebaseInfo.denom == 0) { mach_timebase_info(&timebaseInfo); } deviceRecord = context; hidDeviceRecord = deviceRecord->privateData; element = IOHIDValueGetElement(value); cookie = IOHIDElementGetCookie(element); for (axisIndex = 0; axisIndex < deviceRecord->numAxes; axisIndex++) { if (!hidDeviceRecord->axisElements[axisIndex].isHatSwitchSecondAxis && hidDeviceRecord->axisElements[axisIndex].cookie == cookie) { CFIndex integerValue; if (IOHIDValueGetLength(value) > 4) { // Workaround for a strange crash that occurs with PS3 controller; was getting lengths of 39 (!) continue; } integerValue = IOHIDValueGetIntegerValue(value); if (hidDeviceRecord->axisElements[axisIndex].isHatSwitch) { int x, y; // Fix for Saitek X52 if (!hidDeviceRecord->axisElements[axisIndex].hasNullState) { if (integerValue < hidDeviceRecord->axisElements[axisIndex].logicalMin) { integerValue = hidDeviceRecord->axisElements[axisIndex].logicalMax - hidDeviceRecord->axisElements[axisIndex].logicalMin + 1; } else { integerValue--; } } hatValueToXY(integerValue, hidDeviceRecord->axisElements[axisIndex].logicalMax - hidDeviceRecord->axisElements[axisIndex].logicalMin + 1, &x, &y); if (x != deviceRecord->axisStates[axisIndex]) { queueAxisEvent(deviceRecord, IOHIDValueGetTimeStamp(value) * timebaseInfo.numer / timebaseInfo.denom * 0.000000001, axisIndex, x, deviceRecord->axisStates[axisIndex]); deviceRecord->axisStates[axisIndex] = x; } if (y != deviceRecord->axisStates[axisIndex + 1]) { queueAxisEvent(deviceRecord, IOHIDValueGetTimeStamp(value) * timebaseInfo.numer / timebaseInfo.denom * 0.000000001, axisIndex + 1, y, deviceRecord->axisStates[axisIndex + 1]); deviceRecord->axisStates[axisIndex + 1] = y; } } else { float floatValue; if (integerValue < hidDeviceRecord->axisElements[axisIndex].logicalMin) { hidDeviceRecord->axisElements[axisIndex].logicalMin = integerValue; } if (integerValue > hidDeviceRecord->axisElements[axisIndex].logicalMax) { hidDeviceRecord->axisElements[axisIndex].logicalMax = integerValue; } floatValue = (integerValue - hidDeviceRecord->axisElements[axisIndex].logicalMin) / (float) (hidDeviceRecord->axisElements[axisIndex].logicalMax - hidDeviceRecord->axisElements[axisIndex].logicalMin) * 2.0f - 1.0f; queueAxisEvent(deviceRecord, IOHIDValueGetTimeStamp(value) * timebaseInfo.numer / timebaseInfo.denom * 0.000000001, axisIndex, floatValue, deviceRecord->axisStates[axisIndex]); deviceRecord->axisStates[axisIndex] = floatValue; } return; } } for (buttonIndex = 0; buttonIndex < deviceRecord->numButtons; buttonIndex++) { if (hidDeviceRecord->buttonElements[buttonIndex].cookie == cookie) { bool down; down = IOHIDValueGetIntegerValue(value); queueButtonEvent(deviceRecord, IOHIDValueGetTimeStamp(value) * timebaseInfo.numer / timebaseInfo.denom * 0.000000001, buttonIndex, down); deviceRecord->buttonStates[buttonIndex] = down; return; } } }
void GPUSB_SetBit(int bit, int val) { if (!pGPUSB) return; // no device, bail IOHIDElementRef pCurrentHIDElement = NULL; //IOHIDEventStruct HID_IOEvent; int i; static int bitarray[8]={0,0,0,0,1,1,0,0}; static unsigned char GPUSB_reg = 0x30; if (GPUSB_Model) { // Newer models - use a single byte pCurrentHIDElement = GetFirstOutputElement(pGPUSB); if(pCurrentHIDElement == NULL) { wxMessageBox(std::string(__PRETTY_FUNCTION__) + " Null element"); return; } // HIDTransactionAddElement(pGPUSB,pCurrentHIDElement); unsigned char bmask = 1; bmask = bmask << bit; if (val) { GPUSB_reg = GPUSB_reg | bmask; } else { GPUSB_reg = GPUSB_reg & ~bmask; } //HID_IOEvent.longValueSize = 0; //HID_IOEvent.longValue = nil; /*IOHIDValueRef valueToSend = IOHIDValueCreateWithBytes( kCFAllocatorDefault, pCurrentHIDElement, uint64_t inTimeStamp, &GPUSB_reg, 1); */ //IOHIDElementCookie cookie = IOHIDElementGetCookie(pCurrentHIDElement); IOHIDValueRef valueToSend; IOReturn tIOReturn = IOHIDDeviceGetValue(pGPUSB, pCurrentHIDElement, &valueToSend); if(tIOReturn != kIOReturnSuccess) { CFRelease(pCurrentHIDElement); wxMessageBox(std::string(__PRETTY_FUNCTION__) + " Cannot retrieve value (1)"); return; } assert(IOHIDValueGetLength(valueToSend) == 1); IOHIDValueRef valueToSendCopied = IOHIDValueCreateWithBytes( kCFAllocatorDefault, pCurrentHIDElement, IOHIDValueGetTimeStamp(valueToSend), &GPUSB_reg, 1); tIOReturn = IOHIDDeviceSetValue(pGPUSB, pCurrentHIDElement, valueToSendCopied); if(tIOReturn != kIOReturnSuccess) { CFRelease(pCurrentHIDElement); wxMessageBox(std::string(__PRETTY_FUNCTION__) + " Cannot send value (1)"); return; } //pGPUSB_interface->getElementValue (pGPUSB_interface, cookie, &HID_IOEvent); //HID_IOEvent.value = (SInt32) GPUSB_reg; // wxMessageBox(wxString::Format("%x - %x %x %d %d",foo,GPUSB_reg,bmask,bit,val)); // HID_IOEvent.type = (IOHIDElementType) pCurrentHIDElement->type; //HIDSetElementValue(pGPUSB,pCurrentHIDElement,&HID_IOEvent); // HIDTransactionCommit(pGPUSB); CFRelease(pCurrentHIDElement); } else { // Generic bit-set routine. For older adapters, we can't send a whole // byte and things are setup as SInt32's per bit with 8 bits total... //IOHIDEventStruct hidstruct = {kIOHIDElementTypeOutput}; IOHIDTransactionRef transaction = IOHIDTransactionCreate( kCFAllocatorDefault, pGPUSB, kIOHIDTransactionDirectionTypeOutput, kIOHIDOptionsTypeNone); if(transaction == NULL) { wxMessageBox(std::string(__PRETTY_FUNCTION__) + " Cannot create a transaction"); } bitarray[bit]=val; // std::cout << "Setting to "; for (i=0; i<8; i++) { // write // std::cout << " " << bitarray[i]; if (i==0) { pCurrentHIDElement = GetFirstOutputElement(pGPUSB); } else { pCurrentHIDElement = GetNextOutputElement(pGPUSB, pCurrentHIDElement); } IOHIDValueRef valueToSend; IOReturn tIOReturn = IOHIDDeviceGetValue(pGPUSB, pCurrentHIDElement, &valueToSend); if(tIOReturn != kIOReturnSuccess) { CFRelease(pCurrentHIDElement); wxMessageBox(std::string(__PRETTY_FUNCTION__) + " Cannot retrieve value (1)"); return; } //CFTypeID tID = IOHIDValueGetTypeID(valueToSend); /*IOHIDValueRef valueToSendCopied = IOHIDValueCreateWithBytes( kCFAllocatorDefault, pCurrentHIDElement, IOHIDValueGetTimeStamp(valueToSend), &bitarray[i], sizeof(bitarray[i])); */ IOHIDValueRef valueToSendCopied = IOHIDValueCreateWithIntegerValue( kCFAllocatorDefault, pCurrentHIDElement, IOHIDValueGetTimeStamp(valueToSend), bitarray[i]); IOHIDTransactionAddElement(transaction, pCurrentHIDElement); IOHIDTransactionSetValue(transaction, pCurrentHIDElement, valueToSendCopied, 0); //HIDTransactionAddElement(pGPUSB,pCurrentHIDElement); //hidstruct.type = (IOHIDElementType) pCurrentHIDElement->type; //hidstruct.value = (SInt32) bitarray[i]; //HIDTransactionSetElementValue(pGPUSB,pCurrentHIDElement,&hidstruct); } // std::cout << "\n"; IOHIDTransactionCommit(transaction); } // wxMilliSleep(30); }