The ControllerInterface API has the notion of an "id" which is presumably

meant as a ideally persistent device instance number.

In a dynamic environment such as when dealing with USB/bluetooth HID's,
I am not sure how much sense such an id can make and it would probably
be better to identify devices by an opaque blob (and a printable string).

In any case, the OS X HID manager does not offer the illusion of a
persistent integer instance identifier.

A string in the form of the device's own name is not sufficient as on
e.g. my Macbook Pro, there are three HID devices all bearing the name
"Apple Internal Keyboard / Trackpad".

For now, hijack the ControllerInterface id to mean the the HID usage
page number. This at least separates keyboards and pointing devices,
allowing the keyboard to be selected in the configuration dialog.

Also some minor cleanup.


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5793 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Soren Jorvang 2010-06-26 13:03:25 +00:00
parent ebbfba62a0
commit a53d0cb6d5
7 changed files with 255 additions and 191 deletions

View File

@ -172,4 +172,3 @@
{ kHIDUsage_KeyboardRightAlt, "Right Alt" },
{ kHIDUsage_KeyboardRightGUI, "Right GUI" },
/* 0x4E - 0xFFFF Reserved */

View File

@ -7,7 +7,7 @@ namespace ciface
namespace OSX
{
void Init( std::vector<ControllerInterface::Device*>& devices );
void Init(std::vector<ControllerInterface::Device*>& devices);
void DeInit();
}

View File

