mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-26 15:55:31 +01:00
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:
parent
ebbfba62a0
commit
a53d0cb6d5
@ -172,4 +172,3 @@
|
|||||||
{ kHIDUsage_KeyboardRightAlt, "Right Alt" },
|
{ kHIDUsage_KeyboardRightAlt, "Right Alt" },
|
||||||
{ kHIDUsage_KeyboardRightGUI, "Right GUI" },
|
{ kHIDUsage_KeyboardRightGUI, "Right GUI" },
|
||||||
/* 0x4E - 0xFFFF Reserved */
|
/* 0x4E - 0xFFFF Reserved */
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ namespace ciface
|
|||||||
namespace OSX
|
namespace OSX
|
||||||
{
|
{
|
||||||
|
|
||||||
void Init( std::vector<ControllerInterface::Device*>& devices );
|
void Init(std::vector<ControllerInterface::Device*>& devices);
|
||||||
void DeInit();
|
void DeInit();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
|
#include <Foundation/Foundation.h>
|
||||||
|
#include <IOKit/hid/IOHIDLib.h>
|
||||||
|
|
||||||
#include "../ControllerInterface.h"
|
#include "../ControllerInterface.h"
|
||||||
|
|
||||||
#ifdef CIFACE_USE_OSX
|
|
||||||
|
|
||||||
#include "OSX.h"
|
#include "OSX.h"
|
||||||
#include "OSXKeyboard.h"
|
#include "OSXKeyboard.h"
|
||||||
#include "OSXMouse.h"
|
#include "OSXMouse.h"
|
||||||
#include <Foundation/Foundation.h>
|
|
||||||
#include <IOKit/hid/IOHIDLib.h>
|
|
||||||
|
|
||||||
namespace ciface
|
namespace ciface
|
||||||
{
|
{
|
||||||
@ -17,69 +15,98 @@ namespace OSX
|
|||||||
static IOHIDManagerRef HIDManager = NULL;
|
static IOHIDManagerRef HIDManager = NULL;
|
||||||
static CFStringRef OurRunLoop = CFSTR("DolphinOSXInput");
|
static CFStringRef OurRunLoop = CFSTR("DolphinOSXInput");
|
||||||
|
|
||||||
|
|
||||||
void DeviceElementDebugPrint(const void *value, void *context)
|
void DeviceElementDebugPrint(const void *value, void *context)
|
||||||
{
|
{
|
||||||
IOHIDElementRef e = (IOHIDElementRef)value;
|
IOHIDElementRef e = (IOHIDElementRef)value;
|
||||||
bool recurse = false;
|
bool recurse = false;
|
||||||
if (context)
|
if (context)
|
||||||
recurse = *(bool*)context;
|
recurse = *(bool*)context;
|
||||||
|
|
||||||
std::string type = "";
|
std::string type = "";
|
||||||
switch (IOHIDElementGetType(e))
|
switch (IOHIDElementGetType(e)) {
|
||||||
{
|
case kIOHIDElementTypeInput_Axis:
|
||||||
case kIOHIDElementTypeInput_Axis: type = "axis"; break;
|
type = "axis";
|
||||||
case kIOHIDElementTypeInput_Button: type = "button"; break;
|
break;
|
||||||
case kIOHIDElementTypeInput_Misc: type = "misc"; break;
|
case kIOHIDElementTypeInput_Button:
|
||||||
case kIOHIDElementTypeInput_ScanCodes: type = "scancodes"; break;
|
type = "button";
|
||||||
case kIOHIDElementTypeOutput: type = "output"; break;
|
break;
|
||||||
case kIOHIDElementTypeFeature: type = "feature"; break;
|
case kIOHIDElementTypeInput_Misc:
|
||||||
case kIOHIDElementTypeCollection: type = "collection"; break;
|
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 = "";
|
std::string c_type = "";
|
||||||
if (type == "collection")
|
if (type == "collection")
|
||||||
{
|
{
|
||||||
switch (IOHIDElementGetCollectionType(e))
|
switch (IOHIDElementGetCollectionType(e)) {
|
||||||
{
|
case kIOHIDElementCollectionTypePhysical:
|
||||||
case kIOHIDElementCollectionTypePhysical: c_type = "physical"; break;
|
c_type = "physical";
|
||||||
case kIOHIDElementCollectionTypeApplication: c_type = "application"; break;
|
break;
|
||||||
case kIOHIDElementCollectionTypeLogical: c_type = "logical"; break;
|
case kIOHIDElementCollectionTypeApplication:
|
||||||
case kIOHIDElementCollectionTypeReport: c_type = "report"; break;
|
c_type = "application";
|
||||||
case kIOHIDElementCollectionTypeNamedArray: c_type = "namedArray"; break;
|
break;
|
||||||
case kIOHIDElementCollectionTypeUsageSwitch: c_type = "usageSwitch"; break;
|
case kIOHIDElementCollectionTypeLogical:
|
||||||
case kIOHIDElementCollectionTypeUsageModifier: c_type = "usageModifier"; break;
|
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(" ");
|
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.c_str(),
|
||||||
type == "collection" ? ":" : "",
|
type == "collection" ? ":" : "",
|
||||||
type == "collection" ? c_type.c_str() : " ",
|
type == "collection" ? c_type.c_str() : " ",
|
||||||
IOHIDElementGetUsagePage(e),
|
IOHIDElementGetUsagePage(e),
|
||||||
IOHIDElementGetUsage(e),
|
IOHIDElementGetUsage(e),
|
||||||
IOHIDElementGetName(e), // TOO BAD IT"S FUCKING USELESS
|
IOHIDElementGetName(e), // usually just NULL
|
||||||
IOHIDElementGetLogicalMin(e),
|
IOHIDElementGetLogicalMin(e),
|
||||||
IOHIDElementGetLogicalMax(e),
|
IOHIDElementGetLogicalMax(e),
|
||||||
IOHIDElementGetPhysicalMin(e),
|
IOHIDElementGetPhysicalMin(e),
|
||||||
IOHIDElementGetPhysicalMax(e));
|
IOHIDElementGetPhysicalMax(e));
|
||||||
|
|
||||||
if ((type == "collection") && recurse)
|
if ((type == "collection") && recurse)
|
||||||
{
|
{
|
||||||
CFArrayRef elements = IOHIDElementGetChildren(e);
|
CFArrayRef elements = IOHIDElementGetChildren(e);
|
||||||
CFRange range = {0, CFArrayGetCount(elements)};
|
CFRange range = {0, CFArrayGetCount(elements)};
|
||||||
// this leaks...but it's just debug code, right? :D
|
// this leaks...but it's just debug code, right? :D
|
||||||
CFArrayApplyFunction(elements, range, DeviceElementDebugPrint, NULL);
|
CFArrayApplyFunction(elements, range,
|
||||||
|
DeviceElementDebugPrint, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceDebugPrint(IOHIDDeviceRef device)
|
void DeviceDebugPrint(IOHIDDeviceRef device)
|
||||||
{
|
{
|
||||||
//#define shortlog(x) NSLog(@"%s: %@", x, IOHIDDeviceGetProperty(device, CFSTR(x)));
|
#if 0
|
||||||
#ifdef shortlog
|
#define shortlog(x) NSLog(@"%s: %@", \
|
||||||
|
x, IOHIDDeviceGetProperty(device, CFSTR(x)));
|
||||||
NSLog(@"-------------------------");
|
NSLog(@"-------------------------");
|
||||||
NSLog(@"Got Device: %@", IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)));
|
NSLog(@"Got Device: %@",
|
||||||
|
IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)));
|
||||||
shortlog(kIOHIDTransportKey)
|
shortlog(kIOHIDTransportKey)
|
||||||
shortlog(kIOHIDVendorIDKey)
|
shortlog(kIOHIDVendorIDKey)
|
||||||
shortlog(kIOHIDVendorIDSourceKey)
|
shortlog(kIOHIDVendorIDSourceKey)
|
||||||
@ -100,77 +127,98 @@ void DeviceDebugPrint(IOHIDDeviceRef device)
|
|||||||
shortlog(kIOHIDMaxFeatureReportSizeKey)
|
shortlog(kIOHIDMaxFeatureReportSizeKey)
|
||||||
shortlog(kIOHIDReportIntervalKey)
|
shortlog(kIOHIDReportIntervalKey)
|
||||||
shortlog(kIOHIDReportDescriptorKey)
|
shortlog(kIOHIDReportDescriptorKey)
|
||||||
#endif
|
#endif
|
||||||
#undef shortlog
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DeviceMatching_callback(void* inContext,
|
static void DeviceMatching_callback(void* inContext,
|
||||||
IOReturn inResult,
|
IOReturn inResult,
|
||||||
void* inSender,
|
void *inSender,
|
||||||
IOHIDDeviceRef inIOHIDDeviceRef)
|
IOHIDDeviceRef inIOHIDDeviceRef)
|
||||||
{
|
{
|
||||||
DeviceDebugPrint(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
|
// Add to the devices vector if it's of a type we want
|
||||||
if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard) ||
|
if (IOHIDDeviceConformsTo(inIOHIDDeviceRef,
|
||||||
IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Keypad))
|
kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard) ||
|
||||||
|
IOHIDDeviceConformsTo(inIOHIDDeviceRef,
|
||||||
|
kHIDPage_GenericDesktop, kHIDUsage_GD_Keypad))
|
||||||
{
|
{
|
||||||
devices->push_back(new Keyboard(inIOHIDDeviceRef));
|
devices->push_back(new Keyboard(inIOHIDDeviceRef));
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can probably generalize this class for mouse and gamepad inputs
|
// We can probably generalize this class for mouse and gamepad inputs
|
||||||
if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse) /*||
|
if (IOHIDDeviceConformsTo(inIOHIDDeviceRef,
|
||||||
IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad)*/)
|
kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse) /*||
|
||||||
|
IOHIDDeviceConformsTo(inIOHIDDeviceRef,
|
||||||
|
kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad)*/)
|
||||||
{
|
{
|
||||||
devices->push_back(new Mouse(inIOHIDDeviceRef));
|
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];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
HIDManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
|
HIDManager = IOHIDManagerCreate(kCFAllocatorDefault,
|
||||||
|
kIOHIDOptionsTypeNone);
|
||||||
if (!HIDManager)
|
if (!HIDManager)
|
||||||
NSLog(@"Failed to create HID Manager reference");
|
NSLog(@"Failed to create HID Manager reference");
|
||||||
|
|
||||||
// HID Manager will give us the following devices:
|
// HID Manager will give us the following devices:
|
||||||
// Keyboard, Keypad, Mouse, GamePad
|
// Keyboard, Keypad, Mouse, GamePad
|
||||||
NSArray *matchingDevices =
|
NSArray *matchingDevices =
|
||||||
[NSArray arrayWithObjects:
|
[NSArray arrayWithObjects:
|
||||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
[NSNumber numberWithInteger:kHIDPage_GenericDesktop], @ kIOHIDDeviceUsagePageKey,
|
[NSNumber numberWithInteger:kHIDPage_GenericDesktop],
|
||||||
[NSNumber numberWithInteger:kHIDUsage_GD_Keyboard], @ kIOHIDDeviceUsageKey, nil],
|
@kIOHIDDeviceUsagePageKey,
|
||||||
|
[NSNumber numberWithInteger:kHIDUsage_GD_Keyboard],
|
||||||
|
@kIOHIDDeviceUsageKey, nil],
|
||||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
[NSNumber numberWithInteger:kHIDPage_GenericDesktop], @ kIOHIDDeviceUsagePageKey,
|
[NSNumber numberWithInteger:kHIDPage_GenericDesktop],
|
||||||
[NSNumber numberWithInteger:kHIDUsage_GD_Keypad], @ kIOHIDDeviceUsageKey, nil],
|
@kIOHIDDeviceUsagePageKey,
|
||||||
|
[NSNumber numberWithInteger:kHIDUsage_GD_Keypad],
|
||||||
|
@kIOHIDDeviceUsageKey, nil],
|
||||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
[NSNumber numberWithInteger:kHIDPage_GenericDesktop], @ kIOHIDDeviceUsagePageKey,
|
[NSNumber numberWithInteger:kHIDPage_GenericDesktop],
|
||||||
[NSNumber numberWithInteger:kHIDUsage_GD_Mouse], @ kIOHIDDeviceUsageKey, nil],
|
@kIOHIDDeviceUsagePageKey,
|
||||||
|
[NSNumber numberWithInteger:kHIDUsage_GD_Mouse],
|
||||||
|
@kIOHIDDeviceUsageKey, nil],
|
||||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
[NSNumber numberWithInteger:kHIDPage_GenericDesktop], @ kIOHIDDeviceUsagePageKey,
|
[NSNumber numberWithInteger:kHIDPage_GenericDesktop],
|
||||||
[NSNumber numberWithInteger:kHIDUsage_GD_GamePad], @ kIOHIDDeviceUsageKey, nil],
|
@kIOHIDDeviceUsagePageKey,
|
||||||
|
[NSNumber numberWithInteger:kHIDUsage_GD_GamePad],
|
||||||
|
@kIOHIDDeviceUsageKey, nil],
|
||||||
nil];
|
nil];
|
||||||
// Pass NULL to get all devices
|
// Pass NULL to get all devices
|
||||||
IOHIDManagerSetDeviceMatchingMultiple(HIDManager, (CFArrayRef)matchingDevices);
|
IOHIDManagerSetDeviceMatchingMultiple(HIDManager,
|
||||||
|
(CFArrayRef)matchingDevices);
|
||||||
// Callbacks for acquisition or loss of a matching device
|
|
||||||
IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, DeviceMatching_callback, (void *)&devices);
|
|
||||||
|
|
||||||
// Match devices that are plugged right now.
|
// Callbacks for acquisition or loss of a matching device
|
||||||
IOHIDManagerScheduleWithRunLoop(HIDManager, CFRunLoopGetCurrent(), OurRunLoop);
|
IOHIDManagerRegisterDeviceMatchingCallback(HIDManager,
|
||||||
if (IOHIDManagerOpen(HIDManager, kIOHIDOptionsTypeNone) != kIOReturnSuccess)
|
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");
|
NSLog(@"Failed to open HID Manager");
|
||||||
|
|
||||||
// Wait while current devices are initialized
|
// Wait while current devices are initialized
|
||||||
while (CFRunLoopRunInMode(OurRunLoop,0,TRUE) == kCFRunLoopRunHandledSource);
|
while (CFRunLoopRunInMode(OurRunLoop, 0, TRUE) ==
|
||||||
|
kCFRunLoopRunHandledSource);
|
||||||
// Things should be configured now. Disable hotplugging and other scheduling
|
|
||||||
|
// Things should be configured now
|
||||||
|
// Disable hotplugging and other scheduling
|
||||||
IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, NULL, NULL);
|
IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, NULL, NULL);
|
||||||
IOHIDManagerUnscheduleFromRunLoop(HIDManager, CFRunLoopGetCurrent(), OurRunLoop);
|
IOHIDManagerUnscheduleFromRunLoop(HIDManager,
|
||||||
|
CFRunLoopGetCurrent(), OurRunLoop);
|
||||||
|
|
||||||
[pool release];
|
[pool release];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,5 +232,3 @@ void DeInit()
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#include <IOKit/hid/IOHIDLib.h>
|
||||||
|
|
||||||
#include "../ControllerInterface.h"
|
#include "../ControllerInterface.h"
|
||||||
#include <IOKit/hid/IOHIDLib.h>
|
|
||||||
|
|
||||||
namespace ciface
|
namespace ciface
|
||||||
{
|
{
|
||||||
@ -12,45 +11,47 @@ class Keyboard : public ControllerInterface::Device
|
|||||||
{
|
{
|
||||||
friend class ControllerInterface;
|
friend class ControllerInterface;
|
||||||
friend class ControllerInterface::ControlReference;
|
friend class ControllerInterface::ControlReference;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
class Input : public ControllerInterface::Device::Input
|
class Input : public ControllerInterface::Device::Input
|
||||||
{
|
{
|
||||||
friend class Keyboard;
|
friend class Keyboard;
|
||||||
protected:
|
protected:
|
||||||
virtual ControlState GetState(IOHIDDeviceRef device) const = 0;
|
virtual ControlState GetState(IOHIDDeviceRef device) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Key : public Input
|
class Key : public Input
|
||||||
{
|
{
|
||||||
friend class Keyboard;
|
friend class Keyboard;
|
||||||
public:
|
public:
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
protected:
|
protected:
|
||||||
Key( IOHIDElementRef element );
|
Key(IOHIDElementRef element);
|
||||||
ControlState GetState(IOHIDDeviceRef device) const;
|
ControlState GetState(IOHIDDeviceRef device) const;
|
||||||
private:
|
private:
|
||||||
IOHIDElementRef m_element;
|
IOHIDElementRef m_element;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool UpdateInput();
|
bool UpdateInput();
|
||||||
bool UpdateOutput();
|
bool UpdateOutput();
|
||||||
|
|
||||||
ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const;
|
ControlState GetInputState(
|
||||||
void SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state );
|
const ControllerInterface::Device::Input* const input) const;
|
||||||
|
void SetOutputState(
|
||||||
|
const ControllerInterface::Device::Output* const output,
|
||||||
|
const ControlState state);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Keyboard(IOHIDDeviceRef device);
|
Keyboard(IOHIDDeviceRef device);
|
||||||
|
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
std::string GetSource() const;
|
std::string GetSource() const;
|
||||||
int GetId() const;
|
int GetId() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IOHIDDeviceRef m_device;
|
IOHIDDeviceRef m_device;
|
||||||
std::string m_device_name;
|
std::string m_device_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
#include "../ControllerInterface.h"
|
|
||||||
|
|
||||||
#ifdef CIFACE_USE_OSX
|
|
||||||
|
|
||||||
#include "OSXKeyboard.h"
|
|
||||||
#include <Foundation/Foundation.h>
|
#include <Foundation/Foundation.h>
|
||||||
#include <IOKit/hid/IOHIDLib.h>
|
#include <IOKit/hid/IOHIDLib.h>
|
||||||
|
|
||||||
|
#include "../ControllerInterface.h"
|
||||||
|
#include "OSXKeyboard.h"
|
||||||
|
|
||||||
namespace ciface
|
namespace ciface
|
||||||
{
|
{
|
||||||
namespace OSX
|
namespace OSX
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
struct PrettyKeys
|
const struct PrettyKeys
|
||||||
{
|
{
|
||||||
const uint32_t code;
|
const uint32_t code;
|
||||||
const char* const name;
|
const char* const name;
|
||||||
@ -21,50 +19,54 @@ struct PrettyKeys
|
|||||||
#include "NamedKeys.h"
|
#include "NamedKeys.h"
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void DeviceElementDebugPrint(const void*, void*);
|
extern void DeviceElementDebugPrint(const void *, void *);
|
||||||
|
|
||||||
|
|
||||||
Keyboard::Keyboard(IOHIDDeviceRef device)
|
Keyboard::Keyboard(IOHIDDeviceRef device)
|
||||||
: m_device(device)
|
: m_device(device)
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
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
|
// This class should only recieve Keyboard or Keypad devices
|
||||||
// Now, filter on just the buttons we can handle sanely
|
// Now, filter on just the buttons we can handle sanely
|
||||||
NSDictionary *matchingElements =
|
NSDictionary *matchingElements =
|
||||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
[NSNumber numberWithInteger:kIOHIDElementTypeInput_Button], @ kIOHIDElementTypeKey,
|
[NSNumber numberWithInteger:kIOHIDElementTypeInput_Button],
|
||||||
[NSNumber numberWithInteger:0], @ kIOHIDElementMinKey,
|
@kIOHIDElementTypeKey,
|
||||||
[NSNumber numberWithInteger:1], @ kIOHIDElementMaxKey,
|
[NSNumber numberWithInteger: 0], @kIOHIDElementMinKey,
|
||||||
|
[NSNumber numberWithInteger: 1], @kIOHIDElementMaxKey,
|
||||||
nil];
|
nil];
|
||||||
|
|
||||||
CFArrayRef elements =
|
CFArrayRef elements = IOHIDDeviceCopyMatchingElements(m_device,
|
||||||
IOHIDDeviceCopyMatchingElements(m_device, (CFDictionaryRef)matchingElements, kIOHIDOptionsTypeNone);
|
(CFDictionaryRef)matchingElements, kIOHIDOptionsTypeNone);
|
||||||
|
|
||||||
if (elements)
|
if (elements)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < CFArrayGetCount(elements); i++)
|
for (int i = 0; i < CFArrayGetCount(elements); i++)
|
||||||
{
|
{
|
||||||
IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
|
IOHIDElementRef e =
|
||||||
|
(IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
|
||||||
//DeviceElementDebugPrint(e, NULL);
|
//DeviceElementDebugPrint(e, NULL);
|
||||||
|
|
||||||
try { AddInput(new Key(e)); }
|
AddInput(new Key(e));
|
||||||
catch (std::bad_alloc&) { /*Thrown if the key is reserved*/ }
|
|
||||||
}
|
}
|
||||||
CFRelease(elements);
|
CFRelease(elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
[pool release];
|
[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);
|
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
|
std::string Keyboard::GetSource() const
|
||||||
{
|
{
|
||||||
return "OSX";
|
return "HID";
|
||||||
}
|
}
|
||||||
|
|
||||||
int Keyboard::GetId() const
|
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)
|
Keyboard::Key::Key(IOHIDElementRef element)
|
||||||
: m_element(element)
|
: m_element(element)
|
||||||
, m_name("RESERVED") // for some reason HID Manager gives these to us.
|
|
||||||
{
|
{
|
||||||
uint32_t keycode = IOHIDElementGetUsage(m_element);
|
uint32_t keycode = IOHIDElementGetUsage(m_element);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < sizeof(named_keys)/sizeof(*named_keys); i++)
|
for (uint32_t i = 0; i < sizeof(named_keys)/sizeof(*named_keys); i++)
|
||||||
{
|
{
|
||||||
if (named_keys[i].code == keycode)
|
if (named_keys[i].code == keycode)
|
||||||
@ -107,14 +109,18 @@ Keyboard::Key::Key(IOHIDElementRef element)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NSLog(@"Got key 0x%x of type RESERVED", IOHIDElementGetUsage(m_element));
|
|
||||||
|
m_name = "RESERVED"; /* XXX */
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlState Keyboard::Key::GetState(IOHIDDeviceRef device) const
|
ControlState Keyboard::Key::GetState(IOHIDDeviceRef device) const
|
||||||
{
|
{
|
||||||
IOHIDValueRef value;
|
IOHIDValueRef value;
|
||||||
if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess)
|
|
||||||
|
if (IOHIDDeviceGetValue(device, m_element, &value) ==
|
||||||
|
kIOReturnSuccess) {
|
||||||
return IOHIDValueGetIntegerValue(value) > 0;
|
return IOHIDValueGetIntegerValue(value) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -127,5 +133,3 @@ std::string Keyboard::Key::GetName() const
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#include <IOKit/hid/IOHIDLib.h>
|
||||||
|
|
||||||
#include "../ControllerInterface.h"
|
#include "../ControllerInterface.h"
|
||||||
#include <IOKit/hid/IOHIDLib.h>
|
|
||||||
|
|
||||||
namespace ciface
|
namespace ciface
|
||||||
{
|
{
|
||||||
@ -12,29 +11,28 @@ class Mouse : public ControllerInterface::Device
|
|||||||
{
|
{
|
||||||
friend class ControllerInterface;
|
friend class ControllerInterface;
|
||||||
friend class ControllerInterface::ControlReference;
|
friend class ControllerInterface::ControlReference;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
class Input : public ControllerInterface::Device::Input
|
class Input : public ControllerInterface::Device::Input
|
||||||
{
|
{
|
||||||
friend class Mouse;
|
friend class Mouse;
|
||||||
protected:
|
protected:
|
||||||
virtual ControlState GetState(IOHIDDeviceRef device) const = 0;
|
virtual ControlState GetState(IOHIDDeviceRef device) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Button : public Input
|
class Button : public Input
|
||||||
{
|
{
|
||||||
friend class Mouse;
|
friend class Mouse;
|
||||||
public:
|
public:
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
protected:
|
protected:
|
||||||
Button( IOHIDElementRef element );
|
Button(IOHIDElementRef element);
|
||||||
ControlState GetState(IOHIDDeviceRef device) const;
|
ControlState GetState(IOHIDDeviceRef device) const;
|
||||||
private:
|
private:
|
||||||
IOHIDElementRef m_element;
|
IOHIDElementRef m_element;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Axis : public Input
|
class Axis : public Input
|
||||||
{
|
{
|
||||||
friend class Mouse;
|
friend class Mouse;
|
||||||
@ -45,31 +43,34 @@ protected:
|
|||||||
};
|
};
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
protected:
|
protected:
|
||||||
Axis( IOHIDElementRef element, direction dir );
|
Axis(IOHIDElementRef element, direction dir);
|
||||||
ControlState GetState(IOHIDDeviceRef device) const;
|
ControlState GetState(IOHIDDeviceRef device) const;
|
||||||
private:
|
private:
|
||||||
IOHIDElementRef m_element;
|
IOHIDElementRef m_element;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
direction m_direction;
|
direction m_direction;
|
||||||
float m_range;
|
float m_range;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool UpdateInput();
|
bool UpdateInput();
|
||||||
bool UpdateOutput();
|
bool UpdateOutput();
|
||||||
|
|
||||||
ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const;
|
ControlState GetInputState(
|
||||||
void SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state );
|
const ControllerInterface::Device::Input* const input) const;
|
||||||
|
void SetOutputState(
|
||||||
|
const ControllerInterface::Device::Output* const output,
|
||||||
|
const ControlState state);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Mouse(IOHIDDeviceRef device);
|
Mouse(IOHIDDeviceRef device);
|
||||||
|
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
std::string GetSource() const;
|
std::string GetSource() const;
|
||||||
int GetId() const;
|
int GetId() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IOHIDDeviceRef m_device;
|
IOHIDDeviceRef m_device;
|
||||||
std::string m_device_name;
|
std::string m_device_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
#include "../ControllerInterface.h"
|
|
||||||
|
|
||||||
#ifdef CIFACE_USE_OSX
|
|
||||||
|
|
||||||
#include "OSXMouse.h"
|
|
||||||
#include <Foundation/Foundation.h>
|
#include <Foundation/Foundation.h>
|
||||||
#include <IOKit/hid/IOHIDLib.h>
|
#include <IOKit/hid/IOHIDLib.h>
|
||||||
|
|
||||||
|
#include "../ControllerInterface.h"
|
||||||
|
#include "OSXMouse.h"
|
||||||
|
|
||||||
namespace ciface
|
namespace ciface
|
||||||
{
|
{
|
||||||
namespace OSX
|
namespace OSX
|
||||||
@ -13,67 +11,75 @@ namespace OSX
|
|||||||
|
|
||||||
extern void DeviceElementDebugPrint(const void*, void*);
|
extern void DeviceElementDebugPrint(const void*, void*);
|
||||||
|
|
||||||
|
|
||||||
Mouse::Mouse(IOHIDDeviceRef device)
|
Mouse::Mouse(IOHIDDeviceRef device)
|
||||||
: m_device(device)
|
: m_device(device)
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
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
|
// Buttons
|
||||||
NSDictionary *buttonDict =
|
NSDictionary *buttonDict =
|
||||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
[NSNumber numberWithInteger:kIOHIDElementTypeInput_Button], @ kIOHIDElementTypeKey,
|
[NSNumber numberWithInteger:kIOHIDElementTypeInput_Button],
|
||||||
[NSNumber numberWithInteger:kHIDPage_Button], @ kIOHIDElementUsagePageKey,
|
@kIOHIDElementTypeKey,
|
||||||
|
[NSNumber numberWithInteger:kHIDPage_Button],
|
||||||
|
@kIOHIDElementUsagePageKey,
|
||||||
nil];
|
nil];
|
||||||
|
|
||||||
CFArrayRef buttons =
|
CFArrayRef buttons = IOHIDDeviceCopyMatchingElements(m_device,
|
||||||
IOHIDDeviceCopyMatchingElements(m_device, (CFDictionaryRef)buttonDict, kIOHIDOptionsTypeNone);
|
(CFDictionaryRef)buttonDict, kIOHIDOptionsTypeNone);
|
||||||
|
|
||||||
if (buttons)
|
if (buttons)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < CFArrayGetCount(buttons); i++)
|
for (int i = 0; i < CFArrayGetCount(buttons); i++)
|
||||||
{
|
{
|
||||||
IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(buttons, i);
|
IOHIDElementRef e =
|
||||||
|
(IOHIDElementRef)CFArrayGetValueAtIndex(buttons, i);
|
||||||
//DeviceElementDebugPrint(e, NULL);
|
//DeviceElementDebugPrint(e, NULL);
|
||||||
|
|
||||||
AddInput(new Button(e));
|
AddInput(new Button(e));
|
||||||
}
|
}
|
||||||
CFRelease(buttons);
|
CFRelease(buttons);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Axes
|
// Axes
|
||||||
NSDictionary *axisDict =
|
NSDictionary *axisDict =
|
||||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
[NSNumber numberWithInteger:kIOHIDElementTypeInput_Misc], @ kIOHIDElementTypeKey,
|
[NSNumber numberWithInteger:kIOHIDElementTypeInput_Misc],
|
||||||
|
@kIOHIDElementTypeKey,
|
||||||
nil];
|
nil];
|
||||||
|
|
||||||
CFArrayRef axes =
|
CFArrayRef axes = IOHIDDeviceCopyMatchingElements(m_device,
|
||||||
IOHIDDeviceCopyMatchingElements(m_device, (CFDictionaryRef)axisDict, kIOHIDOptionsTypeNone);
|
(CFDictionaryRef)axisDict, kIOHIDOptionsTypeNone);
|
||||||
|
|
||||||
if (axes)
|
if (axes)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < CFArrayGetCount(axes); i++)
|
for (int i = 0; i < CFArrayGetCount(axes); i++)
|
||||||
{
|
{
|
||||||
IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(axes, i);
|
IOHIDElementRef e =
|
||||||
|
(IOHIDElementRef)CFArrayGetValueAtIndex(axes, i);
|
||||||
//DeviceElementDebugPrint(e, NULL);
|
//DeviceElementDebugPrint(e, NULL);
|
||||||
|
|
||||||
AddInput(new Axis(e, Axis::negative));
|
AddInput(new Axis(e, Axis::negative));
|
||||||
AddInput(new Axis(e, Axis::positive));
|
AddInput(new Axis(e, Axis::positive));
|
||||||
}
|
}
|
||||||
CFRelease(axes);
|
CFRelease(axes);
|
||||||
}
|
}
|
||||||
|
|
||||||
[pool release];
|
[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);
|
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
|
std::string Mouse::GetSource() const
|
||||||
{
|
{
|
||||||
return "OSX";
|
return "HID";
|
||||||
}
|
}
|
||||||
|
|
||||||
int Mouse::GetId() const
|
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
|
// Need to parse the element a bit first
|
||||||
std::string description("unk");
|
std::string description("unk");
|
||||||
|
|
||||||
switch (IOHIDElementGetUsage(m_element))
|
switch (IOHIDElementGetUsage(m_element)) {
|
||||||
{
|
default:
|
||||||
default:
|
NSLog(@"Unknown axis type 0x%x, using it anyway...",
|
||||||
NSLog(@"Unknown axis type 0x%x, using anyways...", IOHIDElementGetUsage(m_element));
|
IOHIDElementGetUsage(m_element));
|
||||||
break;
|
break;
|
||||||
case kHIDUsage_GD_X: description = "X"; break;
|
case kHIDUsage_GD_X:
|
||||||
case kHIDUsage_GD_Y: description = "Y"; break;
|
description = "X";
|
||||||
case kHIDUsage_GD_Wheel: description = "Wheel"; break;
|
break;
|
||||||
case kHIDUsage_Csmr_ACPan: description = "Pan"; 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 = std::string("Axis ") + description;
|
||||||
m_name.append((m_direction == positive) ? "+" : "-");
|
m_name.append((m_direction == positive) ? "+" : "-");
|
||||||
|
|
||||||
// yeah, that factor is completely random :/
|
// yeah, that factor is completely random :/
|
||||||
m_range = (float)IOHIDElementGetLogicalMax(m_element) / 1000.;
|
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
|
ControlState Mouse::Axis::GetState(IOHIDDeviceRef device) const
|
||||||
{
|
{
|
||||||
IOHIDValueRef value;
|
IOHIDValueRef value;
|
||||||
if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess)
|
if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess)
|
||||||
{
|
{
|
||||||
int int_value = IOHIDValueGetIntegerValue(value);
|
int int_value = IOHIDValueGetIntegerValue(value);
|
||||||
|
|
||||||
if (((int_value < 0) && (m_direction == positive)) ||
|
if (((int_value < 0) && (m_direction == positive)) ||
|
||||||
((int_value > 0) && (m_direction == negative)) ||
|
((int_value > 0) && (m_direction == negative)) ||
|
||||||
!int_value)
|
!int_value)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
float actual_value = abs(int_value) / m_range;
|
float actual_value = abs(int_value) / m_range;
|
||||||
|
|
||||||
//NSLog(@"%s %i %f", m_name.c_str(), int_value, actual_value);
|
//NSLog(@"%s %i %f", m_name.c_str(), int_value, actual_value);
|
||||||
|
|
||||||
return actual_value;
|
return actual_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,5 +196,3 @@ std::string Mouse::Axis::GetName() const
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user