diff options
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface/OSX')
6 files changed, 930 insertions, 0 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.h b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.h new file mode 100644 index 0000000000..a922e3f2dd --- /dev/null +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.h @@ -0,0 +1,16 @@ +#pragma once + +#include "../Device.h" + +namespace ciface +{ +namespace OSX +{ + +void Init(std::vector<Core::Device*>& devices, void *window); +void DeInit(); + +void DeviceElementDebugPrint(const void *, void *); + +} +} diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm new file mode 100644 index 0000000000..8a859f46c8 --- /dev/null +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm @@ -0,0 +1,213 @@ +#include <Foundation/Foundation.h> +#include <IOKit/hid/IOHIDLib.h> +#include <Cocoa/Cocoa.h> + +#include "OSX.h" +#include "OSXKeyboard.h" +#include "OSXJoystick.h" + +#include <map> + +namespace ciface +{ +namespace OSX +{ + + +static IOHIDManagerRef HIDManager = NULL; +static CFStringRef OurRunLoop = CFSTR("DolphinOSXInput"); +static std::map<std::string, int> kbd_name_counts, joy_name_counts; + +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; + } + + 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: %@ " + "lmin: %ld lmax: %ld pmin: %ld pmax: %ld", + type.c_str(), + type == "collection" ? ":" : "", + type == "collection" ? c_type.c_str() : " ", + IOHIDElementGetUsagePage(e), + IOHIDElementGetUsage(e), + 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); + } +} + +void DeviceDebugPrint(IOHIDDeviceRef device) +{ +#if 0 +#define shortlog(x) NSLog(@"%s: %@", \ + x, IOHIDDeviceGetProperty(device, CFSTR(x))); + NSLog(@"-------------------------"); + NSLog(@"Got Device: %@", + IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey))); + 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) +#endif +} + +static void *g_window; + +static void DeviceMatching_callback(void* inContext, + IOReturn inResult, + void *inSender, + IOHIDDeviceRef inIOHIDDeviceRef) +{ + NSString *pName = (NSString *) + IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDProductKey)); + std::string name = (pName != NULL) ? [pName UTF8String] : "Unknown device"; + + DeviceDebugPrint(inIOHIDDeviceRef); + + std::vector<Core::Device*> *devices = + (std::vector<Core::Device*> *)inContext; + + // Add to the devices vector if it's of a type we want + if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, + kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard)) + devices->push_back(new Keyboard(inIOHIDDeviceRef, + name, kbd_name_counts[name]++, g_window)); +#if 0 + else if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, + kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse)) + devices->push_back(new Mouse(inIOHIDDeviceRef, + name, mouse_name_counts[name]++)); +#endif + else + devices->push_back(new Joystick(inIOHIDDeviceRef, + name, joy_name_counts[name]++)); +} + +void Init(std::vector<Core::Device*>& devices, void *window) +{ + HIDManager = IOHIDManagerCreate(kCFAllocatorDefault, + kIOHIDOptionsTypeNone); + if (!HIDManager) + NSLog(@"Failed to create HID Manager reference"); + + g_window = window; + + IOHIDManagerSetDeviceMatching(HIDManager, NULL); + + // 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"); + + kbd_name_counts.clear(); + joy_name_counts.clear(); + + // Wait while current devices are initialized + while (CFRunLoopRunInMode(OurRunLoop, 0, TRUE) == + kCFRunLoopRunHandledSource) {}; + + // Things should be configured now + // Disable hotplugging and other scheduling + IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, NULL, NULL); + IOHIDManagerUnscheduleFromRunLoop(HIDManager, + CFRunLoopGetCurrent(), OurRunLoop); +} + +void DeInit() +{ + // This closes all devices as well + IOHIDManagerClose(HIDManager, kIOHIDOptionsTypeNone); + CFRelease(HIDManager); +} + + +} +} diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h new file mode 100644 index 0000000000..ebe908522b --- /dev/null +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h @@ -0,0 +1,80 @@ +#include <IOKit/hid/IOHIDLib.h> + +#include "../Device.h" + +namespace ciface +{ +namespace OSX +{ + +class Joystick : public Core::Device +{ +private: + class Button : public Input + { + public: + std::string GetName() const; + Button(IOHIDElementRef element, IOHIDDeviceRef device) + : m_element(element), m_device(device) {} + ControlState GetState() const; + private: + const IOHIDElementRef m_element; + const IOHIDDeviceRef m_device; + }; + + class Axis : public Input + { + public: + enum direction { + positive = 0, + negative + }; + std::string GetName() const; + Axis(IOHIDElementRef element, IOHIDDeviceRef device, direction dir); + ControlState GetState() const; + private: + const IOHIDElementRef m_element; + const IOHIDDeviceRef m_device; + std::string m_name; + const direction m_direction; + float m_neutral; + float m_scale; + }; + + class Hat : public Input + { + public: + enum direction { + up = 0, + right, + down, + left + }; + std::string GetName() const; + Hat(IOHIDElementRef element, IOHIDDeviceRef device, direction dir); + ControlState GetState() const; + private: + const IOHIDElementRef m_element; + const IOHIDDeviceRef m_device; + const char* m_name; + const direction m_direction; + }; + +public: + bool UpdateInput(); + bool UpdateOutput(); + + Joystick(IOHIDDeviceRef device, std::string name, int index); + + std::string GetName() const; + std::string GetSource() const; + int GetId() const; + +private: + const IOHIDDeviceRef m_device; + const std::string m_device_name; + const int m_index; +}; + +} +} diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm new file mode 100644 index 0000000000..ebd713d142 --- /dev/null +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm @@ -0,0 +1,274 @@ +#include <Foundation/Foundation.h> +#include <IOKit/hid/IOHIDLib.h> + +#include "OSXJoystick.h" + +#include <sstream> + +namespace ciface +{ +namespace OSX +{ + + +Joystick::Joystick(IOHIDDeviceRef device, std::string name, int index) + : m_device(device) + , m_device_name(name) + , m_index(index) +{ + // Buttons + NSDictionary *buttonDict = + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInteger: kIOHIDElementTypeInput_Button], + @kIOHIDElementTypeKey, + [NSNumber numberWithInteger: kHIDPage_Button], + @kIOHIDElementUsagePageKey, + nil]; + + CFArrayRef buttons = IOHIDDeviceCopyMatchingElements(m_device, + (CFDictionaryRef)buttonDict, kIOHIDOptionsTypeNone); + + if (buttons) + { + for (int i = 0; i < CFArrayGetCount(buttons); i++) + { + IOHIDElementRef e = + (IOHIDElementRef)CFArrayGetValueAtIndex(buttons, i); + //DeviceElementDebugPrint(e, NULL); + + AddInput(new Button(e, m_device)); + } + CFRelease(buttons); + } + + // Axes + NSDictionary *axisDict = + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInteger: kIOHIDElementTypeInput_Misc], + @kIOHIDElementTypeKey, + nil]; + + CFArrayRef axes = IOHIDDeviceCopyMatchingElements(m_device, + (CFDictionaryRef)axisDict, kIOHIDOptionsTypeNone); + + if (axes) + { + for (int i = 0; i < CFArrayGetCount(axes); i++) + { + IOHIDElementRef e = + (IOHIDElementRef)CFArrayGetValueAtIndex(axes, i); + //DeviceElementDebugPrint(e, NULL); + + if (IOHIDElementGetUsage(e) == kHIDUsage_GD_Hatswitch) { + AddInput(new Hat(e, m_device, Hat::up)); + AddInput(new Hat(e, m_device, Hat::right)); + AddInput(new Hat(e, m_device, Hat::down)); + AddInput(new Hat(e, m_device, Hat::left)); + } else { + AddAnalogInputs(new Axis(e, m_device, Axis::negative), + new Axis(e, m_device, Axis::positive)); + } + } + CFRelease(axes); + } +} + +bool Joystick::UpdateInput() +{ + return true; +} + +bool Joystick::UpdateOutput() +{ + return true; +} + +std::string Joystick::GetName() const +{ + return m_device_name; +} + +std::string Joystick::GetSource() const +{ + return "Input"; +} + +int Joystick::GetId() const +{ + return m_index; +} + +ControlState Joystick::Button::GetState() const +{ + IOHIDValueRef value; + if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess) + return IOHIDValueGetIntegerValue(value); + else + return 0; +} + +std::string Joystick::Button::GetName() const +{ + std::ostringstream s; + s << IOHIDElementGetUsage(m_element); + return std::string("Button ") + s.str(); +} + +Joystick::Axis::Axis(IOHIDElementRef element, IOHIDDeviceRef device, direction dir) + : m_element(element) + , m_device(device) + , m_direction(dir) +{ + // Need to parse the element a bit first + std::string description("unk"); + + int const usage = IOHIDElementGetUsage(m_element); + switch (usage) + { + case kHIDUsage_GD_X: + description = "X"; + break; + case kHIDUsage_GD_Y: + description = "Y"; + break; + case kHIDUsage_GD_Z: + description = "Z"; + break; + case kHIDUsage_GD_Rx: + description = "Rx"; + break; + case kHIDUsage_GD_Ry: + description = "Ry"; + break; + case kHIDUsage_GD_Rz: + description = "Rz"; + break; + case kHIDUsage_GD_Wheel: + description = "Wheel"; + break; + case kHIDUsage_Csmr_ACPan: + description = "Pan"; + break; + default: + { + std::ostringstream s; + s << usage; + description = s.str(); + break; + } + } + + m_name = std::string("Axis ") + description; + m_name.append((m_direction == positive) ? "+" : "-"); + + m_neutral = (IOHIDElementGetLogicalMax(m_element) + + IOHIDElementGetLogicalMin(m_element)) / 2.; + m_scale = 1 / fabs(IOHIDElementGetLogicalMax(m_element) - m_neutral); +} + +ControlState Joystick::Axis::GetState() const +{ + IOHIDValueRef value; + + if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess) + { + // IOHIDValueGetIntegerValue() crashes when trying + // to convert unusually large element values. + if (IOHIDValueGetLength(value) > 2) + return 0; + + float position = IOHIDValueGetIntegerValue(value); + + if (m_direction == positive && position > m_neutral) + return (position - m_neutral) * m_scale; + if (m_direction == negative && position < m_neutral) + return (m_neutral - position) * m_scale; + } + + return 0; +} + +std::string Joystick::Axis::GetName() const +{ + return m_name; +} + +Joystick::Hat::Hat(IOHIDElementRef element, IOHIDDeviceRef device, direction dir) + : m_element(element) + , m_device(device) + , m_direction(dir) +{ + switch (dir) { + case up: + m_name = "Up"; + break; + case right: + m_name = "Right"; + break; + case down: + m_name = "Down"; + break; + case left: + m_name = "Left"; + break; + default: + m_name = "unk"; + } +} + +ControlState Joystick::Hat::GetState() const +{ + IOHIDValueRef value; + int position; + + if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess) + { + position = IOHIDValueGetIntegerValue(value); + + switch (position) { + case 0: + if (m_direction == up) + return 1; + break; + case 1: + if (m_direction == up || m_direction == right) + return 1; + break; + case 2: + if (m_direction == right) + return 1; + break; + case 3: + if (m_direction == right || m_direction == down) + return 1; + break; + case 4: + if (m_direction == down) + return 1; + break; + case 5: + if (m_direction == down || m_direction == left) + return 1; + break; + case 6: + if (m_direction == left) + return 1; + break; + case 7: + if (m_direction == left || m_direction == up) + return 1; + break; + }; + } + + return 0; +} + +std::string Joystick::Hat::GetName() const +{ + return m_name; +} + + +} +} diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.h b/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.h new file mode 100644 index 0000000000..e5c2c1b3d4 --- /dev/null +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.h @@ -0,0 +1,71 @@ +#include <IOKit/hid/IOHIDLib.h> + +#include "../Device.h" + +namespace ciface +{ +namespace OSX +{ + +class Keyboard : public Core::Device +{ +private: + class Key : public Input + { + public: + std::string GetName() const; + Key(IOHIDElementRef element, IOHIDDeviceRef device); + ControlState GetState() const; + private: + const IOHIDElementRef m_element; + const IOHIDDeviceRef m_device; + std::string m_name; + }; + class Cursor : public Input + { + public: + std::string GetName() const; + bool IsDetectable() { return false; } + Cursor(u8 index, const float& axis, const bool positive) : m_axis(axis), m_index(index), m_positive(positive) {} + ControlState GetState() const; + private: + const float& m_axis; + const u8 m_index; + const bool m_positive; + }; + class Button : public Input + { + public: + std::string GetName() const; + Button(u8 index, const unsigned char& button) : m_button(button), m_index(index) {} + ControlState GetState() const; + private: + const unsigned char& m_button; + const u8 m_index; + }; + +public: + bool UpdateInput(); + bool UpdateOutput(); + + Keyboard(IOHIDDeviceRef device, std::string name, int index, void *window); + + std::string GetName() const; + std::string GetSource() const; + int GetId() const; + +private: + struct + { + float x, y; + } m_cursor; + + const IOHIDDeviceRef m_device; + const std::string m_device_name; + int m_index; + uint32_t m_windowid; + unsigned char m_mousebuttons[3]; +}; + +} +} diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.mm b/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.mm new file mode 100644 index 0000000000..93de15daa4 --- /dev/null +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.mm @@ -0,0 +1,276 @@ +#include <Foundation/Foundation.h> +#include <IOKit/hid/IOHIDLib.h> +#include <Cocoa/Cocoa.h> +#include <wx/wx.h> // wxWidgets + +#include "OSXKeyboard.h" + +#include <sstream> + +namespace ciface +{ +namespace OSX +{ + +Keyboard::Keyboard(IOHIDDeviceRef device, std::string name, int index, void *window) + : m_device(device) + , m_device_name(name) + , m_index(index) +{ + // 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, + nil]; + + CFArrayRef elements = IOHIDDeviceCopyMatchingElements(m_device, + (CFDictionaryRef)matchingElements, kIOHIDOptionsTypeNone); + + if (elements) + { + for (int i = 0; i < CFArrayGetCount(elements); i++) + { + IOHIDElementRef e = + (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i); + //DeviceElementDebugPrint(e, NULL); + + AddInput(new Key(e, m_device)); + } + CFRelease(elements); + } + + m_windowid = [[(NSView *)(((wxWindow *)window)->GetHandle()) window] windowNumber]; + + // cursor, with a hax for-loop + for (unsigned int i=0; i<4; ++i) + AddInput(new Cursor(!!(i&2), (&m_cursor.x)[i/2], !!(i&1))); + + for (u8 i = 0; i < sizeof(m_mousebuttons) / sizeof(m_mousebuttons[0]); ++i) + AddInput(new Button(i, m_mousebuttons[i])); +} + +bool Keyboard::UpdateInput() +{ + CGRect bounds = CGRectZero; + uint32_t windowid[1] = { m_windowid }; + CFArrayRef windowArray = CFArrayCreate(NULL, (const void **) windowid, 1, NULL); + CFArrayRef windowDescriptions = CGWindowListCreateDescriptionFromArray(windowArray); + CFDictionaryRef windowDescription = (CFDictionaryRef) CFArrayGetValueAtIndex((CFArrayRef) windowDescriptions, 0); + + if (CFDictionaryContainsKey(windowDescription, kCGWindowBounds)) + { + CFDictionaryRef boundsDictionary = (CFDictionaryRef) CFDictionaryGetValue(windowDescription, kCGWindowBounds); + + if (boundsDictionary != NULL) + CGRectMakeWithDictionaryRepresentation(boundsDictionary, &bounds); + } + + CFRelease(windowDescriptions); + CFRelease(windowArray); + + CGEventRef event = CGEventCreate(nil); + CGPoint loc = CGEventGetLocation(event); + CFRelease(event); + + loc.x -= bounds.origin.x; + loc.y -= bounds.origin.y; + m_cursor.x = loc.x / bounds.size.width * 2 - 1.0; + m_cursor.y = loc.y / bounds.size.height * 2 - 1.0; + + m_mousebuttons[0] = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonLeft); + m_mousebuttons[1] = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonRight); + m_mousebuttons[2] = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonCenter); + + return true; +} + +bool Keyboard::UpdateOutput() +{ + return true; +} + +std::string Keyboard::GetName() const +{ + return m_device_name; +} + +std::string Keyboard::GetSource() const +{ + return "Keyboard"; +} + +int Keyboard::GetId() const +{ + return m_index; +} + +Keyboard::Key::Key(IOHIDElementRef element, IOHIDDeviceRef device) + : m_element(element) + , m_device(device) +{ + static const struct PrettyKeys { + const uint32_t code; + const char *const name; + } named_keys[] = { + { kHIDUsage_KeyboardA, "A" }, + { kHIDUsage_KeyboardB, "B" }, + { kHIDUsage_KeyboardC, "C" }, + { kHIDUsage_KeyboardD, "D" }, + { kHIDUsage_KeyboardE, "E" }, + { kHIDUsage_KeyboardF, "F" }, + { kHIDUsage_KeyboardG, "G" }, + { kHIDUsage_KeyboardH, "H" }, + { kHIDUsage_KeyboardI, "I" }, + { kHIDUsage_KeyboardJ, "J" }, + { kHIDUsage_KeyboardK, "K" }, + { kHIDUsage_KeyboardL, "L" }, + { kHIDUsage_KeyboardM, "M" }, + { kHIDUsage_KeyboardN, "N" }, + { kHIDUsage_KeyboardO, "O" }, + { kHIDUsage_KeyboardP, "P" }, + { kHIDUsage_KeyboardQ, "Q" }, + { kHIDUsage_KeyboardR, "R" }, + { kHIDUsage_KeyboardS, "S" }, + { kHIDUsage_KeyboardT, "T" }, + { kHIDUsage_KeyboardU, "U" }, + { kHIDUsage_KeyboardV, "V" }, + { kHIDUsage_KeyboardW, "W" }, + { kHIDUsage_KeyboardX, "X" }, + { kHIDUsage_KeyboardY, "Y" }, + { kHIDUsage_KeyboardZ, "Z" }, + { kHIDUsage_Keyboard1, "1" }, + { kHIDUsage_Keyboard2, "2" }, + { kHIDUsage_Keyboard3, "3" }, + { kHIDUsage_Keyboard4, "4" }, + { kHIDUsage_Keyboard5, "5" }, + { kHIDUsage_Keyboard6, "6" }, + { kHIDUsage_Keyboard7, "7" }, + { kHIDUsage_Keyboard8, "8" }, + { kHIDUsage_Keyboard9, "9" }, + { kHIDUsage_Keyboard0, "0" }, + { kHIDUsage_KeyboardReturnOrEnter, "Return" }, + { kHIDUsage_KeyboardEscape, "Escape" }, + { kHIDUsage_KeyboardDeleteOrBackspace, "Backspace" }, + { kHIDUsage_KeyboardTab, "Tab" }, + { kHIDUsage_KeyboardSpacebar, "Space" }, + { kHIDUsage_KeyboardHyphen, "-" }, + { kHIDUsage_KeyboardEqualSign, "=" }, + { kHIDUsage_KeyboardOpenBracket, "[" }, + { kHIDUsage_KeyboardCloseBracket, "]" }, + { kHIDUsage_KeyboardBackslash, "\\" }, + { kHIDUsage_KeyboardSemicolon, ";" }, + { kHIDUsage_KeyboardQuote, "'" }, + { kHIDUsage_KeyboardGraveAccentAndTilde, "Tilde" }, + { kHIDUsage_KeyboardComma, "," }, + { kHIDUsage_KeyboardPeriod, "." }, + { kHIDUsage_KeyboardSlash, "/" }, + { kHIDUsage_KeyboardCapsLock, "Caps Lock" }, + { kHIDUsage_KeyboardF1, "F1" }, + { kHIDUsage_KeyboardF2, "F2" }, + { kHIDUsage_KeyboardF3, "F3" }, + { kHIDUsage_KeyboardF4, "F4" }, + { kHIDUsage_KeyboardF5, "F5" }, + { kHIDUsage_KeyboardF6, "F6" }, + { kHIDUsage_KeyboardF7, "F7" }, + { kHIDUsage_KeyboardF8, "F8" }, + { kHIDUsage_KeyboardF9, "F9" }, + { kHIDUsage_KeyboardF10, "F10" }, + { kHIDUsage_KeyboardF11, "F11" }, + { kHIDUsage_KeyboardF12, "F12" }, + { kHIDUsage_KeyboardInsert, "Insert" }, + { kHIDUsage_KeyboardHome, "Home" }, + { kHIDUsage_KeyboardPageUp, "Page Up" }, + { kHIDUsage_KeyboardDeleteForward, "Delete" }, + { kHIDUsage_KeyboardEnd, "End" }, + { kHIDUsage_KeyboardPageDown, "Page Down" }, + { kHIDUsage_KeyboardRightArrow, "Right Arrow" }, + { kHIDUsage_KeyboardLeftArrow, "Left Arrow" }, + { kHIDUsage_KeyboardDownArrow, "Down Arrow" }, + { kHIDUsage_KeyboardUpArrow, "Up Arrow" }, + { kHIDUsage_KeypadSlash, "Keypad /" }, + { kHIDUsage_KeypadAsterisk, "Keypad *" }, + { kHIDUsage_KeypadHyphen, "Keypad -" }, + { kHIDUsage_KeypadPlus, "Keypad +" }, + { kHIDUsage_KeypadEnter, "Keypad Enter" }, + { kHIDUsage_Keypad1, "Keypad 1" }, + { kHIDUsage_Keypad2, "Keypad 2" }, + { kHIDUsage_Keypad3, "Keypad 3" }, + { kHIDUsage_Keypad4, "Keypad 4" }, + { kHIDUsage_Keypad5, "Keypad 5" }, + { kHIDUsage_Keypad6, "Keypad 6" }, + { kHIDUsage_Keypad7, "Keypad 7" }, + { kHIDUsage_Keypad8, "Keypad 8" }, + { kHIDUsage_Keypad9, "Keypad 9" }, + { kHIDUsage_Keypad0, "Keypad 0" }, + { kHIDUsage_KeypadPeriod, "Keypad ." }, + { kHIDUsage_KeyboardNonUSBackslash, "Paragraph" }, + { kHIDUsage_KeypadEqualSign, "Keypad =" }, + { kHIDUsage_KeypadComma, "Keypad ," }, + { kHIDUsage_KeyboardLeftControl, "Left Control" }, + { kHIDUsage_KeyboardLeftShift, "Left Shift" }, + { kHIDUsage_KeyboardLeftAlt, "Left Alt" }, + { kHIDUsage_KeyboardLeftGUI, "Left Command" }, + { kHIDUsage_KeyboardRightControl, "Right Control" }, + { kHIDUsage_KeyboardRightShift, "Right Shift" }, + { kHIDUsage_KeyboardRightAlt, "Right Alt" }, + { kHIDUsage_KeyboardRightGUI, "Right Command" }, + { 184, "Eject" }, + }; + + const uint32_t keycode = IOHIDElementGetUsage(m_element); + for (auto & named_key : named_keys) + if (named_key.code == keycode) { + m_name = named_key.name; + return; + } + + std::stringstream ss; + ss << "Key " << keycode; + m_name = ss.str(); +} + +ControlState Keyboard::Key::GetState() const +{ + IOHIDValueRef value; + + if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess) + return IOHIDValueGetIntegerValue(value); + else + return 0; +} + +ControlState Keyboard::Cursor::GetState() const +{ + return std::max(0.0f, ControlState(m_axis) / (m_positive ? 1.0f : -1.0f)); +} + +ControlState Keyboard::Button::GetState() const +{ + return (m_button != 0); +} + +std::string Keyboard::Cursor::GetName() const +{ + static char tmpstr[] = "Cursor .."; + tmpstr[7] = (char)('X' + m_index); + tmpstr[8] = (m_positive ? '+' : '-'); + return tmpstr; +} + +std::string Keyboard::Button::GetName() const +{ + return std::string("Click ") + char('0' + m_index); +} + +std::string Keyboard::Key::GetName() const +{ + return m_name; +} + + +} +} |