@ -1,12 +1,10 @@
#include <Foundation/Foundation.h>
#include <IOKit/hid/IOHIDLib.h>
#include "../ControllerInterface.h"
#ifdef CIFACE_USE_OSX
#include "OSX.h"
#include "OSXKeyboard.h"
#include "OSXMouse.h"
#include <Foundation/Foundation.h>
#include <IOKit/hid/IOHIDLib.h>
namespace ciface
{
@ -17,69 +15,98 @@ namespace OSX
static IOHIDManagerRef HIDManager = NULL;
static CFStringRef OurRunLoop = CFSTR("DolphinOSXInput");
void DeviceElementDebugPrint(const void *value, void *context)
{
IOHIDElementRef e = (IOHIDElementRef)value;
bool recurse = false;
if (context)
recurse = *(bool*)context;
std::string type = "";
switch (IOHIDElementGetType(e))
{
case kIOHIDElementTypeInput_Axis: type = "axis"; break;
case kIOHIDElementTypeInput_Button: type = "button"; break;
case kIOHIDElementTypeInput_Misc: type = "misc"; break;
case kIOHIDElementTypeInput_ScanCodes: type = "scancodes"; break;
case kIOHIDElementTypeOutput: type = "output"; break;
case kIOHIDElementTypeFeature: type = "feature"; break;
case kIOHIDElementTypeCollection: type = "collection"; break;
switch (IOHIDElementGetType(e)) {
case kIOHIDElementTypeInput_Axis:
type = "axis";
break;
case kIOHIDElementTypeInput_Button:
type = "button";
break;
case kIOHIDElementTypeInput_Misc:
type = "misc";
break;
case kIOHIDElementTypeInput_ScanCodes:
type = "scancodes";
break;
case kIOHIDElementTypeOutput:
type = "output";
break;
case kIOHIDElementTypeFeature:
type = "feature";
break;
case kIOHIDElementTypeCollection:
type = "collection";
break;
}
std::string c_type = "";
if (type == "collection")
{
switch (IOHIDElementGetCollectionType(e))
{
case kIOHIDElementCollectionTypePhysical: c_type = "physical"; break;
case kIOHIDElementCollectionTypeApplication: c_type = "application"; break;
case kIOHIDElementCollectionTypeLogical: c_type = "logical"; break;
case kIOHIDElementCollectionTypeReport: c_type = "report"; break;
case kIOHIDElementCollectionTypeNamedArray: c_type = "namedArray"; break;
case kIOHIDElementCollectionTypeUsageSwitch: c_type = "usageSwitch"; break;
case kIOHIDElementCollectionTypeUsageModifier: c_type = "usageModifier"; break;
switch (IOHIDElementGetCollectionType(e)) {
case kIOHIDElementCollectionTypePhysical:
c_type = "physical";
break;
case kIOHIDElementCollectionTypeApplication:
c_type = "application";
break;
case kIOHIDElementCollectionTypeLogical:
c_type = "logical";
break;
case kIOHIDElementCollectionTypeReport:
c_type = "report";
break;
case kIOHIDElementCollectionTypeNamedArray:
c_type = "namedArray";
break;
case kIOHIDElementCollectionTypeUsageSwitch:
c_type = "usageSwitch";
break;
case kIOHIDElementCollectionTypeUsageModifier:
c_type = "usageModifier";
break;
}
}
c_type.append(" ");
NSLog(@"%s%s%spage: 0x%x usage: 0x%x name: %s lmin: %i lmax: %i pmin: %i pmax: %i",
NSLog(@"%s%s%spage: 0x%x usage: 0x%x name: %s "
"lmin: %i lmax: %i pmin: %i pmax: %i",
type.c_str(),
type == "collection" ? ":" : "",
type == "collection" ? c_type.c_str() : " ",
IOHIDElementGetUsagePage(e),
IOHIDElementGetUsage(e),
IOHIDElementGetName(e), // TOO BAD IT"S FUCKING USELESS
IOHIDElementGetName(e), // usually just NULL
IOHIDElementGetLogicalMin(e),
IOHIDElementGetLogicalMax(e),
IOHIDElementGetPhysicalMin(e),
IOHIDElementGetPhysicalMax(e));
if ((type == "collection") && recurse)
{
CFArrayRef elements = IOHIDElementGetChildren(e);
CFRange range = {0, CFArrayGetCount(elements)};
// this leaks...but it's just debug code, right? :D
CFArrayApplyFunction(elements, range, DeviceElementDebugPrint, NULL);
CFArrayApplyFunction(elements, range,
DeviceElementDebugPrint, NULL);
}
}
void DeviceDebugPrint(IOHIDDeviceRef device)
{
//#define shortlog(x) NSLog(@"%s: %@", x, IOHIDDeviceGetProperty(device, CFSTR(x)));
#ifdef shortlog
#if 0
#define shortlog(x) NSLog(@"%s: %@", \
x, IOHIDDeviceGetProperty(device, CFSTR(x)));
NSLog(@"-------------------------");
NSLog(@"Got Device: %@", IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)));
NSLog(@"Got Device: %@",
IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)));
shortlog(kIOHIDTransportKey)
shortlog(kIOHIDVendorIDKey)
shortlog(kIOHIDVendorIDSourceKey)
@ -100,77 +127,98 @@ void DeviceDebugPrint(IOHIDDeviceRef device)
shortlog(kIOHIDMaxFeatureReportSizeKey)
shortlog(kIOHIDReportIntervalKey)
shortlog(kIOHIDReportDescriptorKey)
#endif
#undef shortlog
#endif
}
static void DeviceMatching_callback(void* inContext,
IOReturn inResult,
void* inSender,
IOHIDDeviceRef inIOHIDDeviceRef)
IOReturn inResult,
void *inSender,
IOHIDDeviceRef inIOHIDDeviceRef)
{
DeviceDebugPrint(inIOHIDDeviceRef);
std::vector<ControllerInterface::Device*> *devices = (std::vector<ControllerInterface::Device*> *)inContext;
std::vector<ControllerInterface::Device*> *devices =
(std::vector<ControllerInterface::Device*> *)inContext;
// Add to the devices vector if it's of a type we want
if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard) ||
IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Keypad))
if (IOHIDDeviceConformsTo(inIOHIDDeviceRef,
kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard) ||
IOHIDDeviceConformsTo(inIOHIDDeviceRef,
kHIDPage_GenericDesktop, kHIDUsage_GD_Keypad))
{
devices->push_back(new Keyboard(inIOHIDDeviceRef));
}
// We can probably generalize this class for mouse and gamepad inputs
if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse) /*||
IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad)*/)
if (IOHIDDeviceConformsTo(inIOHIDDeviceRef,
kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse) /*||
IOHIDDeviceConformsTo(inIOHIDDeviceRef,
kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad)*/)
{
devices->push_back(new Mouse(inIOHIDDeviceRef));
}
}
void Init( std::vector<ControllerInterface::Device*>& devices )
void Init(std::vector<ControllerInterface::Device*>& devices)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
HIDManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
HIDManager = IOHIDManagerCreate(kCFAllocatorDefault,
kIOHIDOptionsTypeNone);
if (!HIDManager)
NSLog(@"Failed to create HID Manager reference");
// HID Manager will give us the following devices:
// Keyboard, Keypad, Mouse, GamePad
NSArray *matchingDevices =
[NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:kHIDPage_GenericDesktop], @ kIOHIDDeviceUsagePageKey,
[NSNumber numberWithInteger:kHIDUsage_GD_Keyboard], @ kIOHIDDeviceUsageKey, nil],
[NSNumber numberWithInteger:kHIDPage_GenericDesktop],
@kIOHIDDeviceUsagePageKey,
[NSNumber numberWithInteger:kHIDUsage_GD_Keyboard],
@kIOHIDDeviceUsageKey, nil],
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:kHIDPage_GenericDesktop], @ kIOHIDDeviceUsagePageKey,
[NSNumber numberWithInteger:kHIDUsage_GD_Keypad], @ kIOHIDDeviceUsageKey, nil],
[NSNumber numberWithInteger:kHIDPage_GenericDesktop],
@kIOHIDDeviceUsagePageKey,
[NSNumber numberWithInteger:kHIDUsage_GD_Keypad],
@kIOHIDDeviceUsageKey, nil],
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:kHIDPage_GenericDesktop], @ kIOHIDDeviceUsagePageKey,
[NSNumber numberWithInteger:kHIDUsage_GD_Mouse], @ kIOHIDDeviceUsageKey, nil],
[NSNumber numberWithInteger:kHIDPage_GenericDesktop],
@kIOHIDDeviceUsagePageKey,
[NSNumber numberWithInteger:kHIDUsage_GD_Mouse],
@kIOHIDDeviceUsageKey, nil],
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:kHIDPage_GenericDesktop], @ kIOHIDDeviceUsagePageKey,
[NSNumber numberWithInteger:kHIDUsage_GD_GamePad], @ kIOHIDDeviceUsageKey, nil],
[NSNumber numberWithInteger:kHIDPage_GenericDesktop],
@kIOHIDDeviceUsagePageKey,
[NSNumber numberWithInteger:kHIDUsage_GD_GamePad],
@kIOHIDDeviceUsageKey, nil],
nil];
// Pass NULL to get all devices
IOHIDManagerSetDeviceMatchingMultiple(HIDManager, (CFArrayRef)matchingDevices);
// Callbacks for acquisition or loss of a matching device
IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, DeviceMatching_callback, (void *)&devices);
IOHIDManagerSetDeviceMatchingMultiple(HIDManager,
(CFArrayRef)matchingDevices);
// Match devices that are plugged right now.
IOHIDManagerScheduleWithRunLoop(HIDManager, CFRunLoopGetCurrent(), OurRunLoop);
if (IOHIDManagerOpen(HIDManager, kIOHIDOptionsTypeNone) != kIOReturnSuccess)
// Callbacks for acquisition or loss of a matching device
IOHIDManagerRegisterDeviceMatchingCallback(HIDManager,
DeviceMatching_callback, (void *)&devices);
// Match devices that are plugged in right now
IOHIDManagerScheduleWithRunLoop(HIDManager,
CFRunLoopGetCurrent(), OurRunLoop);
if (IOHIDManagerOpen(HIDManager, kIOHIDOptionsTypeNone) !=
kIOReturnSuccess)
NSLog(@"Failed to open HID Manager");
// Wait while current devices are initialized
while (CFRunLoopRunInMode(OurRunLoop,0,TRUE) == kCFRunLoopRunHandledSource);
// Things should be configured now. Disable hotplugging and other scheduling
while (CFRunLoopRunInMode(OurRunLoop, 0, TRUE) ==
kCFRunLoopRunHandledSource);
// Things should be configured now
// Disable hotplugging and other scheduling
IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, NULL, NULL);
IOHIDManagerUnscheduleFromRunLoop(HIDManager, CFRunLoopGetCurrent(), OurRunLoop);
IOHIDManagerUnscheduleFromRunLoop(HIDManager,
CFRunLoopGetCurrent(), OurRunLoop);
[pool release];
}
@ -184,5 +232,3 @@ void DeInit()
}
}
#endif

