Ejemplo n.º 1
0
/**************************************************************************
 *                              button_usage_comparator
 */
static CFComparisonResult button_usage_comparator(const void *val1, const void *val2, void *context)
{
    IOHIDElementRef element1 = (IOHIDElementRef)val1, element2 = (IOHIDElementRef)val2;
    int usage1 = IOHIDElementGetUsage(element1), usage2 = IOHIDElementGetUsage(element2);

    if (usage1 < usage2)
        return kCFCompareLessThan;
    if (usage1 > usage2)
        return kCFCompareGreaterThan;
    return kCFCompareEqualTo;
}
Ejemplo n.º 2
0
// NOTE: I pieced this together through trial and error, any corrections are welcome
static void hid_device_input_callback(void* context, IOReturn result, void* sender, IOHIDValueRef value)
{
   struct apple_pad_connection* connection = (struct apple_pad_connection*)context;

   IOHIDElementRef element = IOHIDValueGetElement(value);
   uint32_t type = IOHIDElementGetType(element);
   uint32_t page = IOHIDElementGetUsagePage(element);
   uint32_t use = IOHIDElementGetUsage(element);

   // Joystick handler: TODO: Can GamePad work the same?
   if (type == kIOHIDElementTypeInput_Button && page == kHIDPage_Button)
   {
      CFIndex state = IOHIDValueGetIntegerValue(value);

      if (state)  g_current_input_data.pad_buttons[connection->slot] |= (1 << (use - 1));
      else        g_current_input_data.pad_buttons[connection->slot] &= ~(1 << (use - 1));
   }
   else if (type == kIOHIDElementTypeInput_Misc && page == kHIDPage_GenericDesktop)
   {
      static const uint32_t axis_use_ids[4] = { 48, 49, 50, 53 };
      for (int i = 0; i < 4; i ++)
      {
         if (use == axis_use_ids[i])
         {
            CFIndex min = IOHIDElementGetPhysicalMin(element);
            CFIndex max = IOHIDElementGetPhysicalMax(element) - min;
            CFIndex state = IOHIDValueGetIntegerValue(value) - min;
         
            float val = (float)state / (float)max;
            g_current_input_data.pad_axis[connection->slot][i] = ((val * 2.0f) - 1.0f) * 32767.0f;
         }
      }
   }
}
Ejemplo n.º 3
0
void updateindicators(usbdevice* kb, int force){
    // Set NumLock on permanently
    char ileds = 1;
    // Set Caps Lock if enabled. Unlike Linux, OSX keyboards have independent caps lock states, so
    // we use the last-assigned value rather than fetching it from the system
    if(kb->eflags & kCGEventFlagMaskAlphaShift)
        ileds |= 2;
    if(force || ileds != kb->ileds){
        kb->ileds = ileds;
        // Set the LEDs
        CFArrayRef leds = IOHIDDeviceCopyMatchingElements(kb->handles[0], 0, kIOHIDOptionsTypeNone);
        CFIndex count = CFArrayGetCount(leds);
        for(CFIndex i = 0; i < count; i++){
            IOHIDElementRef led = (void*)CFArrayGetValueAtIndex(leds, i);
            uint32_t page = IOHIDElementGetUsagePage(led);
            if(page != kHIDPage_LEDs)
                continue;
            uint32_t usage = IOHIDElementGetUsage(led);
            IOHIDValueRef value = IOHIDValueCreateWithIntegerValue(kCFAllocatorDefault, led, 0, !!(ileds & (1 << (usage - 1))));
            IOHIDDeviceSetValue(kb->handles[0], led, value);
            CFRelease(value);
        }
        CFRelease(leds);
        IOHIDDeviceSetReport(kb->handles[1], kIOHIDReportTypeOutput, 0, &kb->ileds, 1);
    }
}
Ejemplo n.º 4
0
static void input_callback(void *ctx, IOReturn result, void *sender, IOHIDValueRef value)
{
	struct osx_mouse_data *mdata = static_cast<struct osx_mouse_data *>(ctx);
	IOHIDElementRef elem = IOHIDValueGetElement(value);
	uint32_t page = IOHIDElementGetUsagePage(elem);
	uint32_t usage = IOHIDElementGetUsage(elem);
	uint32_t val = IOHIDValueGetIntegerValue(value);

	if (page == kHIDPage_GenericDesktop) {
		switch (usage) {
			case kHIDUsage_GD_X:
				SDL_LockMutex(mdata->mouse_mutex);
				mdata->mouse_x += val;
				SDL_UnlockMutex(mdata->mouse_mutex);
				break;
			case kHIDUsage_GD_Y:
				SDL_LockMutex(mdata->mouse_mutex);
				mdata->mouse_y += val;
				SDL_UnlockMutex(mdata->mouse_mutex);
				break;
			default:
				break;
		}
	}
}
Ejemplo n.º 5
0
    void analog_event(IOReturn result, IOHIDElementRef element, IOHIDValueRef value) {
        int int_value = IOHIDValueGetIntegerValue(value);
        uint16_t usage = IOHIDElementGetUsage(element);
        switch (usage) {
          case kHIDUsage_GD_X:
          case kHIDUsage_GD_Y:
          case kHIDUsage_GD_Rx:
          case kHIDUsage_GD_Ry:
            {
                int min = IOHIDElementGetLogicalMin(element);
                int max = IOHIDElementGetLogicalMax(element);
                double double_value = int_value;
                if (int_value < 0) {
                    double_value = -(double_value / min);
                } else {
                    double_value = (double_value / max);
                }

                usage -= kHIDUsage_GD_X;
                gamepad[usage] = double_value;
                static const int x_component[] = {0, 0, -1, 3, 3, -1};
                double x = gamepad[x_component[usage]];
                double y = gamepad[x_component[usage] + 1];
                enqueue(new GamepadStickEvent(
                            now_usecs(), kHIDUsage_GD_X + x_component[usage], x, y));
            }
            break;
          case kHIDUsage_GD_Z:
          case kHIDUsage_GD_Rz:
            button_event(result, element, value);
            break;
        }
    }
