Skip to content

Commit

Permalink
Add support for the mouse cursor and mouse clicking events on OS X.
Browse files Browse the repository at this point in the history
  • Loading branch information
grp committed Jan 18, 2013
1 parent 69b1da9 commit 2f28d93
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ Source/Core/Common/Src/scmrev.h
*.ipch
.sconsign.dblite
Externals/scons-local/*
.DS_Store
4 changes: 4 additions & 0 deletions Source/Core/DolphinWX/Src/FrameTools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/InputCommon/Src/ControllerInterface/OSX/OSX.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down
8 changes: 6 additions & 2 deletions Source/Core/InputCommon/Src/ControllerInterface/OSX/OSX.mm
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <Foundation/Foundation.h>
#include <IOKit/hid/IOHIDLib.h>
#include <Cocoa/Cocoa.h>

#include "../ControllerInterface.h"
#include "OSX.h"
Expand Down Expand Up @@ -131,6 +132,7 @@ void DeviceDebugPrint(IOHIDDeviceRef device)
#endif
}

static void *g_window;

static void DeviceMatching_callback(void* inContext,
IOReturn inResult,
Expand All @@ -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))
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,51 @@ class Keyboard : public ControllerInterface::Device
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];
};

}
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -9,10 +11,11 @@
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
Expand All @@ -39,10 +42,48 @@
}
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;
}

Expand Down Expand Up @@ -201,10 +242,34 @@
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;
}


}
}

0 comments on commit 2f28d93

Please sign in to comment.