View File

@ -1,7 +1,6 @@
#pragma once
#include <IOKit/hid/IOHIDLib.h>
#include "../ControllerInterface.h"
#include <IOKit/hid/IOHIDLib.h>
namespace ciface
{
@ -12,45 +11,47 @@ class Keyboard : public ControllerInterface::Device
{
friend class ControllerInterface;
friend class ControllerInterface::ControlReference;
protected:
class Input : public ControllerInterface::Device::Input
{
friend class Keyboard;
protected:
virtual ControlState GetState(IOHIDDeviceRef device) const = 0;
};
class Key : public Input
{
friend class Keyboard;
public:
std::string GetName() const;
protected:
Key( IOHIDElementRef element );
Key(IOHIDElementRef element);
ControlState GetState(IOHIDDeviceRef device) const;
private:
IOHIDElementRef m_element;
IOHIDElementRef m_element;
std::string m_name;
};
bool UpdateInput();
bool UpdateOutput();
ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const;
void SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state );
ControlState GetInputState(
const ControllerInterface::Device::Input* const input) const;
void SetOutputState(
const ControllerInterface::Device::Output* const output,
const ControlState state);
public:
Keyboard(IOHIDDeviceRef device);
std::string GetName() const;
std::string GetSource() const;
int GetId() const;
private:
IOHIDDeviceRef m_device;
std::string m_device_name;
std::string m_device_name;
};
}

