| 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 | static KeyID getKeyID(ULONG virtualKey, KeyButton button);
|
|---|
| 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 | KeyID getIDForKey(CKeyMap::KeyItem& item,
|
|---|
| 145 | KeyButton button, ULONG virtualKey,
|
|---|
| 146 | PBYTE keyState) const;
|
|---|
| 147 |
|
|---|
| 148 | void addKeyEntry(CKeyMap& keyMap, CKeyMap::KeyItem& item);
|
|---|
| 149 |
|
|---|
| 150 | private:
|
|---|
| 151 | // not implemented
|
|---|
| 152 | CPMKeyState(const CPMKeyState&);
|
|---|
| 153 | CPMKeyState& operator=(const CPMKeyState&);
|
|---|
| 154 |
|
|---|
| 155 | private:
|
|---|
| 156 | typedef std::map<KeyID, UInt32> KeyToVKMap;
|
|---|
| 157 | void* m_eventTarget;
|
|---|
| 158 | ULONG m_buttonToVK[512];
|
|---|
| 159 | KeyButton m_virtualKeyToButton[256];
|
|---|
| 160 | KeyToVKMap m_keyToVKMap;
|
|---|
| 161 |
|
|---|
| 162 | // function which can inject fake WM_CHAR messages.
|
|---|
| 163 | FakeMsgFunc m_fakeMsg;
|
|---|
| 164 |
|
|---|
| 165 | // the last button pressed.
|
|---|
| 166 | KeyButton m_lastButton;
|
|---|
| 167 |
|
|---|
| 168 | // the timer used to check for fixing key state
|
|---|
| 169 | CEventQueueTimer* m_fixTimer;
|
|---|
| 170 |
|
|---|
| 171 | // the last button that we generated a key down event for. this
|
|---|
| 172 | // is zero if the last key event was a key up. we use this to
|
|---|
| 173 | // synthesize key repeats since the low level keyboard hook can't
|
|---|
| 174 | // tell us if an event is a key repeat.
|
|---|
| 175 | KeyButton m_lastDown;
|
|---|
| 176 |
|
|---|
| 177 | // modifier tracking
|
|---|
| 178 | bool m_useSavedModifiers;
|
|---|
| 179 | KeyModifierMask m_savedModifiers;
|
|---|
| 180 | KeyModifierMask m_originalSavedModifiers;
|
|---|
| 181 |
|
|---|
| 182 | static const KeyID s_virtualKey[0x42];
|
|---|
| 183 | };
|
|---|
| 184 |
|
|---|
| 185 | /*
|
|---|
| 186 | * Local Variables:
|
|---|
| 187 | * mode: c
|
|---|
| 188 | * c-file-style: "k&r"
|
|---|
| 189 | * c-basic-offset: 4
|
|---|
| 190 | * tab-width: 4
|
|---|
| 191 | * indent-tabs-mode: t
|
|---|
| 192 | * End:
|
|---|
| 193 | */
|
|---|
| 194 |
|
|---|
| 195 |
|
|---|
| 196 | #endif
|
|---|