Add support for the mouse cursor and mouse clicking events on OS X.

This commit is contained in:
Grant Paul 2013-01-17 23:32:07 -08:00
parent 69b1da915f
commit 2f28d938cf
7 changed files with 110 additions and 6 deletions

1
.gitignore vendored
View File

@ -35,3 +35,4 @@ Source/Core/Common/Src/scmrev.h
*.ipch
.sconsign.dblite
Externals/scons-local/*
.DS_Store

View File

@ -1129,6 +1129,8 @@ void CFrame::OnConfigPAD(wxCommandEvent& WXUNUSED (event))
#if defined(HAVE_X11) && HAVE_X11
Window win = X11Utils::XWindowFromHandle(GetHandle());
Pad::Initialize((void *)win);
#elif defined(__APPLE__)
Pad::Initialize((void *)this);
#else
Pad::Initialize(GetHandle());
#endif
@ -1153,6 +1155,8 @@ void CFrame::OnConfigWiimote(wxCommandEvent& WXUNUSED (event))
#if defined(HAVE_X11) && HAVE_X11
Window win = X11Utils::XWindowFromHandle(GetHandle());
Wiimote::Initialize((void *)win);
#elif defined(__APPLE__)
Wiimote::Initialize((void *)this);
#else
Wiimote::Initialize(GetHandle());
#endif

View File

@ -45,7 +45,7 @@ void ControllerInterface::Initialize()
ciface::Xlib::Init(m_devices, m_hwnd);
#endif
#ifdef CIFACE_USE_OSX
ciface::OSX::Init(m_devices);
ciface::OSX::Init(m_devices, m_hwnd);
#endif
#ifdef CIFACE_USE_SDL
ciface::SDL::Init(m_devices);

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 *window);
void DeInit();
void DeviceElementDebugPrint(const void *, void *);

View File

@ -1,5 +1,6 @@
#include <Foundation/Foundation.h>
#include <IOKit/hid/IOHIDLib.h>
#include <Cocoa/Cocoa.h>
#include "../ControllerInterface.h"
#include "OSX.h"
@ -131,6 +132,7 @@ void DeviceDebugPrint(IOHIDDeviceRef device)
#endif
}
static void *g_window;
static void DeviceMatching_callback(void* inContext,
IOReturn inResult,
@ -150,7 +152,7 @@ static void DeviceMatching_callback(void* inContext,
if (IOHIDDeviceConformsTo(inIOHIDDeviceRef,
kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard))
devices->push_back(new Keyboard(inIOHIDDeviceRef,
name, kbd_name_counts[name]++));
name, kbd_name_counts[name]++, g_window));
#if 0
else if (IOHIDDeviceConformsTo(inIOHIDDeviceRef,
kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse))
@ -162,13 +164,15 @@ static void DeviceMatching_callback(void* inContext,
name, joy_name_counts[name]++));
}
void Init(std::vector<ControllerInterface::Device*>& devices)
void Init(std::vector<ControllerInterface::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

View File

@ -21,21 +21,51 @@ private:
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_index(index), m_axis(axis), 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_index(index), m_button(button) {}
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);
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;
void *m_window;
uint32_t m_windowid;
unsigned char m_mousebuttons[3];
};
}

View File

@ -1,5 +1,7 @@
#include <Foundation/Foundation.h>
#include <IOKit/hid/IOHIDLib.h>
#include <Cocoa/Cocoa.h>
#include <wx/wx.h> // wxWidgets
#include "../ControllerInterface.h"
#include "OSXKeyboard.h"
@ -9,10 +11,11 @@ namespace ciface
namespace OSX
{
Keyboard::Keyboard(IOHIDDeviceRef device, std::string name, int index)
Keyboard::Keyboard(IOHIDDeviceRef device, std::string name, int index, void *window)
: m_device(device)
, m_device_name(name)
, m_index(index)
, m_window(window)
{
// This class should only recieve Keyboard or Keypad devices
// Now, filter on just the buttons we can handle sanely
@ -39,10 +42,48 @@ Keyboard::Keyboard(IOHIDDeviceRef device, std::string name, int index)
}
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(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;
}
@ -201,10 +242,34 @@ ControlState Keyboard::Key::GetState() const
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;
}
}
}