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