1 | /*
|
---|
2 | * synergy -- mouse and keyboard sharing utility
|
---|
3 | * Copyright (C) 2003 Chris Schoeneman
|
---|
4 | * Copyright (C) 2006 Knut St. Osmundsen
|
---|
5 | *
|
---|
6 | * This package is free software; you can redistribute it and/or
|
---|
7 | * modify it under the terms of the GNU General Public License
|
---|
8 | * found in the file COPYING that should have accompanied this file.
|
---|
9 | *
|
---|
10 | * This package is distributed in the hope that it will be useful,
|
---|
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
13 | * GNU General Public License for more details.
|
---|
14 | */
|
---|
15 |
|
---|
16 | #ifndef CPMKEYSTATE_H
|
---|
17 | #define CPMKEYSTATE_H
|
---|
18 |
|
---|
19 | #include "CKeyState.h"
|
---|
20 | #include "CString.h"
|
---|
21 | #include "CPMSynergyHook.h"
|
---|
22 | #include "stdvector.h"
|
---|
23 | #define INCL_ERRORS
|
---|
24 | #define INCL_BASE
|
---|
25 | #define INCL_PM
|
---|
26 | #include <os2.h>
|
---|
27 |
|
---|
28 | class CEvent;
|
---|
29 | class CEventQueueTimer;
|
---|
30 |
|
---|
31 | //! Microsoft Windows key mapper
|
---|
32 | /*!
|
---|
33 | This class maps KeyIDs to keystrokes.
|
---|
34 | */
|
---|
35 | class CPMKeyState : public CKeyState {
|
---|
36 | public:
|
---|
37 | CPMKeyState(void* eventTarget, FakeMsgFunc fakeMsg);
|
---|
38 | virtual ~CPMKeyState();
|
---|
39 |
|
---|
40 | //! @name manipulators
|
---|
41 | //@{
|
---|
42 |
|
---|
43 | //! Handle screen disabling
|
---|
44 | /*!
|
---|
45 | Called when screen is disabled. This is needed to deal with platform
|
---|
46 | brokenness.
|
---|
47 | */
|
---|
48 | void disable();
|
---|
49 |
|
---|
50 | //! Test and set autorepeat state
|
---|
51 | /*!
|
---|
52 | Returns true if the given button is autorepeating and updates internal
|
---|
53 | state.
|
---|
54 | */
|
---|
55 | bool testAutoRepeat(bool press, bool isRepeat, KeyButton);
|
---|
56 |
|
---|
57 | //! Remember modifier state
|
---|
58 | /*!
|
---|
59 | Records the current non-toggle modifier state.
|
---|
60 | */
|
---|
61 | void saveModifiers();
|
---|
62 |
|
---|
63 | //! Set effective modifier state
|
---|
64 | /*!
|
---|
65 | Temporarily sets the non-toggle modifier state to those saved by the
|
---|
66 | last call to \c saveModifiers if \p enable is \c true. Restores the
|
---|
67 | modifier state to the current modifier state if \p enable is \c false.
|
---|
68 | This is for synthesizing keystrokes on the primary screen when the
|
---|
69 | cursor is on a secondary screen. When on a secondary screen we capture
|
---|
70 | all non-toggle modifier state, track the state internally and do not
|
---|
71 | pass it on. So if Alt+F1 synthesizes Alt+X we need to synthesize
|
---|
72 | not just X but also Alt, despite the fact that our internal modifier
|
---|
73 | state indicates Alt is down, because local apps never saw the Alt down
|
---|
74 | event.
|
---|
75 | */
|
---|
76 | void useSavedModifiers(bool enable);
|
---|
77 |
|
---|
78 | //@}
|
---|
79 | //! @name accessors
|
---|
80 | //@{
|
---|
81 |
|
---|
82 | //! Map a virtual key to a button
|
---|
83 | /*!
|
---|
84 | Returns the button for the \p virtualKey.
|
---|
85 | */
|
---|
86 | KeyButton virtualKeyToButton(ULONG virtualKey) const;
|
---|
87 |
|
---|
88 | //! Map key event to a key
|
---|
89 | /*!
|
---|
90 | Converts a key event into a KeyID and the shadow modifier state
|
---|
91 | to a modifier mask.
|
---|
92 | */
|
---|
93 | KeyID mapKeyFromEvent(USHORT fsFlags, UCHAR ucRepeat, UCHAR ucScanCode, USHORT usch, USHORT usvk, KeyModifierMask* maskOut) const;
|
---|
94 |
|
---|
95 | //! Check if keyboard groups have changed
|
---|
96 | /*!
|
---|
97 | Returns true iff the number or order of the keyboard groups have
|
---|
98 | changed since the last call to updateKeys().
|
---|
99 | */
|
---|
100 | bool didGroupsChange() const;
|
---|
101 |
|
---|
102 | //! Map key to virtual key
|
---|
103 | /*!
|
---|
104 | Returns the virtual key for key \p key or 0 if there's no such virtual
|
---|
105 | key.
|
---|
106 | */
|
---|
107 | ULONG mapKeyToVirtualKey(KeyID key) const;
|
---|
108 |
|
---|
109 | //! Map virtual key and button to KeyID
|
---|
110 | /*!
|
---|
111 | Returns the KeyID for virtual key \p virtualKey and button \p button
|
---|
112 | (button should include the extended key bit), or kKeyNone if there is
|
---|
113 | no such key.
|
---|
114 | */
|
---|
115 | KeyID getKeyID(ULONG virtualKey, KeyButton button, bool fNumPadKey, USHORT usChar);
|
---|
116 |
|
---|
117 | //@}
|
---|
118 |
|
---|
119 | // IKeyState overrides
|
---|
120 | virtual void fakeKeyDown(KeyID id, KeyModifierMask mask,
|
---|
121 | KeyButton button);
|
---|
122 | virtual void fakeKeyRepeat(KeyID id, KeyModifierMask mask,
|
---|
123 | SInt32 count, KeyButton button);
|
---|
124 | virtual bool fakeCtrlAltDel();
|
---|
125 | virtual KeyModifierMask
|
---|
126 | pollActiveModifiers() const;
|
---|
127 | virtual SInt32 pollActiveGroup() const;
|
---|
128 | virtual void pollPressedKeys(KeyButtonSet& pressedKeys) const;
|
---|
129 |
|
---|
130 | // CKeyState overrides
|
---|
131 | virtual void sendKeyEvent(void* target,
|
---|
132 | bool press, bool isAutoRepeat,
|
---|
133 | KeyID key, KeyModifierMask mask,
|
---|
134 | SInt32 count, KeyButton button);
|
---|
135 |
|
---|
136 | protected:
|
---|
137 | // CKeyState overrides
|
---|
138 | virtual void getKeyMap(CKeyMap& keyMap);
|
---|
139 | virtual void fakeKey(const Keystroke& keystroke);
|
---|
140 | virtual KeyModifierMask&
|
---|
141 | getActiveModifiersRValue();
|
---|
142 |
|
---|
143 | private:
|
---|
144 | typedef union {
|
---|
145 | /** the 64-bit data view. */
|
---|
146 | UInt64 u;
|
---|
147 | /** the struct view. */
|
---|
148 | struct
|
---|
149 | {
|
---|
150 | /** The pm scan code. */
|
---|
151 | unsigned xlatScan : 8;
|
---|
152 | /** The char. */
|
---|
153 | unsigned xlatChar: 8;
|
---|
154 | /** The raw scan code. */
|
---|
155 | unsigned scan : 7;
|
---|
156 | /** KDD_EXTENDEDKEY. */
|
---|
157 | unsigned fExtendedKey : 1;
|
---|
158 | /** The pm scan code of the 2nd message. */
|
---|
159 | unsigned xlatScan2 : 8;
|
---|
160 | /** The char of the 2nd message. */
|
---|
161 | unsigned xlatChar2: 8;
|
---|
162 | /** The raw scan code of the 2nd message. */
|
---|
163 | unsigned scan2 : 7;
|
---|
164 | /** KDD_SECONDARY. */
|
---|
165 | unsigned fSecondary : 1;
|
---|
166 | /** The virtual key. */
|
---|
167 | unsigned virtualKey : 7;
|
---|
168 | /** KC_DEADKEY. */
|
---|
169 | unsigned fDeadKey : 1;
|
---|
170 | /** KC_COMPOSITE. */
|
---|
171 | unsigned fComposite : 1;
|
---|
172 | /** shift key. */
|
---|
173 | unsigned fShiftKey : 1;
|
---|
174 | /** Indicates that the key requires the xlscan=2a KDD_SECONADARY+KDD_UNDEFINED+KDD_UNDEFINED
|
---|
175 | * key if numlock is effective. */
|
---|
176 | unsigned fNeedNumUnlockKey : 1;
|
---|
177 | /** Bits we haven't used yet. */
|
---|
178 | unsigned fReserved : 4;
|
---|
179 | } s;
|
---|
180 | } ClientData;
|
---|
181 |
|
---|
182 | void convertScancodes(ClientData *pData);
|
---|
183 | KeyID getIDForKey(CKeyMap::KeyItem& item,
|
---|
184 | KeyButton button, ULONG virtualKey,
|
---|
185 | PBYTE keyState) const;
|
---|
186 |
|
---|
187 | void addKeyEntry(CKeyMap& keyMap, CKeyMap::KeyItem& item);
|
---|
188 |
|
---|
189 | private:
|
---|
190 | // not implemented
|
---|
191 | CPMKeyState(const CPMKeyState&);
|
---|
192 | CPMKeyState& operator=(const CPMKeyState&);
|
---|
193 |
|
---|
194 | private:
|
---|
195 | typedef std::map<KeyID, UInt32> KeyToVKMap;
|
---|
196 | void* m_eventTarget;
|
---|
197 | ULONG m_buttonToVK[512];
|
---|
198 | KeyButton m_virtualKeyToButton[256];
|
---|
199 | KeyToVKMap m_keyToVKMap;
|
---|
200 |
|
---|
201 | // scan code conversions.
|
---|
202 | UInt8 m_pmScanToOemScan[256];
|
---|
203 | UInt8 m_pmScanToOemScanExt[256];
|
---|
204 | UInt8 m_oemScanToPmScan[128];
|
---|
205 | UInt8 m_oemScanToPmScanExt[128];
|
---|
206 |
|
---|
207 | // function which can inject fake WM_CHAR messages.
|
---|
208 | FakeMsgFunc m_fakeMsg;
|
---|
209 |
|
---|
210 | // the last button pressed.
|
---|
211 | KeyButton m_lastButton;
|
---|
212 |
|
---|
213 | // the timer used to check for fixing key state
|
---|
214 | CEventQueueTimer* m_fixTimer;
|
---|
215 |
|
---|
216 | // the last button that we generated a key down event for. this
|
---|
217 | // is zero if the last key event was a key up. we use this to
|
---|
218 | // synthesize key repeats since the low level keyboard hook can't
|
---|
219 | // tell us if an event is a key repeat.
|
---|
220 | KeyButton m_lastDown;
|
---|
221 |
|
---|
222 | // modifier tracking
|
---|
223 | bool m_useSavedModifiers;
|
---|
224 | KeyModifierMask m_savedModifiers;
|
---|
225 | KeyModifierMask m_originalSavedModifiers;
|
---|
226 |
|
---|
227 | typedef struct {
|
---|
228 | KeyID key;
|
---|
229 | unsigned char ch;
|
---|
230 | bool numpad;
|
---|
231 | char extended;
|
---|
232 | } VirtualKey;
|
---|
233 | static const VirtualKey s_virtualKey[0x42];
|
---|
234 | };
|
---|
235 |
|
---|
236 | /*
|
---|
237 | * Local Variables:
|
---|
238 | * mode: c
|
---|
239 | * c-file-style: "k&r"
|
---|
240 | * c-basic-offset: 4
|
---|
241 | * tab-width: 4
|
---|
242 | * indent-tabs-mode: t
|
---|
243 | * End:
|
---|
244 | */
|
---|
245 |
|
---|
246 |
|
---|
247 | #endif
|
---|