Ejemplo n.º 6
0
void os_updateindicators(usbdevice* kb, int force){
    if(!IS_CONNECTED(kb) || NEEDS_FW_UPDATE(kb))
        return;
    // Set NumLock on permanently
    char ileds = 1;
    // Set Caps Lock if enabled. Unlike Linux, OSX keyboards have independent caps lock states, so
    // we use the last-assigned value rather than fetching it from the system
    if(kb->eventflags & kCGEventFlagMaskAlphaShift)
        ileds |= 2;
    usbmode* mode = kb->profile.currentmode;
    if(mode && kb->active)
        ileds = (ileds & ~mode->ioff) | mode->ion;
    if(force || ileds != kb->ileds){
        kb->ileds = ileds;
        // Set the LEDs
        CFArrayRef leds = IOHIDDeviceCopyMatchingElements(kb->handles[0], 0, kIOHIDOptionsTypeNone);
        CFIndex count = CFArrayGetCount(leds);
        for(CFIndex i = 0; i < count; i++){
            IOHIDElementRef led = (void*)CFArrayGetValueAtIndex(leds, i);
            uint32_t page = IOHIDElementGetUsagePage(led);
            if(page != kHIDPage_LEDs)
                continue;
            uint32_t usage = IOHIDElementGetUsage(led);
            IOHIDValueRef value = IOHIDValueCreateWithIntegerValue(kCFAllocatorDefault, led, 0, !!(ileds & (1 << (usage - 1))));
            IOHIDDeviceSetValue(kb->handles[0], led, value);
            CFRelease(value);
        }
        CFRelease(leds);
    }
}
// Set up a config record for saving
// takes an input records, returns record user can save as they want 
// Note: the save rec must be pre-allocated by the calling app and will be filled out
void HIDSetElementConfig (pRecSaveHID pConfigRec, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHIDElementRef, int actionCookie)
{
	// must save:
    // actionCookie
    // Device: serial,vendorID, productID, location, usagePage, usage
    // Element: cookie, usagePage, usage,
    pConfigRec->actionCookie = actionCookie;
    // device
    // need to add serial number when I have a test case
	if (inIOHIDDeviceRef && inIOHIDElementRef) {
		pConfigRec->device.vendorID = IOHIDDevice_GetVendorID( inIOHIDDeviceRef );
		pConfigRec->device.productID = IOHIDDevice_GetProductID( inIOHIDDeviceRef );
		pConfigRec->device.locID = IOHIDDevice_GetLocationID( inIOHIDDeviceRef );
		pConfigRec->device.usage = IOHIDDevice_GetUsage( inIOHIDDeviceRef );
		pConfigRec->device.usagePage = IOHIDDevice_GetUsagePage( inIOHIDDeviceRef );
		
		pConfigRec->element.usagePage = IOHIDElementGetUsagePage( inIOHIDElementRef );
		pConfigRec->element.usage = IOHIDElementGetUsage( inIOHIDElementRef );
		pConfigRec->element.minReport = IOHIDElement_GetCalibrationSaturationMin( inIOHIDElementRef );
		pConfigRec->element.maxReport = IOHIDElement_GetCalibrationSaturationMax( inIOHIDElementRef );
		pConfigRec->element.cookie = IOHIDElementGetCookie( inIOHIDElementRef );
	} else {
		pConfigRec->device.vendorID = 0;
		pConfigRec->device.productID = 0;
		pConfigRec->device.locID = 0;
		pConfigRec->device.usage = 0;
		pConfigRec->device.usagePage = 0;
		
		pConfigRec->element.usagePage = 0;
		pConfigRec->element.usage = 0;
		pConfigRec->element.minReport = 0;
		pConfigRec->element.maxReport = 0;
		pConfigRec->element.cookie = 0;
	}
}
Ejemplo n.º 8
0
bool HIDGamepad::maybeAddButton(IOHIDElementRef element)
{
    uint32_t usagePage = IOHIDElementGetUsagePage(element);
    if (usagePage != kHIDPage_Button && usagePage != kHIDPage_GenericDesktop)
        return false;

    uint32_t usage = IOHIDElementGetUsage(element);

    if (usagePage == kHIDPage_GenericDesktop) {
        if (usage < kHIDUsage_GD_DPadUp || usage > kHIDUsage_GD_DPadLeft)
            return false;
        usage = std::numeric_limits<uint32_t>::max();
    } else if (!usage)
        return false;

    CFIndex min = IOHIDElementGetLogicalMin(element);
    CFIndex max = IOHIDElementGetLogicalMax(element);

    m_buttons.append(makeUniqueRef<HIDGamepadButton>(usage, min, max, element));

    IOHIDElementCookie cookie = IOHIDElementGetCookie(element);
    m_elementMap.set(cookie, &m_buttons.last().get());

    return true;
}
Ejemplo n.º 9
0
static CFIndex find_top_level(IOHIDDeviceRef tIOHIDDeviceRef, CFArrayRef topLevels)
{
    CFArrayRef      gElementCFArrayRef;
    CFIndex         numTops = 0;

    if (!tIOHIDDeviceRef)
        return 0;

    gElementCFArrayRef = IOHIDDeviceCopyMatchingElements(tIOHIDDeviceRef, NULL, 0);

    if (gElementCFArrayRef)
    {
        CFIndex idx, cnt = CFArrayGetCount(gElementCFArrayRef);
        for (idx=0; idx<cnt; idx++)
        {
            IOHIDElementRef tIOHIDElementRef = (IOHIDElementRef)CFArrayGetValueAtIndex(gElementCFArrayRef, idx);
            int eleType = IOHIDElementGetType(tIOHIDElementRef);

            /* Check for top-level gaming device collections */
            if (eleType == kIOHIDElementTypeCollection && IOHIDElementGetParent(tIOHIDElementRef) == 0)
            {
                int tUsagePage = IOHIDElementGetUsagePage(tIOHIDElementRef);
                int tUsage = IOHIDElementGetUsage(tIOHIDElementRef);

                if (tUsagePage == kHIDPage_GenericDesktop &&
                        (tUsage == kHIDUsage_GD_Joystick || tUsage == kHIDUsage_GD_GamePad))
                {
                    CFArrayAppendValue((CFMutableArrayRef)topLevels, tIOHIDElementRef);
                    numTops++;
                }
            }
        }
    }
    return numTops;
}
Ejemplo n.º 10
0
int  joy_hidlib_enumerate_elements(joy_hid_device_t *device)
{
    IOHIDDeviceRef dev = device->internal_device;
    if(dev == NULL) {
        return -1;
    }
    
    /* get all elements of device */
    CFArrayRef internal_elements = IOHIDDeviceCopyMatchingElements( dev, NULL, 0 );    
    if(!internal_elements) {
        return -1;
    }
    
    /* get number of elements */
    CFIndex cnt = CFArrayGetCount( internal_elements );
    device->num_elements = (int)cnt;
    
    /* create elements array */
    joy_hid_element_t *elements = (joy_hid_element_t *)
        lib_malloc(sizeof(joy_hid_element_t) * cnt);
    if(elements == NULL) {
        CFRelease(internal_elements);
        internal_elements = NULL;
        return -1;
    }
    
    /* enumerate and convert all elements */
    CFIndex i;
    joy_hid_element_t *e = elements;
    for(i=0;i<cnt;i++) { 
        IOHIDElementRef internal_element = 
            ( IOHIDElementRef ) CFArrayGetValueAtIndex( internal_elements, i );
        if ( internal_element ) {
            uint32_t usage_page = IOHIDElementGetUsagePage( internal_element );
            uint32_t usage = IOHIDElementGetUsage( internal_element );
            CFIndex min = IOHIDElementGetPhysicalMin( internal_element );
            CFIndex max = IOHIDElementGetPhysicalMax( internal_element );
            
            e->usage_page = (int)usage_page;
            e->usage      = (int)usage;
            e->min_value  = (int)min;
            e->max_value  = (int)max;
            e->internal_element = internal_element;
        } else {
            e->usage_page = -1;
            e->usage      = -1;
            e->min_value  = -1;
            e->max_value  = -1;
            e->internal_element = NULL;
        }
        e++;
    }
    
    /* keep the reference until the elements are free'ed again */
    device->internal_elements = internal_elements;
    device->elements = elements;
    
    return (int)cnt;
}
Ejemplo n.º 11
0
CFComparisonResult iohidmanager_sort_elements(const void *val1, const void *val2, void *context)
{
   uint32_t page1   = (uint32_t)IOHIDElementGetUsagePage((IOHIDElementRef)val1);
   uint32_t page2   = (uint32_t)IOHIDElementGetUsagePage((IOHIDElementRef)val2);
   uint32_t use1    = (uint32_t)IOHIDElementGetUsage((IOHIDElementRef)val1);
   uint32_t use2    = (uint32_t)IOHIDElementGetUsage((IOHIDElementRef)val2);
   uint32_t cookie1 = (uint32_t)IOHIDElementGetCookie((IOHIDElementRef)val1);
   uint32_t cookie2 = (uint32_t)IOHIDElementGetCookie((IOHIDElementRef)val2);

   if (page1 != page2)
      return (CFComparisonResult)(page1 > page2);

   if(use1 != use2)
       return (CFComparisonResult)(use1 > use2);

   return (CFComparisonResult)(cookie1 > cookie2);
}
  void
  osxHIDPointingDevice::hidQueueCallback(void *context, IOReturn /*result*/, void *sender) {
    // std::cerr << "osxHIDPointingDevice::hidQueueCallback" << std::endl ;
    
    osxHIDPointingDevice *self = (osxHIDPointingDevice*)context ;
    IOHIDQueueRef queue = (IOHIDQueueRef)sender ;

    while (true) {

      IOHIDValueRef hidvalue = IOHIDQueueCopyNextValueWithTimeout(queue, 0.) ;
      if (!hidvalue) break ;

#if 1
      TimeStamp::inttime uptime = AbsoluteTimeInNanoseconds(IOHIDValueGetTimeStamp(hidvalue)) ;
      TimeStamp::inttime timestamp = self->epoch + (uptime - self->epoch_mach)*TimeStamp::one_nanosecond ;
#else

      TimeStamp::inttime timestamp = TimeStamp::createAsInt() ;
#endif

      if (self->qreport.isOlderThan(timestamp)) {
	// Flush the old qreport before creating a new one
	self->report(self->qreport) ;
	self->qreport.clear() ;
      }

      IOHIDElementRef element = IOHIDValueGetElement(hidvalue) ;
      uint32_t usagepage = IOHIDElementGetUsagePage(element) ;
      uint32_t usage = IOHIDElementGetUsage(element) ;
      //std::cout << usagepage << std::endl;
      //std::cout << usage << std::endl;
      if (usagepage==kHIDPage_GenericDesktop) {
	if (usage==kHIDUsage_GD_X || usage==kHIDUsage_GD_Y) {
      // Could use IOHIDValueGetScaledValue(hidvalue, kIOHIDValueScaleTypePhysical)
      CFIndex d = IOHIDValueGetIntegerValue(hidvalue) ;

      //std::cout << IOHIDValueGetBytePtr(hidvalue) << std::endl;
      //std::cout << IOHIDValueGetLength(hidvalue) << std::endl;
      if (d) {
	    if (usage==kHIDUsage_GD_X) self->qreport.dx = (int32_t)d ; else self->qreport.dy = (int32_t)d ;
	    self->qreport.t = timestamp ;
	  }
	}
	// FIXME: GD_Z, GD_Wheel, etc.
      } else if (usagepage==kHIDPage_Button) {
	// kHIDUsage_Button_1 is 1
	self->qreport.setButton(usage-1, (uint32_t)IOHIDValueGetIntegerValue(hidvalue)) ;
	self->qreport.t = timestamp ;
      }

      CFRelease(hidvalue) ;
    }

    // Flush the qreport we were constructing, if any
    if (self->qreport.t!=TimeStamp::undef)
      self->report(self->qreport) ;
    self->qreport.clear() ;
  }