View File

@ -1,18 +1,16 @@
#include "../ControllerInterface.h"
#ifdef CIFACE_USE_OSX
#include "OSXKeyboard.h"
#include <Foundation/Foundation.h>
#include <IOKit/hid/IOHIDLib.h>
#include "../ControllerInterface.h"
#include "OSXKeyboard.h"
namespace ciface
{
namespace OSX
{
struct PrettyKeys
const struct PrettyKeys
{
const uint32_t code;
const char* const name;
@ -21,50 +19,54 @@ struct PrettyKeys
#include "NamedKeys.h"
};
extern void DeviceElementDebugPrint(const void*, void*);
extern void DeviceElementDebugPrint(const void *, void *);
Keyboard::Keyboard(IOHIDDeviceRef device)
: m_device(device)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
m_device_name = [(NSString *)IOHIDDeviceGetProperty(m_device, CFSTR(kIOHIDProductKey)) UTF8String];
m_device_name = [(NSString *)IOHIDDeviceGetProperty(m_device,
CFSTR(kIOHIDProductKey)) UTF8String];
// This class should only recieve Keyboard or Keypad devices
// Now, filter on just the buttons we can handle sanely
NSDictionary *matchingElements =
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:kIOHIDElementTypeInput_Button], @ kIOHIDElementTypeKey,
[NSNumber numberWithInteger:0], @ kIOHIDElementMinKey,
[NSNumber numberWithInteger:1], @ kIOHIDElementMaxKey,
[NSNumber numberWithInteger:kIOHIDElementTypeInput_Button],
@kIOHIDElementTypeKey,
[NSNumber numberWithInteger: 0], @kIOHIDElementMinKey,
[NSNumber numberWithInteger: 1], @kIOHIDElementMaxKey,
nil];
CFArrayRef elements =
IOHIDDeviceCopyMatchingElements(m_device, (CFDictionaryRef)matchingElements, kIOHIDOptionsTypeNone);
CFArrayRef elements = IOHIDDeviceCopyMatchingElements(m_device,
(CFDictionaryRef)matchingElements, kIOHIDOptionsTypeNone);
if (elements)
{
for (int i = 0; i < CFArrayGetCount(elements); i++)
{
IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
IOHIDElementRef e =
(IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
//DeviceElementDebugPrint(e, NULL);
try { AddInput(new Key(e)); }
catch (std::bad_alloc&) { /*Thrown if the key is reserved*/ }
AddInput(new Key(e));
}
CFRelease(elements);
}
[pool release];
}
ControlState Keyboard::GetInputState( const ControllerInterface::Device::Input* const input ) const
ControlState Keyboard::GetInputState(
const ControllerInterface::Device::Input* const input) const
{
return ((Input*)input)->GetState(m_device);
}
void Keyboard::SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state )
void Keyboard::SetOutputState(
const ControllerInterface::Device::Output * const output,
const ControlState state)
{
}
@ -85,20 +87,20 @@ std::string Keyboard::GetName() const
std::string Keyboard::GetSource() const
{
return "OSX";
return "HID";
}
int Keyboard::GetId() const
{
return 0;
// Overload the "id" to identify devices by HID type when names collide
return kHIDUsage_GD_Keyboard;
}
Keyboard::Key::Key(IOHIDElementRef element)
: m_element(element)
, m_name("RESERVED") // for some reason HID Manager gives these to us.
{
uint32_t keycode = IOHIDElementGetUsage(m_element);
for (uint32_t i = 0; i < sizeof(named_keys)/sizeof(*named_keys); i++)
{
if (named_keys[i].code == keycode)
@ -107,14 +109,18 @@ Keyboard::Key::Key(IOHIDElementRef element)
return;
}
}
NSLog(@"Got key 0x%x of type RESERVED", IOHIDElementGetUsage(m_element));
m_name = "RESERVED"; /* XXX */
}
ControlState Keyboard::Key::GetState(IOHIDDeviceRef device) const
{
IOHIDValueRef value;
if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess)
if (IOHIDDeviceGetValue(device, m_element, &value) ==
kIOReturnSuccess) {
return IOHIDValueGetIntegerValue(value) > 0;
}
return false;
}
@ -127,5 +133,3 @@ std::string Keyboard::Key::GetName() const
}
}
#endif

