Example #1
0
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, &currentValue) == 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;
    }
  }
}
Example #3
0
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);
}