Ejemplo n.º 13
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");
}
Ejemplo n.º 14
0
 void button_event(IOReturn result, IOHIDElementRef element, IOHIDValueRef value) {
     if (!antares_is_active()) {
         return;
     }
     bool down = IOHIDValueGetIntegerValue(value);
     uint16_t usage = IOHIDElementGetUsage(element);
     if (down) {
         enqueue(new GamepadButtonDownEvent(now_usecs(), usage));
     } else {
         enqueue(new GamepadButtonUpEvent(now_usecs(), usage));
     }
 }
Boolean HIDSaveElementPref( const CFStringRef inKeyCFStringRef,
						   CFStringRef inAppCFStringRef,
						   IOHIDDeviceRef inIOHIDDeviceRef,
						   IOHIDElementRef inIOHIDElementRef )
{
	Boolean success = FALSE;
	
	if ( inKeyCFStringRef && inAppCFStringRef && inIOHIDDeviceRef && inIOHIDElementRef ) {
		long vendorID = IOHIDDevice_GetVendorID( inIOHIDDeviceRef );
		require( vendorID, Oops );
		
		long productID = IOHIDDevice_GetProductID( inIOHIDDeviceRef );
		require( productID, Oops );
		
		long locID = IOHIDDevice_GetLocationID( inIOHIDDeviceRef );
		require( locID, Oops );
		
		uint32_t usagePage = IOHIDDevice_GetUsagePage( inIOHIDDeviceRef );
		uint32_t usage = IOHIDDevice_GetUsage( inIOHIDDeviceRef );
		
		if ( !usagePage || !usage ) {
			usagePage = IOHIDDevice_GetPrimaryUsagePage( inIOHIDDeviceRef );
			usage = IOHIDDevice_GetPrimaryUsage( inIOHIDDeviceRef );
		}
		require( usagePage && usage, Oops );
		
		uint32_t usagePageE = IOHIDElementGetUsagePage( inIOHIDElementRef );
		uint32_t usageE = IOHIDElementGetUsage( inIOHIDElementRef );
		IOHIDElementCookie eleCookie = IOHIDElementGetCookie( inIOHIDElementRef );
		
		CFStringRef prefCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL,
															   CFSTR( "d:{v:%ld, p:%ld, l:%ld, p:%ld, u:%ld}, e:{p:%ld, u:%ld, c:%ld}" ),
															   vendorID,
															   productID,
															   locID,
															   usagePage,
															   usage,
															   usagePageE,
															   usageE,
															   eleCookie );
		
		if ( prefCFStringRef ) {
			CFPreferencesSetAppValue( inKeyCFStringRef, prefCFStringRef, inAppCFStringRef );
			CFRelease( prefCFStringRef );
			success = TRUE;
		}
	}