View File

@ -1,7 +1,6 @@
#pragma once
#include <IOKit/hid/IOHIDLib.h>
#include "../ControllerInterface.h"
#include <IOKit/hid/IOHIDLib.h>
namespace ciface
{
@ -12,29 +11,28 @@ class Mouse : public ControllerInterface::Device
{
friend class ControllerInterface;
friend class ControllerInterface::ControlReference;
protected:
class Input : public ControllerInterface::Device::Input
{
friend class Mouse;
protected:
virtual ControlState GetState(IOHIDDeviceRef device) const = 0;
};
class Button : public Input
{
friend class Mouse;
public:
std::string GetName() const;
protected:
Button( IOHIDElementRef element );
Button(IOHIDElementRef element);
ControlState GetState(IOHIDDeviceRef device) const;
private:
IOHIDElementRef m_element;
IOHIDElementRef m_element;
std::string m_name;
};
class Axis : public Input
{
friend class Mouse;
@ -45,31 +43,34 @@ protected:
};
std::string GetName() const;
protected:
Axis( IOHIDElementRef element, direction dir );
Axis(IOHIDElementRef element, direction dir);
ControlState GetState(IOHIDDeviceRef device) const;
private:
IOHIDElementRef m_element;
IOHIDElementRef m_element;
std::string m_name;
direction m_direction;
float m_range;
};
bool UpdateInput();
bool UpdateOutput();
ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const;
void SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state );
ControlState GetInputState(
const ControllerInterface::Device::Input* const input) const;
void SetOutputState(
const ControllerInterface::Device::Output* const output,
const ControlState state);
public:
Mouse(IOHIDDeviceRef device);
std::string GetName() const;
std::string GetSource() const;
int GetId() const;
private:
IOHIDDeviceRef m_device;
std::string m_device_name;
std::string m_device_name;
};
}

View File

