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
180
|
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "barrier/KeyState.h"
#include "common/stdmap.h"
#include "common/stdset.h"
#include "common/stdvector.h"
#include <Carbon/Carbon.h>
typedef TISInputSourceRef KeyLayout;
class IOSXKeyResource;
//! OS X key state
/*!
A key state for OS X.
*/
class OSXKeyState : public KeyState {
public:
typedef std::vector<KeyID> KeyIDs;
OSXKeyState(IEventQueue* events);
OSXKeyState(IEventQueue* events, barrier::KeyMap& keyMap);
virtual ~OSXKeyState();
//! @name modifiers
//@{
//! Handle modifier key change
/*!
Determines which modifier keys have changed and updates the modifier
state and sends key events as appropriate.
*/
void handleModifierKeys(void* target,
KeyModifierMask oldMask, KeyModifierMask newMask);
//@}
//! @name accessors
//@{
//! Convert OS X modifier mask to barrier mask
/*!
Returns the barrier modifier mask corresponding to the OS X modifier
mask in \p mask.
*/
KeyModifierMask mapModifiersFromOSX(UInt32 mask) const;
//! Convert CG flags-style modifier mask to old-style Carbon
/*!
Still required in a few places for translation calls.
*/
KeyModifierMask mapModifiersToCarbon(UInt32 mask) const;
//! Map key event to keys
/*!
Converts a key event into a sequence of KeyIDs and the shadow modifier
state to a modifier mask. The KeyIDs list, in order, the characters
generated by the key press/release. It returns the id of the button
that was pressed or released, or 0 if the button doesn't map to a known
KeyID.
*/
KeyButton mapKeyFromEvent(KeyIDs& ids,
KeyModifierMask* maskOut, CGEventRef event) const;
//! Map key and mask to native values
/*!
Calculates mac virtual key and mask for a key \p key and modifiers
\p mask. Returns \c true if the key can be mapped, \c false otherwise.
*/
bool mapBarrierHotKeyToMac(KeyID key, KeyModifierMask mask,
UInt32& macVirtualKey,
UInt32& macModifierMask) const;
//@}
// IKeyState overrides
virtual bool fakeCtrlAltDel();
virtual bool fakeMediaKey(KeyID id);
virtual KeyModifierMask
pollActiveModifiers() const;
virtual SInt32 pollActiveGroup() const;
virtual void pollPressedKeys(KeyButtonSet& pressedKeys) const;
CGEventFlags getModifierStateAsOSXFlags();
protected:
// KeyState overrides
virtual void getKeyMap(barrier::KeyMap& keyMap);
virtual void fakeKey(const Keystroke& keystroke);
private:
class KeyResource;
typedef std::vector<KeyLayout> GroupList;
// Add hard coded special keys to a barrier::KeyMap.
void getKeyMapForSpecialKeys(
barrier::KeyMap& keyMap, SInt32 group) const;
// Convert keyboard resource to a key map
bool getKeyMap(barrier::KeyMap& keyMap,
SInt32 group, const IOSXKeyResource& r) const;
// Get the available keyboard groups
bool getGroups(GroupList&) const;
// Change active keyboard group to group
void setGroup(SInt32 group);
// Check if the keyboard layout has changed and update keyboard state
// if so.
void checkKeyboardLayout();
// Send an event for the given modifier key
void handleModifierKey(void* target,
UInt32 virtualKey, KeyID id,
bool down, KeyModifierMask newMask);
// Checks if any in \p ids is a glyph key and if \p isCommand is false.
// If so it adds the AltGr modifier to \p mask. This allows OS X
// servers to use the option key both as AltGr and as a modifier. If
// option is acting as AltGr (i.e. it generates a glyph and there are
// no command modifiers active) then we don't send the super modifier
// to clients because they'd try to match it as a command modifier.
void adjustAltGrModifier(const KeyIDs& ids,
KeyModifierMask* mask, bool isCommand) const;
// Maps an OS X virtual key id to a KeyButton. This simply remaps
// the ids so we don't use KeyButton 0.
static KeyButton mapVirtualKeyToKeyButton(UInt32 keyCode);
// Maps a KeyButton to an OS X key code. This is the inverse of
// mapVirtualKeyToKeyButton.
static UInt32 mapKeyButtonToVirtualKey(KeyButton keyButton);
void init();
// Post a key event to HID manager. It posts an event to HID client, a
// much lower level than window manager which's the target from carbon
// CGEventPost
void postHIDVirtualKey(const UInt8 virtualKeyCode,
const bool postDown);
private:
// OS X uses a physical key if 0 for the 'A' key. barrier reserves
// KeyButton 0 so we offset all OS X physical key ids by this much
// when used as a KeyButton and by minus this much to map a KeyButton
// to a physical button.
enum {
KeyButtonOffset = 1
};
typedef std::map<CFDataRef, SInt32> GroupMap;
typedef std::map<UInt32, KeyID> VirtualKeyMap;
VirtualKeyMap m_virtualKeyMap;
mutable UInt32 m_deadKeyState;
GroupList m_groups;
GroupMap m_groupMap;
bool m_shiftPressed;
bool m_controlPressed;
bool m_altPressed;
bool m_superPressed;
bool m_capsPressed;
};
|