Oops:   ;
	return success;
}   // HIDSaveElementPref
Ejemplo n.º 16
0
void CPH_HidMacOSX::InputValueCallback(IOHIDValueRef valueRef)
{
	IOHIDElementRef elementRef = IOHIDValueGetElement(valueRef);
	uint32 usage = IOHIDElementGetUsage(elementRef);
	uint32 usagePage = IOHIDElementGetUsagePage(elementRef);
	CFIndex state = IOHIDValueGetIntegerValue(valueRef);
	if(usagePage != kHIDPage_KeyboardOrKeypad) return;
	for(auto bindingIterator(std::begin(m_bindings));
	    bindingIterator != std::end(m_bindings); bindingIterator++)
	{
		const auto& binding = (*bindingIterator);
		if(!binding) continue;
		binding->ProcessEvent(usage, state);
	}
}
Ejemplo n.º 17
0
// Set up a config record for saving
// takes an input records, returns record user can save as they want
// Note: the save rec must be pre-allocated by the calling app and will be filled out
void HIDSetElementConfig(HID_info_ptr		inHIDInfoPtr,
                         IOHIDDeviceRef		inIOHIDDeviceRef,
                         IOHIDElementRef	inIOHIDElementRef,
                         IOHIDElementCookie actionCookie) {
	// must save:
	// actionCookie
	// Device: serial,vendorID, productID, location, usagePage, usage
	// Element: cookie, usagePage, usage,
	inHIDInfoPtr->actionCookie = actionCookie;
	// device
	// need to add serial number when I have a test case
	if (inIOHIDDeviceRef &&
	    inIOHIDElementRef)
	{
		inHIDInfoPtr->device.vendorID = IOHIDDevice_GetVendorID(inIOHIDDeviceRef);
		inHIDInfoPtr->device.productID = IOHIDDevice_GetProductID(inIOHIDDeviceRef);
		inHIDInfoPtr->device.locID = IOHIDDevice_GetLocationID(inIOHIDDeviceRef);
		inHIDInfoPtr->device.usage = IOHIDDevice_GetUsage(inIOHIDDeviceRef);
		inHIDInfoPtr->device.usagePage = IOHIDDevice_GetUsagePage(inIOHIDDeviceRef);
		if (!inHIDInfoPtr->device.usagePage ||
		    !inHIDInfoPtr->device.usage)
		{
			inHIDInfoPtr->device.usagePage = IOHIDDevice_GetPrimaryUsagePage(inIOHIDDeviceRef);
			inHIDInfoPtr->device.usage = IOHIDDevice_GetPrimaryUsage(inIOHIDDeviceRef);
		}

		inHIDInfoPtr->element.usagePage = IOHIDElementGetUsagePage(inIOHIDElementRef);
		inHIDInfoPtr->element.usage = IOHIDElementGetUsage(inIOHIDElementRef);
		inHIDInfoPtr->element.minReport = IOHIDElement_GetCalibrationSaturationMin(inIOHIDElementRef);
		inHIDInfoPtr->element.maxReport = IOHIDElement_GetCalibrationSaturationMax(inIOHIDElementRef);
		inHIDInfoPtr->element.cookie = IOHIDElementGetCookie(inIOHIDElementRef);
	} else {
		inHIDInfoPtr->device.vendorID = 0;
		inHIDInfoPtr->device.productID = 0;
		inHIDInfoPtr->device.locID = 0;
		inHIDInfoPtr->device.usage = 0;
		inHIDInfoPtr->device.usagePage = 0;

		inHIDInfoPtr->element.usagePage = 0;
		inHIDInfoPtr->element.usage = 0;
		inHIDInfoPtr->element.minReport = 0;
		inHIDInfoPtr->element.maxReport = 0;
		inHIDInfoPtr->element.cookie = 0;
	}
}                                                                               // HIDSetElementConfig
Ejemplo n.º 18
0
    void key_event(IOReturn result, IOHIDElementRef element, IOHIDValueRef value) {
        if (!antares_is_active()) {
            return;
        }
        bool down = IOHIDValueGetIntegerValue(value);
        uint16_t scan_code = IOHIDElementGetUsage(element);
        if ((scan_code < 4) || (231 < scan_code)) {
            return;
        } else if (scan_code == Keys::CAPS_LOCK) {
            return;
        }

        if (down) {
            enqueue(new KeyDownEvent(now_usecs(), scan_code));
        } else {
            enqueue(new KeyUpEvent(now_usecs(), scan_code));
        }
    }
