First OSX keyboard stuff...works, with limitations:\nNo Mouse support yet (Add gamepad via IOKit as well?)\nCould poll less for less cpu time\nDon't know why rumble events don't seem to be sent to the class until right before it's deleted (Billiard?)
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5407 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
a443ec7d8d
commit
452c2e711a
|
@ -43,7 +43,7 @@ void ControllerInterface::Init()
|
||||||
ciface::Xlib::Init( m_devices, m_hwnd );
|
ciface::Xlib::Init( m_devices, m_hwnd );
|
||||||
#endif
|
#endif
|
||||||
#ifdef CIFACE_USE_OSX
|
#ifdef CIFACE_USE_OSX
|
||||||
ciface::OSX::Init( m_devices, m_hwnd );
|
ciface::OSX::Init( m_devices );
|
||||||
#endif
|
#endif
|
||||||
#ifdef CIFACE_USE_SDL
|
#ifdef CIFACE_USE_SDL
|
||||||
ciface::SDL::Init( m_devices );
|
ciface::SDL::Init( m_devices );
|
||||||
|
@ -89,7 +89,7 @@ void ControllerInterface::DeInit()
|
||||||
// nothing needed
|
// nothing needed
|
||||||
#endif
|
#endif
|
||||||
#ifdef CIFACE_USE_OSX
|
#ifdef CIFACE_USE_OSX
|
||||||
// nothing needed
|
ciface::OSX::DeInit();
|
||||||
#endif
|
#endif
|
||||||
#ifdef CIFACE_USE_SDL
|
#ifdef CIFACE_USE_SDL
|
||||||
// there seems to be some sort of memory leak with SDL, quit isn't freeing everything up
|
// there seems to be some sort of memory leak with SDL, quit isn't freeing everything up
|
||||||
|
|
|
@ -1,101 +0,0 @@
|
||||||
#include "../ControllerInterface.h"
|
|
||||||
|
|
||||||
#ifdef CIFACE_USE_OSX
|
|
||||||
|
|
||||||
#include "OSX.h"
|
|
||||||
#include "OSXPrivate.h"
|
|
||||||
|
|
||||||
namespace ciface
|
|
||||||
{
|
|
||||||
namespace OSX
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
void Init( std::vector<ControllerInterface::Device*>& devices, void* hwnd )
|
|
||||||
{
|
|
||||||
// mouse will be added to this, Keyboard class will be turned into KeyboardMouse
|
|
||||||
// single device for combined keyboard/mouse, this will allow combinations like shift+click more easily
|
|
||||||
//devices.push_back( new Keyboard( hwnd ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
Keyboard::Keyboard( void *View )
|
|
||||||
{
|
|
||||||
|
|
||||||
memset( &m_state, 0, sizeof(m_state) );
|
|
||||||
OSX_Init(View);
|
|
||||||
// This is REALLY dumb right here
|
|
||||||
// Should REALLY cover the entire UTF-8 Range
|
|
||||||
for (int a = 0; a < 256; ++a)
|
|
||||||
inputs.push_back( new Key( (char)a ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Keyboard::~Keyboard()
|
|
||||||
{
|
|
||||||
// might not need this func
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ControlState Keyboard::GetInputState( const ControllerInterface::Device::Input* const input )
|
|
||||||
{
|
|
||||||
return ((Input*)input)->GetState( &m_state );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Keyboard::SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state )
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Keyboard::UpdateInput()
|
|
||||||
{
|
|
||||||
memset(m_state.keyboard, 0, 256);
|
|
||||||
OSX_UpdateKeys(256, m_state.keyboard );
|
|
||||||
|
|
||||||
// mouse stuff in here too
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Keyboard::UpdateOutput()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string Keyboard::GetName() const
|
|
||||||
{
|
|
||||||
return "Keyboard";
|
|
||||||
//return "Keyboard Mouse"; // change to this later
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Keyboard::GetSource() const
|
|
||||||
{
|
|
||||||
return "OSX";
|
|
||||||
}
|
|
||||||
|
|
||||||
int Keyboard::GetId() const
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ControlState Keyboard::Key::GetState( State* const state )
|
|
||||||
{
|
|
||||||
for(unsigned int a = 0; a < 256; ++a)
|
|
||||||
if(state->keyboard[a] == m_index)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Keyboard::Key::GetName() const
|
|
||||||
{
|
|
||||||
char temp[16];
|
|
||||||
sprintf(temp, "Key:%c", m_index);
|
|
||||||
return std::string(temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,16 +1,17 @@
|
||||||
#ifndef _CIFACE_OSX_H_
|
#pragma once
|
||||||
#define _CIFACE_OSX_H_
|
|
||||||
|
|
||||||
#include "../ControllerInterface.h"
|
#include "../ControllerInterface.h"
|
||||||
|
#include <IOKit/hid/IOHIDLib.h>
|
||||||
|
|
||||||
namespace ciface
|
namespace ciface
|
||||||
{
|
{
|
||||||
namespace OSX
|
namespace OSX
|
||||||
{
|
{
|
||||||
|
|
||||||
void Init( std::vector<ControllerInterface::Device*>& devices, void* hwnd );
|
void Init( std::vector<ControllerInterface::Device*>& devices );
|
||||||
|
void DeInit();
|
||||||
|
|
||||||
class Keyboard : public ControllerInterface::Device
|
class KeyboardMouse : public ControllerInterface::Device
|
||||||
{
|
{
|
||||||
friend class ControllerInterface;
|
friend class ControllerInterface;
|
||||||
friend class ControllerInterface::ControlReference;
|
friend class ControllerInterface::ControlReference;
|
||||||
|
@ -19,29 +20,73 @@ namespace ciface
|
||||||
|
|
||||||
struct State
|
struct State
|
||||||
{
|
{
|
||||||
char keyboard[256]; // really dumb
|
unsigned char buttons[32];
|
||||||
// mouse crap will go here
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Input : public ControllerInterface::Device::Input
|
class Input : public ControllerInterface::Device::Input
|
||||||
{
|
{
|
||||||
friend class Keyboard;
|
friend class KeyboardMouse;
|
||||||
protected:
|
protected:
|
||||||
Input( const unsigned char index ) : m_index(index) {}
|
virtual ControlState GetState( const State* const state ) = 0;
|
||||||
virtual ControlState GetState( State* const js ) = 0;
|
};
|
||||||
|
|
||||||
const unsigned char m_index;
|
class Output : public ControllerInterface::Device::Output
|
||||||
|
{
|
||||||
|
friend class KeyboardMouse;
|
||||||
|
protected:
|
||||||
|
virtual void SetState( const ControlState state, unsigned char* const state_out ) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Key : public Input
|
class Key : public Input
|
||||||
{
|
{
|
||||||
friend class Keyboard;
|
friend class KeyboardMouse;
|
||||||
public:
|
public:
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
protected:
|
protected:
|
||||||
Key( const unsigned char key ) : Input(key) {}
|
Key( IOHIDElementRef key_element );
|
||||||
ControlState GetState( State* const js );
|
ControlState GetState( const State* const state );
|
||||||
|
private:
|
||||||
|
IOHIDElementRef m_key_element;
|
||||||
|
std::string m_key_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Button : public Input
|
||||||
|
{
|
||||||
|
friend class KeyboardMouse;
|
||||||
|
public:
|
||||||
|
std::string GetName() const;
|
||||||
|
protected:
|
||||||
|
Button( IOHIDElementRef button_element );
|
||||||
|
ControlState GetState( const State* const state );
|
||||||
|
private:
|
||||||
|
IOHIDElementRef m_button_element;
|
||||||
|
std::string m_button_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Axis : public Input
|
||||||
|
{
|
||||||
|
friend class KeyboardMouse;
|
||||||
|
public:
|
||||||
|
std::string GetName() const;
|
||||||
|
protected:
|
||||||
|
Axis( IOHIDElementRef button_element );
|
||||||
|
ControlState GetState( const State* const state );
|
||||||
|
private:
|
||||||
|
IOHIDElementRef m_axis_element;
|
||||||
|
std::string m_axis_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Light : public Output
|
||||||
|
{
|
||||||
|
friend class KeyboardMouse;
|
||||||
|
public:
|
||||||
|
std::string GetName() const;
|
||||||
|
protected:
|
||||||
|
Light( IOHIDElementRef light_element );
|
||||||
|
void SetState( const ControlState state, unsigned char* const state_out );
|
||||||
|
private:
|
||||||
|
IOHIDElementRef m_light_element;
|
||||||
|
std::string m_light_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool UpdateInput();
|
bool UpdateInput();
|
||||||
|
@ -51,18 +96,19 @@ namespace ciface
|
||||||
void SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state );
|
void SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Keyboard( void* view );
|
KeyboardMouse(IOHIDDeviceRef device);
|
||||||
~Keyboard();
|
~KeyboardMouse();
|
||||||
|
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
std::string GetSource() const;
|
std::string GetSource() const;
|
||||||
int GetId() const;
|
int GetId() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
State m_state;
|
State m_state_in;
|
||||||
|
unsigned char m_state_out[6]; // ugly
|
||||||
|
IOHIDDeviceRef m_device;
|
||||||
|
std::string m_device_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -0,0 +1,354 @@
|
||||||
|
#include "../ControllerInterface.h"
|
||||||
|
|
||||||
|
#ifdef CIFACE_USE_OSX
|
||||||
|
|
||||||
|
#include "OSX.h"
|
||||||
|
#include <Foundation/Foundation.h>
|
||||||
|
#include <IOKit/hid/IOHIDLib.h>
|
||||||
|
|
||||||
|
namespace ciface
|
||||||
|
{
|
||||||
|
namespace OSX
|
||||||
|
{
|
||||||
|
|
||||||
|
struct PrettyLights
|
||||||
|
{
|
||||||
|
const uint32_t code;
|
||||||
|
const char* const name;
|
||||||
|
} named_lights[] =
|
||||||
|
{
|
||||||
|
{ kHIDUsage_LED_NumLock, "Num Lock" },
|
||||||
|
{ kHIDUsage_LED_CapsLock, "Caps Lock" },
|
||||||
|
{ kHIDUsage_LED_ScrollLock, "Scroll Lock" },
|
||||||
|
{ kHIDUsage_LED_Compose, "Compose" },
|
||||||
|
{ kHIDUsage_LED_Kana, "Kana" },
|
||||||
|
{ kHIDUsage_LED_Power, "Power" }
|
||||||
|
};
|
||||||
|
|
||||||
|
static IOHIDManagerRef HIDManager = NULL;
|
||||||
|
static CFStringRef OurRunLoop = CFSTR("DolphinOSXInput");
|
||||||
|
|
||||||
|
|
||||||
|
static void DeviceMatching_callback(void* inContext,
|
||||||
|
IOReturn inResult,
|
||||||
|
void* inSender,
|
||||||
|
IOHIDDeviceRef inIOHIDDeviceRef)
|
||||||
|
{
|
||||||
|
NSLog(@"Got Device: %@", IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDProductKey)));
|
||||||
|
|
||||||
|
// 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)/* ||
|
||||||
|
IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse)*/)
|
||||||
|
{
|
||||||
|
std::vector<ControllerInterface::Device*> *devices = (std::vector<ControllerInterface::Device*> *)inContext;
|
||||||
|
devices->push_back(new KeyboardMouse(inIOHIDDeviceRef));
|
||||||
|
}
|
||||||
|
/* else if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad))
|
||||||
|
{
|
||||||
|
}*/
|
||||||
|
else {
|
||||||
|
// Actually, we don't want it
|
||||||
|
NSLog(@"Throwing away...");
|
||||||
|
#define shortlog(x) NSLog(@"%s: %@", x, IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(x)));
|
||||||
|
shortlog(kIOHIDTransportKey)
|
||||||
|
shortlog(kIOHIDVendorIDKey)
|
||||||
|
shortlog(kIOHIDVendorIDSourceKey)
|
||||||
|
shortlog(kIOHIDProductIDKey)
|
||||||
|
shortlog(kIOHIDVersionNumberKey)
|
||||||
|
shortlog(kIOHIDManufacturerKey)
|
||||||
|
shortlog(kIOHIDProductKey)
|
||||||
|
shortlog(kIOHIDSerialNumberKey)
|
||||||
|
shortlog(kIOHIDCountryCodeKey)
|
||||||
|
shortlog(kIOHIDLocationIDKey)
|
||||||
|
shortlog(kIOHIDDeviceUsageKey)
|
||||||
|
shortlog(kIOHIDDeviceUsagePageKey)
|
||||||
|
shortlog(kIOHIDDeviceUsagePairsKey)
|
||||||
|
shortlog(kIOHIDPrimaryUsageKey)
|
||||||
|
shortlog(kIOHIDPrimaryUsagePageKey)
|
||||||
|
shortlog(kIOHIDMaxInputReportSizeKey)
|
||||||
|
shortlog(kIOHIDMaxOutputReportSizeKey)
|
||||||
|
shortlog(kIOHIDMaxFeatureReportSizeKey)
|
||||||
|
shortlog(kIOHIDReportIntervalKey)
|
||||||
|
shortlog(kIOHIDReportDescriptorKey)
|
||||||
|
#undef shortlog
|
||||||
|
NSLog(@"\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will come in handy if we support hotplugging
|
||||||
|
static void DeviceRemoval_callback(void *inContext,
|
||||||
|
IOReturn inResult,
|
||||||
|
void *inSender,
|
||||||
|
IOHIDDeviceRef inIOHIDDeviceRef)
|
||||||
|
{
|
||||||
|
NSLog(@"%s( context: %p, result: %p, sender: %p, device: %p )",
|
||||||
|
__PRETTY_FUNCTION__, inContext, (void *)inResult, inSender, (void *)inIOHIDDeviceRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init( std::vector<ControllerInterface::Device*>& devices )
|
||||||
|
{
|
||||||
|
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],
|
||||||
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
|
[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],
|
||||||
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
|
[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);
|
||||||
|
IOHIDManagerRegisterDeviceRemovalCallback(HIDManager, DeviceRemoval_callback, (void *)&devices);
|
||||||
|
|
||||||
|
// Match devices that are plugged 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
|
||||||
|
// TODO: support hotplugging, get rid of the following:
|
||||||
|
IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, NULL, NULL);
|
||||||
|
IOHIDManagerRegisterDeviceRemovalCallback(HIDManager, NULL, NULL);
|
||||||
|
IOHIDManagerUnscheduleFromRunLoop(HIDManager, CFRunLoopGetCurrent(), OurRunLoop);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeInit()
|
||||||
|
{
|
||||||
|
// This closes all devices as well
|
||||||
|
IOHIDManagerClose(HIDManager, kIOHIDOptionsTypeNone);
|
||||||
|
CFRelease(HIDManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DeviceElementDebugPrint(const void *value, void *context)
|
||||||
|
{
|
||||||
|
IOHIDElementRef e = (IOHIDElementRef)value;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c_type.append(" ");
|
||||||
|
NSLog(@"%s%s%spage: 0x%x usage: 0x%x name: %s lmin: %u lmax: %u",
|
||||||
|
type.c_str(),
|
||||||
|
type == "collection" ? ":" : "",
|
||||||
|
type == "collection" ? c_type.c_str() : " ",
|
||||||
|
IOHIDElementGetUsagePage(e),
|
||||||
|
IOHIDElementGetUsage(e),
|
||||||
|
IOHIDElementGetName(e), // TOO BAD IT"S FUCKING USELESS
|
||||||
|
IOHIDElementGetLogicalMin(e),
|
||||||
|
IOHIDElementGetLogicalMax(e));
|
||||||
|
|
||||||
|
if (type == "collection")
|
||||||
|
{
|
||||||
|
CFArrayRef elements = IOHIDElementGetChildren(e);
|
||||||
|
CFRange range = {0, CFArrayGetCount(elements)};
|
||||||
|
// this leaks...but it's just debug code, right? :D
|
||||||
|
CFArrayApplyFunction(elements, range, DeviceElementDebugPrint, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
KeyboardMouse::KeyboardMouse(IOHIDDeviceRef device)
|
||||||
|
: m_device(device)
|
||||||
|
{
|
||||||
|
m_device_name = [(NSString *)IOHIDDeviceGetProperty(m_device, CFSTR(kIOHIDProductKey)) UTF8String];
|
||||||
|
|
||||||
|
// Go through all the elements of the device we've been given and try to make something out of them
|
||||||
|
CFArrayRef elements = IOHIDDeviceCopyMatchingElements(m_device, NULL, kIOHIDOptionsTypeNone);
|
||||||
|
CFIndex idx = 0;
|
||||||
|
for (IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, idx);
|
||||||
|
e;
|
||||||
|
e = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, ++idx))
|
||||||
|
{
|
||||||
|
if ((IOHIDElementGetType(e) == kIOHIDElementTypeInput_Button) &&
|
||||||
|
(IOHIDElementGetUsagePage(e) == kHIDPage_KeyboardOrKeypad) &&
|
||||||
|
(IOHIDElementGetLogicalMin(e) == 0) &&
|
||||||
|
(IOHIDElementGetLogicalMax(e) == 1))
|
||||||
|
{
|
||||||
|
inputs.push_back(new Key(e));
|
||||||
|
}
|
||||||
|
else if((IOHIDElementGetType(e) == kIOHIDElementTypeOutput) &&
|
||||||
|
(IOHIDElementGetUsagePage(e) == kHIDPage_LEDs) &&
|
||||||
|
(IOHIDElementGetLogicalMin(e) == 0) &&
|
||||||
|
(IOHIDElementGetLogicalMax(e) == 1))
|
||||||
|
{
|
||||||
|
outputs.push_back(new Light(e));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DeviceElementDebugPrint((void *)e, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
CFRelease(elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
ControlState KeyboardMouse::GetInputState( const ControllerInterface::Device::Input* const input )
|
||||||
|
{
|
||||||
|
return ((Input*)input)->GetState( &m_state_in );
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardMouse::SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state )
|
||||||
|
{
|
||||||
|
((Output*)output)->SetState(state, m_state_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyboardMouse::UpdateInput()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyboardMouse::UpdateOutput()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string KeyboardMouse::GetName() const
|
||||||
|
{
|
||||||
|
return m_device_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string KeyboardMouse::GetSource() const
|
||||||
|
{
|
||||||
|
return "OSX";
|
||||||
|
}
|
||||||
|
|
||||||
|
int KeyboardMouse::GetId() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
KeyboardMouse::Key::Key(IOHIDElementRef key_element)
|
||||||
|
: m_key_element(key_element)
|
||||||
|
{
|
||||||
|
std::ostringstream s;
|
||||||
|
s << IOHIDElementGetUsage(m_key_element);
|
||||||
|
m_key_name = s.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
ControlState KeyboardMouse::Key::GetState( const State* const state )
|
||||||
|
{
|
||||||
|
IOHIDValueRef value;
|
||||||
|
if (IOHIDDeviceGetValue(IOHIDElementGetDevice(m_key_element), m_key_element, &value) == kIOReturnSuccess)
|
||||||
|
{
|
||||||
|
double scaled_value = IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical);
|
||||||
|
//NSLog(@"element %x value %x scaled %f", IOHIDElementGetUsage(m_key_element), value, scaled_value);
|
||||||
|
return scaled_value > 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string KeyboardMouse::Key::GetName() const
|
||||||
|
{
|
||||||
|
return m_key_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
KeyboardMouse::Button::Button(IOHIDElementRef button_element)
|
||||||
|
: m_button_element(button_element)
|
||||||
|
{
|
||||||
|
std::ostringstream s;
|
||||||
|
s << IOHIDElementGetUsage(m_button_element);
|
||||||
|
m_button_name = s.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
ControlState KeyboardMouse::Button::GetState( const State* const state )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string KeyboardMouse::Button::GetName() const
|
||||||
|
{
|
||||||
|
return m_button_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
KeyboardMouse::Axis::Axis(IOHIDElementRef axis_element)
|
||||||
|
: m_axis_element(axis_element)
|
||||||
|
{
|
||||||
|
std::ostringstream s;
|
||||||
|
s << IOHIDElementGetUsage(m_axis_element);
|
||||||
|
m_axis_name = s.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
ControlState KeyboardMouse::Axis::GetState( const State* const state )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string KeyboardMouse::Axis::GetName() const
|
||||||
|
{
|
||||||
|
return m_axis_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
KeyboardMouse::Light::Light(IOHIDElementRef light_element)
|
||||||
|
: m_light_element(light_element)
|
||||||
|
{
|
||||||
|
int idx = IOHIDElementGetUsage(m_light_element);
|
||||||
|
m_light_name = (idx <= 5) ? named_lights[idx].name : "UNKNOWN";
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardMouse::Light::SetState( const ControlState state, unsigned char* const state_out )
|
||||||
|
{
|
||||||
|
uint64_t timestamp = 0;
|
||||||
|
IOHIDValueRef value = IOHIDValueCreateWithIntegerValue(kCFAllocatorDefault, m_light_element, timestamp, (int)state);
|
||||||
|
if (IOHIDDeviceSetValue(IOHIDElementGetDevice(m_light_element), m_light_element, value) == kIOReturnSuccess)
|
||||||
|
{
|
||||||
|
NSLog(@"element %x value %x", IOHIDElementGetUsage(m_light_element), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string KeyboardMouse::Light::GetName() const
|
||||||
|
{
|
||||||
|
return m_light_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,3 +0,0 @@
|
||||||
|
|
||||||
void OSX_Init(void *_View);
|
|
||||||
void OSX_UpdateKeys( int max, char* keys );
|
|
|
@ -1,38 +0,0 @@
|
||||||
#import <AppKit/NSWindow.h>
|
|
||||||
#import <AppKit/NSView.h>
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
|
|
||||||
#include "OSXPrivate.h"
|
|
||||||
NSWindow* m_Window;
|
|
||||||
void OSX_Init(void *_View)
|
|
||||||
{
|
|
||||||
// _View is really a wxNSView
|
|
||||||
//m_Window is really a wxNSWindow
|
|
||||||
NSView *View = (NSView*)_View;
|
|
||||||
m_Window = [View window];
|
|
||||||
}
|
|
||||||
|
|
||||||
void OSX_UpdateKeys( int max, char* keys )
|
|
||||||
{
|
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
||||||
|
|
||||||
NSEvent *event = [[NSEvent alloc] init];
|
|
||||||
|
|
||||||
/*event = [m_Window nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ];
|
|
||||||
|
|
||||||
if ( event != nil ) {
|
|
||||||
switch ([event type]) {
|
|
||||||
case NSKeyDown:
|
|
||||||
//case NSKeyUp:
|
|
||||||
//case NSFlagsChanged: // For Command
|
|
||||||
memcpy(keys, [[event characters] UTF8String], max);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
[m_Window sendEvent:event];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
[event release];
|
|
||||||
[pool release];
|
|
||||||
}
|
|
|
@ -28,8 +28,7 @@ if icenv['HAVE_SDL']:
|
||||||
|
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
files += [
|
files += [
|
||||||
'ControllerInterface/OSX/OSX.cpp',
|
'ControllerInterface/OSX/OSX.mm'
|
||||||
'ControllerInterface/OSX/OSXPrivate.mm'
|
|
||||||
]
|
]
|
||||||
icenv['FRAMEWORKS'] = ['IOKit']
|
icenv['FRAMEWORKS'] = ['IOKit']
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue