source: trunk/synergy/lib/platform/CPMKeyState.h

Last change on this file was 2768, checked in by bird, 19 years ago

Expanded m_client to 64-bit. Finally managed to hack together a getKeyMap and fakeKey for PM.

File size: 6.7 KB
Line 
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
28class CEvent;
29class CEventQueueTimer;
30
31//! Microsoft Windows key mapper
32/*!
33This class maps KeyIDs to keystrokes.
34*/
35class CPMKeyState : public CKeyState {
36public:
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
136protected:
137 // CKeyState overrides
138 virtual void getKeyMap(CKeyMap& keyMap);
139 virtual void fakeKey(const Keystroke& keystroke);
140 virtual KeyModifierMask&
141 getActiveModifiersRValue();
142
143private:
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
189private:
190 // not implemented
191 CPMKeyState(const CPMKeyState&);
192 CPMKeyState& operator=(const CPMKeyState&);
193
194private:
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
Note: See TracBrowser for help on using the repository browser.