Ejemplo n.º 19
0
/**************************************************************************
 *                              find_top_level
 */
static CFIndex find_top_level(IOHIDDeviceRef hid_device, CFMutableArrayRef main_elements)
{
    CFArrayRef      elements;
    CFIndex         total = 0;

    TRACE("hid_device %s\n", debugstr_device(hid_device));

    if (!hid_device)
        return 0;

    elements = IOHIDDeviceCopyMatchingElements(hid_device, NULL, 0);

    if (elements)
    {
        CFIndex i, count = CFArrayGetCount(elements);
        for (i = 0; i < count; i++)
        {
            IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
            int type = IOHIDElementGetType(element);

            TRACE("element %s\n", debugstr_element(element));

            /* Check for top-level gaming device collections */
            if (type == kIOHIDElementTypeCollection && IOHIDElementGetParent(element) == 0)
            {
                int usage_page = IOHIDElementGetUsagePage(element);
                int usage = IOHIDElementGetUsage(element);

                if (usage_page == kHIDPage_GenericDesktop &&
                    (usage == kHIDUsage_GD_Joystick || usage == kHIDUsage_GD_GamePad))
                {
                    CFArrayAppendValue(main_elements, element);
                    total++;
                }
            }
        }
        CFRelease(elements);
    }

    TRACE("-> total %d\n", (int)total);
    return total;
}
Ejemplo n.º 20
0
bool HIDGamepad::maybeAddButton(IOHIDElementRef element)
{
    uint32_t usagePage = IOHIDElementGetUsagePage(element);
    if (usagePage != kHIDPage_Button)
        return false;

    uint32_t usage = IOHIDElementGetUsage(element);
    if (!usage)
        return false;

    CFIndex min = IOHIDElementGetLogicalMin(element);
    CFIndex max = IOHIDElementGetLogicalMax(element);

    m_buttons.append(std::make_unique<HIDGamepadButton>(usage, min, max, element));

    IOHIDElementCookie cookie = IOHIDElementGetCookie(element);
    m_elementMap.set(cookie, m_buttons.last().get());

    return true;
}
Ejemplo n.º 21
0
bool HIDGamepad::maybeAddDPad(IOHIDElementRef element)
{
    uint32_t usagePage = IOHIDElementGetUsagePage(element);
    if (usagePage != kHIDPage_GenericDesktop)
        return false;

    uint32_t usage = IOHIDElementGetUsage(element);
    if (!usage || usage != kHIDUsage_GD_Hatswitch)
        return false;

    CFIndex min = IOHIDElementGetLogicalMin(element);
    CFIndex max = IOHIDElementGetLogicalMax(element);

    m_dPads.append(makeUniqueRef<HIDGamepadDPad>(min, max, element));

    IOHIDElementCookie cookie = IOHIDElementGetCookie(element);
    m_elementMap.set(cookie, &m_dPads.last().get());

    return true;
}
// Put element into the dictionary and into the queue:
PsychError PsychHIDOSKbElementAdd(IOHIDElementRef element, IOHIDQueueRef queue, int deviceIndex)
{
    // If at least one keyboard style device is detected, mark this queue as keyboard queue:
    if (IOHIDElementGetUsagePage(element) == kHIDPage_KeyboardOrKeypad) queueIsAKeyboard[deviceIndex] = TRUE;
    
    // Avoid redundant assignment to same keycode:
    if (IOHIDQueueContainsElement(queue, element)) {
        if (getenv("PSYCHHID_TELLME")) printf("--> Key %i Already assigned --> Skipping.\n", IOHIDElementGetUsage(element) - 1);
        return(PsychError_none);
    }
    
    if (getenv("PSYCHHID_TELLME")) {
        printf("--> Accepting key %i as new KbQueue element%s.\n", IOHIDElementGetUsage(element) - 1, (queueIsAKeyboard) ? " for a keyboard" : "");
    }
    
    // Put the element cookie into the queue:
    IOHIDQueueAddElement(queue, element);
    
    return(PsychError_none);
}
Ejemplo n.º 23
0
static void insert_sort_button(int header, IOHIDElementRef tIOHIDElementRef,
                               CFMutableArrayRef elementCFArrayRef, int index,
                               int target)
{
    IOHIDElementRef targetElement;
    int usage;

    CFArraySetValueAtIndex(elementCFArrayRef, header+index, NULL);
    targetElement = ( IOHIDElementRef ) CFArrayGetValueAtIndex( elementCFArrayRef, header+target);
    if (targetElement == NULL)
    {
        CFArraySetValueAtIndex(elementCFArrayRef, header+target,tIOHIDElementRef);
        return;
    }
    usage = IOHIDElementGetUsage( targetElement );
    usage --; /* usage 1 based index */

    insert_sort_button(header, targetElement, elementCFArrayRef, target, usage);
    CFArraySetValueAtIndex(elementCFArrayRef, header+target,tIOHIDElementRef);
}
Ejemplo n.º 24
0
bool HIDGamepad::maybeAddAxis(IOHIDElementRef element)
{
    uint32_t usagePage = IOHIDElementGetUsagePage(element);
    if (usagePage != kHIDPage_GenericDesktop)
        return false;

    uint32_t usage = IOHIDElementGetUsage(element);
    // This range covers the standard axis usages.
    if (usage < kHIDUsage_GD_X || usage > kHIDUsage_GD_Rz)
        return false;

    CFIndex min = IOHIDElementGetPhysicalMin(element);
    CFIndex max = IOHIDElementGetPhysicalMax(element);

    m_axes.append(std::make_unique<HIDGamepadAxis>(min, max, element));

    IOHIDElementCookie cookie = IOHIDElementGetCookie(element);
    m_elementMap.set(cookie, m_axes.last().get());

    return true;
}
Ejemplo n.º 25
0
void CInputProviderMacOsHid::SetInitialBindValues(IOHIDDeviceRef device)
{
	CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device, nullptr, 0);

	for(int i = 0; i < CFArrayGetCount(elements); i++)
	{
		IOHIDElementRef elementRef = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
		uint32 usagePage = IOHIDElementGetUsagePage(elementRef);
		if(
		    (usagePage != kHIDPage_GenericDesktop) &&
		    (usagePage != kHIDPage_Button))
		{
			continue;
		}
		IOHIDValueRef valueRef;
		if(IOHIDDeviceGetValue(device, elementRef, &valueRef) != kIOReturnSuccess)
		{
			continue;
		}

		CFIndex value = IOHIDValueGetIntegerValue(valueRef);
		IOHIDElementType type = IOHIDElementGetType(elementRef);
		uint32 usage = IOHIDElementGetUsage(elementRef);
		BINDINGTARGET tgt;
		tgt.providerId = PROVIDER_ID;
		tgt.deviceId = GetDeviceID(device);
		tgt.keyId = usage;
		tgt.keyType = GetKeyType(usage, type);
		switch(type)
		{
		case kIOHIDElementTypeInput_Misc:
		case kIOHIDElementTypeInput_Button:
		case kIOHIDElementTypeInput_Axis:
			OnInput(tgt, value);
			break;
		default:
			break;
		}
	}
}
Ejemplo n.º 26
0
void CInputProviderMacOsHid::InputValueCallback(DEVICE_INFO* deviceInfo, IOReturn result, void* sender, IOHIDValueRef valueRef)
{
	if(!OnInput) return;

	IOHIDElementRef elementRef = IOHIDValueGetElement(valueRef);
	uint32 usagePage = IOHIDElementGetUsagePage(elementRef);
	if(
	    (usagePage != kHIDPage_GenericDesktop) &&
	    (usagePage != kHIDPage_Button))
	{
		return;
	}
	uint32 usage = IOHIDElementGetUsage(elementRef);
	CFIndex value = IOHIDValueGetIntegerValue(valueRef);
	IOHIDElementType type = IOHIDElementGetType(elementRef);
	BINDINGTARGET tgt;
	tgt.providerId = PROVIDER_ID;
	tgt.deviceId = deviceInfo->deviceId;
	tgt.keyId = usage;
	tgt.keyType = GetKeyType(usage, type);
	OnInput(tgt, value);
}
Ejemplo n.º 27
0
void os_updateindicators(usbdevice* kb, int force){
    // Set NumLock on permanently
    char ileds = 1;
    // Set Caps Lock if enabled. Unlike Linux, OSX keyboards have independent caps lock states, so
    // we use the last-assigned value rather than fetching it from the system
    if(kb->modifiers & kCGEventFlagMaskAlphaShift)
        ileds |= 2;
    kb->hw_ileds = ileds;
    if(kb->active){
        usbmode* mode = kb->profile->currentmode;
        ileds = (ileds & ~mode->ioff) | mode->ion;
    }
    if(force || ileds != kb->ileds){
        kb->ileds = ileds;
        // Get a list of LED elements from handle 0
        long ledpage = kHIDPage_LEDs;
        const void* keys[] = { CFSTR(kIOHIDElementUsagePageKey) };
        const void* values[] = { CFNumberCreate(kCFAllocatorDefault, kCFNumberLongType, &ledpage) };
        CFDictionaryRef matching = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        CFRelease(values[0]);
        CFArrayRef leds;
        kern_return_t res = (*kb->handles[0])->copyMatchingElements(kb->handles[0], matching, &leds, 0);
        CFRelease(matching);
        if(res != kIOReturnSuccess)
            return;
        // Iterate through them and update the LEDs which have changed
        DELAY_SHORT(kb);
        CFIndex count = CFArrayGetCount(leds);
        for(CFIndex i = 0; i < count; i++){
            IOHIDElementRef led = (void*)CFArrayGetValueAtIndex(leds, i);
            uint32_t usage = IOHIDElementGetUsage(led);
            IOHIDValueRef value = IOHIDValueCreateWithIntegerValue(kCFAllocatorDefault, led, 0, !!(ileds & (1 << (usage - 1))));
            (*kb->handles[0])->setValue(kb->handles[0], led, value, 5000, 0, 0, 0);
            CFRelease(value);
        }
        CFRelease(leds);
    }
}
Ejemplo n.º 28
0
static void apple_hid_device_input_callback(void *data, IOReturn result,
      void* sender, IOHIDValueRef value)
{
   driver_t                  *driver = driver_get_ptr();
   apple_input_data_t         *apple = (apple_input_data_t*)driver->input_data;
   struct apple_hid_adapter *adapter = (struct apple_hid_adapter*)data;
   IOHIDElementRef element           = IOHIDValueGetElement(value);
   uint32_t type                     = IOHIDElementGetType(element);
   uint32_t page                     = IOHIDElementGetUsagePage(element);
   uint32_t use                      = IOHIDElementGetUsage(element);

   if (type != kIOHIDElementTypeInput_Misc)
      if (type != kIOHIDElementTypeInput_Button)
         if (type != kIOHIDElementTypeInput_Axis)
            return;

   /* Joystick handler.
    * TODO: Can GamePad work the same? */

   switch (page)
   {
      case kHIDPage_GenericDesktop:
         switch (type)
         {
            case kIOHIDElementTypeInput_Misc:
               switch (use)
               {
                  case kHIDUsage_GD_Hatswitch:
                     break;
                  default:
                     {
                        int i;
                        static const uint32_t axis_use_ids[4] = { 48, 49, 50, 53 };

                        for (i = 0; i < 4; i ++)
                        {
                           CFIndex min   = IOHIDElementGetPhysicalMin(element);
                           CFIndex max   = IOHIDElementGetPhysicalMax(element) - min;
                           CFIndex state = IOHIDValueGetIntegerValue(value) - min;
                           float val     = (float)state / (float)max;

                           if (use != axis_use_ids[i])
                              continue;

                           apple->axes[adapter->slot][i] =
                              ((val * 2.0f) - 1.0f) * 32767.0f;
                        }
                     }
                     break;
               }
               break;
         }
         break;
      case kHIDPage_Button:
         switch (type)
         {
            case kIOHIDElementTypeInput_Button:
               {
                  CFIndex state = IOHIDValueGetIntegerValue(value);
                  unsigned id = use - 1;

                  if (state)
                     BIT64_SET(apple->buttons[adapter->slot], id);
                  else
                     BIT64_CLEAR(apple->buttons[adapter->slot], id);
               }
               break;
         }
         break;
   }
}
Ejemplo n.º 29
0
void Burger::Mouse::InputCallback(void *pData, int iReturn,void * /* pSender */,IOHIDValueRef pValue)
{
	if (iReturn == kIOReturnSuccess) {
		Mouse *pMouse = static_cast<Mouse *>(pData);
		Word uCount = pMouse->m_uMiceCount;
		if (uCount) {
			IOHIDElementRef pElement = IOHIDValueGetElement(pValue);
			IOHIDDeviceRef pDevice = IOHIDElementGetDevice(pElement);
#if 0
			Word uRatNumber = BURGER_MAXUINT;
			const DeviceStruct *pRat = pMouse->m_Mice;
			do {
				if (pRat->m_pDevice == pDevice) {
					uRatNumber = pMouse->m_uMiceCount-uCount;
					break;
				}
				++pRat;
			} while (--uCount);
			if (uRatNumber==BURGER_MAXUINT) {
			}
#endif
			Word32 uTime = static_cast<Word32>(IOHIDValueGetTimeStamp(pValue));
			CFIndex iValue = IOHIDValueGetIntegerValue(pValue);
			
			uint32_t uPage = IOHIDElementGetUsagePage(pElement);
			uint32_t uUsage = IOHIDElementGetUsage(pElement);
			switch (uPage) {
			case kHIDPage_GenericDesktop:
				if (iValue) {
					switch (uUsage) {
					case kHIDUsage_GD_X:
						pMouse->PostMouseMotion(static_cast<Int32>(iValue),0,uTime);
						break;
					case kHIDUsage_GD_Y:
						pMouse->PostMouseMotion(0,static_cast<Int32>(iValue),uTime);
						break;
					case kHIDUsage_GD_Wheel:
						pMouse->PostMouseWheel(0,static_cast<Int32>(iValue),uTime);
						break;
					default:
						printf("Unknown usage %u\n",uUsage);
						break;
					}
				}
				break;
			case kHIDPage_Button:
				// iValue == down
				// Usage = which 1.2.3.4
				if (iValue) {
					pMouse->PostMouseDown(1<<(uUsage-1));
				} else {
					pMouse->PostMouseUp(1<<(uUsage-1));
				}
				break;
				// Ignore this one
			case kHIDPage_Consumer:
				break;
			default:
				printf("Unknown page found %u\n",uPage);
				break;
			}
		}
	}
}
Ejemplo n.º 30
0
//int main( int argc, const char * argv[] )
int manipulate_led( int which_led, int led_value )
{
#pragma unused ( argc, argv )
	IOHIDDeviceRef * tIOHIDDeviceRefs = nil;

	// create a IO HID Manager reference
	IOHIDManagerRef tIOHIDManagerRef = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone );
	require( tIOHIDManagerRef, Oops );

	// Create a device matching dictionary
	CFDictionaryRef matchingCFDictRef = hu_CreateMatchingDictionaryUsagePageUsage( TRUE,
																				  kHIDPage_GenericDesktop,
																				  kHIDUsage_GD_Keyboard );
	require( matchingCFDictRef, Oops );

	// 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 );
	require_noerr( tIOReturn, Oops );

	// and copy out its devices
	CFSetRef deviceCFSetRef = IOHIDManagerCopyDevices( tIOHIDManagerRef );
	require( deviceCFSetRef, Oops );

	// 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
	tIOHIDDeviceRefs = malloc( sizeof( IOHIDDeviceRef ) * deviceCount );
	if (!tIOHIDDeviceRefs) {
		CFRelease(deviceCFSetRef);
		deviceCFSetRef = NULL;
		goto Oops;
	}

	// now extract the device ref's from the set
	CFSetGetValues( deviceCFSetRef, (const void **) tIOHIDDeviceRefs );
	CFRelease(deviceCFSetRef);
	deviceCFSetRef = NULL;

	// before we get into the device loop we'll setup our element matching dictionary
	matchingCFDictRef = hu_CreateMatchingDictionaryUsagePageUsage( FALSE, kHIDPage_LEDs, 0 );
	require( matchingCFDictRef, Oops );

	int pass;	// do 256 passes
	//for ( pass = 0; pass < 256; pass++ ) {
		Boolean delayFlag = FALSE;	// if we find an LED element we'll set this to TRUE

		//printf( "pass = %d.\n", pass );
		for ( deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++ ) {

			// if this isn't a keyboard device...
			if ( !IOHIDDeviceConformsTo( tIOHIDDeviceRefs[deviceIndex], kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard ) ) {
				continue;	// ...skip it
			}

			//printf( "	 device = %p.\n", tIOHIDDeviceRefs[deviceIndex] );

			// copy all the elements
			CFArrayRef elementCFArrayRef = IOHIDDeviceCopyMatchingElements( tIOHIDDeviceRefs[deviceIndex],
																		   matchingCFDictRef,
																		   kIOHIDOptionsTypeNone );
			require( elementCFArrayRef, next_device );

			// for each device on the system these values are divided by the value ranges of all LED elements found
			// for example, if the first four LED element have a range of 0-1 then the four least significant bits of
			// this value will be sent to these first four LED elements, etc.
			int device_value = pass;

			// iterate over all the elements
			CFIndex elementIndex, elementCount = CFArrayGetCount( elementCFArrayRef );
			for ( elementIndex = 0; elementIndex < elementCount; elementIndex++ ) {
				IOHIDElementRef tIOHIDElementRef = ( IOHIDElementRef ) CFArrayGetValueAtIndex( elementCFArrayRef, elementIndex );
				require( tIOHIDElementRef, next_element );

				uint32_t usagePage = IOHIDElementGetUsagePage( tIOHIDElementRef );

				// if this isn't an LED element...
				if ( kHIDPage_LEDs != usagePage ) {
					continue;	// ...skip it
				}

				uint32_t usage = IOHIDElementGetUsage( tIOHIDElementRef );
				IOHIDElementType tIOHIDElementType = IOHIDElementGetType( tIOHIDElementRef );

				//printf( "		 element = %p (page: %d, usage: %d, type: %d ).\n",
				//	   tIOHIDElementRef, usagePage, usage, tIOHIDElementType );

				// get the logical mix/max for this LED element
				CFIndex minCFIndex = IOHIDElementGetLogicalMin( tIOHIDElementRef );
				CFIndex maxCFIndex = IOHIDElementGetLogicalMax( tIOHIDElementRef );

				// calculate the range
				CFIndex modCFIndex = maxCFIndex - minCFIndex + 1;

				// compute the value for this LED element
				//CFIndex tCFIndex = minCFIndex + ( device_value % modCFIndex );
				CFIndex tCFIndex = led_value;
				device_value /= modCFIndex;

				//printf( "			 value = 0x%08lX.\n", tCFIndex );

				uint64_t timestamp = 0; // create the IO HID Value to be sent to this LED element
				IOHIDValueRef tIOHIDValueRef = IOHIDValueCreateWithIntegerValue( kCFAllocatorDefault, tIOHIDElementRef, timestamp, tCFIndex );
				if ( tIOHIDValueRef ) {
					// now set it on the device
					tIOReturn = IOHIDDeviceSetValue( tIOHIDDeviceRefs[deviceIndex], tIOHIDElementRef, tIOHIDValueRef );
					CFRelease( tIOHIDValueRef );
					require_noerr( tIOReturn, next_element );
					delayFlag = TRUE;	// set this TRUE so we'll delay before changing our LED values again
				}
			next_element:	;
				continue;
			}
			CFRelease( elementCFArrayRef );
		next_device: ;
			continue;
		}

		// if we found an LED we'll delay before continuing
		//if ( delayFlag ) {
		//	usleep( 500000 ); // sleep one half second
		//}

		// if the mouse is down…
		//if (GetCurrentButtonState()) {
		//	break;	// abort pass loop
		//}
	//}						  // next pass

	if ( matchingCFDictRef ) {
		CFRelease( matchingCFDictRef );
	}
Oops:	;
	if ( tIOHIDDeviceRefs ) {
		free(tIOHIDDeviceRefs);
	}

	if ( tIOHIDManagerRef ) {
		CFRelease( tIOHIDManagerRef );
	}
	return 0;
} /* main */