@ -1,11 +1,9 @@
#include "../ControllerInterface.h"
#ifdef CIFACE_USE_OSX
#include "OSXMouse.h"
#include <Foundation/Foundation.h>
#include <IOKit/hid/IOHIDLib.h>
#include "../ControllerInterface.h"
#include "OSXMouse.h"
namespace ciface
{
namespace OSX
@ -13,67 +11,75 @@ namespace OSX
extern void DeviceElementDebugPrint(const void*, void*);
Mouse::Mouse(IOHIDDeviceRef device)
: m_device(device)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
m_device_name = [(NSString *)IOHIDDeviceGetProperty(m_device, CFSTR(kIOHIDProductKey)) UTF8String];
m_device_name = [(NSString *)IOHIDDeviceGetProperty(m_device,
CFSTR(kIOHIDProductKey)) UTF8String];
// Buttons
NSDictionary *buttonDict =
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:kIOHIDElementTypeInput_Button], @ kIOHIDElementTypeKey,
[NSNumber numberWithInteger:kHIDPage_Button], @ kIOHIDElementUsagePageKey,
[NSNumber numberWithInteger:kIOHIDElementTypeInput_Button],
@kIOHIDElementTypeKey,
[NSNumber numberWithInteger:kHIDPage_Button],
@kIOHIDElementUsagePageKey,
nil];
CFArrayRef buttons =
IOHIDDeviceCopyMatchingElements(m_device, (CFDictionaryRef)buttonDict, kIOHIDOptionsTypeNone);
CFArrayRef buttons = IOHIDDeviceCopyMatchingElements(m_device,
(CFDictionaryRef)buttonDict, kIOHIDOptionsTypeNone);
if (buttons)
{
for (int i = 0; i < CFArrayGetCount(buttons); i++)
{
IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(buttons, i);
IOHIDElementRef e =
(IOHIDElementRef)CFArrayGetValueAtIndex(buttons, i);
//DeviceElementDebugPrint(e, NULL);
AddInput(new Button(e));
}
CFRelease(buttons);
}
// Axes
NSDictionary *axisDict =
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:kIOHIDElementTypeInput_Misc], @ kIOHIDElementTypeKey,
[NSNumber numberWithInteger:kIOHIDElementTypeInput_Misc],
@kIOHIDElementTypeKey,
nil];
CFArrayRef axes =
IOHIDDeviceCopyMatchingElements(m_device, (CFDictionaryRef)axisDict, kIOHIDOptionsTypeNone);
CFArrayRef axes = IOHIDDeviceCopyMatchingElements(m_device,
(CFDictionaryRef)axisDict, kIOHIDOptionsTypeNone);
if (axes)
{
for (int i = 0; i < CFArrayGetCount(axes); i++)
{
IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(axes, i);
IOHIDElementRef e =
(IOHIDElementRef)CFArrayGetValueAtIndex(axes, i);
//DeviceElementDebugPrint(e, NULL);
AddInput(new Axis(e, Axis::negative));
AddInput(new Axis(e, Axis::positive));
}
CFRelease(axes);
}
[pool release];
}
ControlState Mouse::GetInputState( const ControllerInterface::Device::Input* const input ) const
ControlState Mouse::GetInputState(
const ControllerInterface::Device::Input* const input) const
{
return ((Input*)input)->GetState(m_device);
}
void Mouse::SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state )
void Mouse::SetOutputState(
const ControllerInterface::Device::Output* const output,
const ControlState state)
{
}
@ -94,12 +100,13 @@ std::string Mouse::GetName() const
std::string Mouse::GetSource() const
{
return "OSX";
return "HID";
}
int Mouse::GetId() const
{
return 0;
// Overload the "id" to identify devices by HID type when names collide
return kHIDUsage_GD_Mouse;
}
@ -132,21 +139,29 @@ Mouse::Axis::Axis(IOHIDElementRef element, direction dir)
{
// Need to parse the element a bit first
std::string description("unk");
switch (IOHIDElementGetUsage(m_element))
{
default:
NSLog(@"Unknown axis type 0x%x, using anyways...", IOHIDElementGetUsage(m_element));
break;
case kHIDUsage_GD_X: description = "X"; break;
case kHIDUsage_GD_Y: description = "Y"; break;
case kHIDUsage_GD_Wheel: description = "Wheel"; break;
case kHIDUsage_Csmr_ACPan: description = "Pan"; break;
switch (IOHIDElementGetUsage(m_element)) {
default:
NSLog(@"Unknown axis type 0x%x, using it anyway...",
IOHIDElementGetUsage(m_element));
break;
case kHIDUsage_GD_X:
description = "X";
break;
case kHIDUsage_GD_Y:
description = "Y";
break;
case kHIDUsage_GD_Wheel:
description = "Wheel";
break;
case kHIDUsage_Csmr_ACPan:
description = "Pan";
break;
}
m_name = std::string("Axis ") + description;
m_name.append((m_direction == positive) ? "+" : "-");
// yeah, that factor is completely random :/
m_range = (float)IOHIDElementGetLogicalMax(m_element) / 1000.;
}
@ -154,22 +169,22 @@ Mouse::Axis::Axis(IOHIDElementRef element, direction dir)
ControlState Mouse::Axis::GetState(IOHIDDeviceRef device) const
{
IOHIDValueRef value;
if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess)
if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess)
{
int int_value = IOHIDValueGetIntegerValue(value);
if (((int_value < 0) && (m_direction == positive)) ||
((int_value > 0) && (m_direction == negative)) ||
!int_value)
return false;
float actual_value = abs(int_value) / m_range;
//NSLog(@"%s %i %f", m_name.c_str(), int_value, actual_value);
return actual_value;
}
return false;
}
@ -181,5 +196,3 @@ std::string Mouse::Axis::GetName() const
}
}
#endif