1 /* 2 * synergy -- mouse and keyboard sharing utility 3 * Copyright (C) 2012-2016 Symless Ltd. 4 * Copyright (C) 2003 Chris Schoeneman 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 LICENSE 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 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #pragma once 20 21 #include "synergy/KeyState.h" 22 #include "common/stdmap.h" 23 #include "common/stdvector.h" 24 25 #if X_DISPLAY_MISSING 26 # error X11 is required to build synergy 27 #else 28 # include <X11/Xlib.h> 29 # if HAVE_X11_EXTENSIONS_XTEST_H 30 # include <X11/extensions/XTest.h> 31 # else 32 # error The XTest extension is required to build synergy 33 # endif 34 # if HAVE_XKB_EXTENSION 35 # include <X11/extensions/XKBstr.h> 36 # endif 37 #endif 38 39 class IEventQueue; 40 41 //! X Windows key state 42 /*! 43 A key state for X Windows. 44 */ 45 class XWindowsKeyState : public KeyState { 46 public: 47 typedef std::vector<int> KeycodeList; 48 enum { 49 kGroupPoll = -1, 50 kGroupPollAndSet = -2 51 }; 52 53 XWindowsKeyState(Display*, bool useXKB, IEventQueue* events); 54 XWindowsKeyState(Display*, bool useXKB, 55 IEventQueue* events, synergy::KeyMap& keyMap); 56 ~XWindowsKeyState(); 57 58 //! @name modifiers 59 //@{ 60 61 //! Set active group 62 /*! 63 Sets the active group to \p group. This is the group returned by 64 \c pollActiveGroup(). If \p group is \c kGroupPoll then 65 \c pollActiveGroup() will really poll, but that's a slow operation 66 on X11. If \p group is \c kGroupPollAndSet then this will poll the 67 active group now and use it for future calls to \c pollActiveGroup(). 68 */ 69 void setActiveGroup(SInt32 group); 70 71 //! Set the auto-repeat state 72 /*! 73 Sets the auto-repeat state. 74 */ 75 void setAutoRepeat(const XKeyboardState&); 76 77 //@} 78 //! @name accessors 79 //@{ 80 81 //! Convert X modifier mask to synergy mask 82 /*! 83 Returns the synergy modifier mask corresponding to the X modifier 84 mask in \p state. 85 */ 86 KeyModifierMask mapModifiersFromX(unsigned int state) const; 87 88 //! Convert synergy modifier mask to X mask 89 /*! 90 Converts the synergy modifier mask to the corresponding X modifier 91 mask. Returns \c true if successful and \c false if any modifier 92 could not be converted. 93 */ 94 bool mapModifiersToX(KeyModifierMask, unsigned int&) const; 95 96 //! Convert synergy key to all corresponding X keycodes 97 /*! 98 Converts the synergy key \p key to all of the keycodes that map to 99 that key. 100 */ 101 void mapKeyToKeycodes(KeyID key, 102 KeycodeList& keycodes) const; 103 104 //@} 105 106 // IKeyState overrides 107 virtual bool fakeCtrlAltDel(); 108 virtual KeyModifierMask 109 pollActiveModifiers() const; 110 virtual SInt32 pollActiveGroup() const; 111 virtual void pollPressedKeys(KeyButtonSet& pressedKeys) const; 112 113 protected: 114 // KeyState overrides 115 virtual void getKeyMap(synergy::KeyMap& keyMap); 116 virtual void fakeKey(const Keystroke& keystroke); 117 118 private: 119 void init(Display* display, bool useXKB); 120 void updateKeysymMap(synergy::KeyMap&); 121 void updateKeysymMapXKB(synergy::KeyMap&); 122 bool hasModifiersXKB() const; 123 int getEffectiveGroup(KeyCode, int group) const; 124 UInt32 getGroupFromState(unsigned int state) const; 125 126 static void remapKeyModifiers(KeyID, SInt32, 127 synergy::KeyMap::KeyItem&, void*); 128 129 private: 130 struct XKBModifierInfo { 131 public: 132 unsigned char m_level; 133 UInt32 m_mask; 134 bool m_lock; 135 }; 136 137 #ifdef TEST_ENV 138 public: // yuck 139 #endif 140 typedef std::vector<KeyModifierMask> KeyModifierMaskList; 141 142 private: 143 typedef std::map<KeyModifierMask, unsigned int> KeyModifierToXMask; 144 typedef std::multimap<KeyID, KeyCode> KeyToKeyCodeMap; 145 typedef std::map<KeyCode, unsigned int> NonXKBModifierMap; 146 typedef std::map<UInt32, XKBModifierInfo> XKBModifierMap; 147 148 Display* m_display; 149 #if HAVE_XKB_EXTENSION 150 XkbDescPtr m_xkb; 151 #endif 152 SInt32 m_group; 153 XKBModifierMap m_lastGoodXKBModifiers; 154 NonXKBModifierMap m_lastGoodNonXKBModifiers; 155 156 // X modifier (bit number) to synergy modifier (mask) mapping 157 KeyModifierMaskList m_modifierFromX; 158 159 // synergy modifier (mask) to X modifier (mask) 160 KeyModifierToXMask m_modifierToX; 161 162 // map KeyID to all keycodes that can synthesize that KeyID 163 KeyToKeyCodeMap m_keyCodeFromKey; 164 165 // autorepeat state 166 XKeyboardState m_keyboardState; 167 168 #ifdef TEST_ENV 169 public: group()170 SInt32 group() const { return m_group; } group(const SInt32 & group)171 void group(const SInt32& group) { m_group = group; } modifierFromX()172 KeyModifierMaskList modifierFromX() const { return m_modifierFromX; } 173 #endif 174 }; 175