-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSNIIS_Mac.h
179 lines (151 loc) · 6.28 KB
/
SNIIS_Mac.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/// @file SNIIS_Linux.h
/// Linux-specific classes
#pragma once
#include "SNIIS.h"
#if SNIIS_SYSTEM_MAC
#include <cmath>
#include <IOKit/hid/IOHIDLib.h>
#include <CoreGraphics/CoreGraphics.h>
#include "SNIIS_Mac_Helper.h"
class MacDevice;
class MacMouse;
class MacKeyboard;
class MacJoystick;
/// -------------------------------------------------------------------------------------------------------------------
/// Mac OSX Input System
class MacInput : public SNIIS::InputSystem
{
id mWindow;
IOHIDManagerRef mHidManager;
std::vector<MacDevice*> mMacDevices;
public:
MacInput( id pWindowId);
~MacInput();
void Update() override;
void InternSetFocus(bool pHasFocus) override;
void InternSetMouseGrab( bool enabled) override;
id GetWindowId() const { return mWindow; }
protected:
static void HandleNewDeviceCallback( void* context, IOReturn result, void* sender, IOHIDDeviceRef device);
void HandleNewDevice( IOHIDDeviceRef device);
};
/// -------------------------------------------------------------------------------------------------------------------
/// Describes a control of a HID - it's the same for all kinds of devices on Mac, which makes things confortable
struct MacControl
{
enum Type { Type_Axis, Type_Hat, Type_Hat_Second, Type_Button };
IOHIDDeviceRef mDevice;
Type mType;
std::string mName;
IOHIDElementCookie mCookie;
uint32_t mUsePage, mUsage;
long mMin, mMax; // only for Type_Axis
};
std::vector<MacControl> EnumerateDeviceControls( IOHIDDeviceRef devref);
void InputElementValueChangeCallback( void* ctx, IOReturn res, void* sender, IOHIDValueRef val);
std::pair<float, float> ConvertHatToAxes( long min, long max, long value);
/// -------------------------------------------------------------------------------------------------------------------
/// common Mac device interface, because they all work on USB HID data
class MacDevice
{
friend class MacInput;
public:
MacDevice( MacInput* pSystem, IOHIDDeviceRef pDeviceRef) : mSystem( pSystem), mDevice( pDeviceRef) { }
/// Starts the update
virtual void StartUpdate() = 0;
/// Handles an input event coming from the USB HID callback
virtual void HandleEvent( IOHIDDeviceRef dev, IOHIDElementCookie cookie, uint32_t usepage, uint32_t usage, CFIndex value) = 0;
/// Notifies the input device that the application has lost/gained focus.
virtual void SetFocus( bool pHasFocus) = 0;
protected:
MacInput* mSystem;
IOHIDDeviceRef mDevice;
};
/// -------------------------------------------------------------------------------------------------------------------
/// Mac mouse, fed by USB HID events
class MacMouse : public SNIIS::Mouse, public MacDevice
{
bool mIsTrackpad;
struct State
{
float axes[16], prevAxes[16];
uint32_t buttons, prevButtons;
} mState;
std::vector<MacControl> mButtons, mAxes, mSecondaryButtons, mSecondaryAxes;
public:
MacMouse( MacInput* pSystem, size_t pId, IOHIDDeviceRef pDeviceRef, bool isTrackpad);
/// The MacBook shows up as two separate mice, where one does the movement and the other does clicks and wheel... unite those
void AddDevice( IOHIDDeviceRef pRef);
~MacMouse();
void StartUpdate() override;
void HandleEvent( IOHIDDeviceRef dev, IOHIDElementCookie cookie, uint32_t usepage, uint32_t usage, CFIndex value) override;
void EndUpdate();
void SetFocus( bool pHasFocus) override;
bool IsTrackpad() const { return mIsTrackpad; }
size_t GetNumButtons() const override;
std::string GetButtonText( size_t idx) const override;
size_t GetNumAxes() const override;
std::string GetAxisText( size_t idx) const override;
bool IsButtonDown( size_t idx) const override;
bool WasButtonPressed( size_t idx) const override;
bool WasButtonReleased( size_t idx) const override;
float GetAxisAbsolute( size_t idx) const override;
float GetAxisDifference( size_t idx) const override;
float GetMouseX() const override;
float GetMouseY() const override;
float GetRelMouseX() const override;
float GetRelMouseY() const override;
private:
void DoMouseWheel( float wheel);
void DoMouseButton( size_t btnIndex, bool isPressed);
};
/// -------------------------------------------------------------------------------------------------------------------
/// OSX keyboard, aswell fed by USB
class MacKeyboard : public SNIIS::Keyboard, public MacDevice
{
size_t mNumKeys;
std::vector<uint32_t> mExtraButtons;
std::vector<uint64_t> mState, mPrevState; ///< current and previous keystate
unsigned long mDeadKeyState; // "Uint32" - lol
public:
MacKeyboard( MacInput* pSystem, size_t pId, IOHIDDeviceRef pDeviceRef);
void StartUpdate() override;
void HandleEvent( IOHIDDeviceRef dev, IOHIDElementCookie cookie, uint32_t usepage, uint32_t usage, CFIndex value) override;
void SetFocus( bool pHasFocus) override;
size_t GetNumButtons() const override;
std::string GetButtonText( size_t idx) const override;
bool IsButtonDown( size_t idx) const override;
bool WasButtonPressed( size_t idx) const override;
bool WasButtonReleased( size_t idx) const override;
protected:
void DoKeyboardKey(SNIIS::KeyCode kc, size_t unicode, bool isPressed);
void Set( size_t kc, bool set);
bool IsSet( size_t kc) const;
bool WasSet( size_t kc) const;
size_t TranslateText( size_t kc);
};
/// -------------------------------------------------------------------------------------------------------------------
/// OSX joystick
class MacJoystick : public SNIIS::Joystick, public MacDevice
{
std::vector<MacControl> mButtons, mAxes;
struct State {
uint64_t buttons, prevButtons;
float axes[16], diffs[16];
} mState;
public:
MacJoystick( MacInput* pSystem, size_t pId, IOHIDDeviceRef pDeviceRef);
void StartUpdate() override;
void HandleEvent( IOHIDDeviceRef dev, IOHIDElementCookie cookie, uint32_t usepage, uint32_t usage, CFIndex value) override;
void SetFocus( bool pHasFocus) override;
size_t GetNumButtons() const override;
std::string GetButtonText( size_t idx) const override;
size_t GetNumAxes() const override;
std::string GetAxisText( size_t idx) const override;
bool IsButtonDown( size_t idx) const override;
bool WasButtonPressed( size_t idx) const override;
bool WasButtonReleased( size_t idx) const override;
float GetAxisAbsolute( size_t idx) const override;
float GetAxisDifference( size_t idx) const override;
};
#endif // SNIIS_SYSTEM_MAC