1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2016 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of the QtGui module of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 21 ** packaging of this file. Please review the following information to 22 ** ensure the GNU Lesser General Public License version 3 requirements 23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24 ** 25 ** GNU General Public License Usage 26 ** Alternatively, this file may be used under the terms of the GNU 27 ** General Public License version 2.0 or (at your option) the GNU General 28 ** Public license version 3 or any later version approved by the KDE Free 29 ** Qt Foundation. The licenses are as published by the Free Software 30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31 ** included in the packaging of this file. Please review the following 32 ** information to ensure the GNU General Public License requirements will 33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34 ** https://www.gnu.org/licenses/gpl-3.0.html. 35 ** 36 ** $QT_END_LICENSE$ 37 ** 38 ****************************************************************************/ 39 40 #ifndef QEVDEVKEYBOARDHANDLER_P_H 41 #define QEVDEVKEYBOARDHANDLER_P_H 42 43 // 44 // W A R N I N G 45 // ------------- 46 // 47 // This file is not part of the Qt API. It exists purely as an 48 // implementation detail. This header file may change from version to 49 // version without notice, or even be removed. 50 // 51 // We mean it. 52 // 53 54 #include <qobject.h> 55 #include <QTimer> 56 #include <QDataStream> 57 58 #include <memory> 59 60 QT_BEGIN_NAMESPACE 61 62 class QSocketNotifier; 63 64 namespace QEvdevKeyboardMap { 65 const quint32 FileMagic = 0x514d4150; // 'QMAP' 66 67 struct Mapping { 68 quint16 keycode; 69 quint16 unicode; 70 quint32 qtcode; 71 quint8 modifiers; 72 quint8 flags; 73 quint16 special; 74 75 }; 76 77 enum Flags { 78 IsDead = 0x01, 79 IsLetter = 0x02, 80 IsModifier = 0x04, 81 IsSystem = 0x08 82 }; 83 84 enum System { 85 SystemConsoleFirst = 0x0100, 86 SystemConsoleMask = 0x007f, 87 SystemConsoleLast = 0x017f, 88 SystemConsolePrevious = 0x0180, 89 SystemConsoleNext = 0x0181, 90 SystemReboot = 0x0200, 91 SystemZap = 0x0300 92 }; 93 94 struct Composing { 95 quint16 first; 96 quint16 second; 97 quint16 result; 98 }; 99 100 enum Modifiers { 101 ModPlain = 0x00, 102 ModShift = 0x01, 103 ModAltGr = 0x02, 104 ModControl = 0x04, 105 ModAlt = 0x08, 106 ModShiftL = 0x10, 107 ModShiftR = 0x20, 108 ModCtrlL = 0x40, 109 ModCtrlR = 0x80 110 // ModCapsShift = 0x100, // not supported! 111 }; 112 } 113 114 inline QDataStream &operator>>(QDataStream &ds, QEvdevKeyboardMap::Mapping &m) 115 { 116 return ds >> m.keycode >> m.unicode >> m.qtcode >> m.modifiers >> m.flags >> m.special; 117 } 118 119 inline QDataStream &operator<<(QDataStream &ds, const QEvdevKeyboardMap::Mapping &m) 120 { 121 return ds << m.keycode << m.unicode << m.qtcode << m.modifiers << m.flags << m.special; 122 } 123 124 inline QDataStream &operator>>(QDataStream &ds, QEvdevKeyboardMap::Composing &c) 125 { 126 return ds >> c.first >> c.second >> c.result; 127 } 128 129 inline QDataStream &operator<<(QDataStream &ds, const QEvdevKeyboardMap::Composing &c) 130 { 131 return ds << c.first << c.second << c.result; 132 } 133 134 class QFdContainer 135 { 136 int m_fd; 137 Q_DISABLE_COPY_MOVE(QFdContainer); 138 public: m_fd(fd)139 explicit QFdContainer(int fd = -1) noexcept : m_fd(fd) {} ~QFdContainer()140 ~QFdContainer() { reset(); } 141 get()142 int get() const noexcept { return m_fd; } 143 release()144 int release() noexcept { int result = m_fd; m_fd = -1; return result; } 145 void reset() noexcept; 146 }; 147 148 class QEvdevKeyboardHandler : public QObject 149 { 150 public: 151 QEvdevKeyboardHandler(const QString &device, QFdContainer &fd, bool disableZap, bool enableCompose, const QString &keymapFile); 152 ~QEvdevKeyboardHandler(); 153 154 enum KeycodeAction { 155 None = 0, 156 157 CapsLockOff = 0x01000000, 158 CapsLockOn = 0x01000001, 159 NumLockOff = 0x02000000, 160 NumLockOn = 0x02000001, 161 ScrollLockOff = 0x03000000, 162 ScrollLockOn = 0x03000001, 163 164 Reboot = 0x04000000, 165 166 PreviousConsole = 0x05000000, 167 NextConsole = 0x05000001, 168 SwitchConsoleFirst = 0x06000000, 169 SwitchConsoleLast = 0x0600007f, 170 SwitchConsoleMask = 0x0000007f 171 }; 172 173 static std::unique_ptr<QEvdevKeyboardHandler> create(const QString &device, 174 const QString &specification, 175 const QString &defaultKeymapFile = QString()); 176 toQtModifiers(quint8 mod)177 static Qt::KeyboardModifiers toQtModifiers(quint8 mod) 178 { 179 Qt::KeyboardModifiers qtmod = Qt::NoModifier; 180 181 if (mod & (QEvdevKeyboardMap::ModShift | QEvdevKeyboardMap::ModShiftL | QEvdevKeyboardMap::ModShiftR)) 182 qtmod |= Qt::ShiftModifier; 183 if (mod & (QEvdevKeyboardMap::ModControl | QEvdevKeyboardMap::ModCtrlL | QEvdevKeyboardMap::ModCtrlR)) 184 qtmod |= Qt::ControlModifier; 185 if (mod & QEvdevKeyboardMap::ModAlt) 186 qtmod |= Qt::AltModifier; 187 188 return qtmod; 189 } 190 191 bool loadKeymap(const QString &file); 192 void unloadKeymap(); 193 194 void readKeycode(); 195 KeycodeAction processKeycode(quint16 keycode, bool pressed, bool autorepeat); 196 197 void switchLang(); 198 199 private: 200 void processKeyEvent(int nativecode, int unicode, int qtcode, 201 Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat); 202 void switchLed(int, bool); 203 204 QString m_device; 205 QFdContainer m_fd; 206 QSocketNotifier *m_notify; 207 208 // keymap handling 209 quint8 m_modifiers; 210 quint8 m_locks[3]; 211 int m_composing; 212 quint16 m_dead_unicode; 213 quint8 m_langLock; 214 215 bool m_no_zap; 216 bool m_do_compose; 217 218 const QEvdevKeyboardMap::Mapping *m_keymap; 219 int m_keymap_size; 220 const QEvdevKeyboardMap::Composing *m_keycompose; 221 int m_keycompose_size; 222 223 static const QEvdevKeyboardMap::Mapping s_keymap_default[]; 224 static const QEvdevKeyboardMap::Composing s_keycompose_default[]; 225 }; 226 227 228 QT_END_NAMESPACE 229 230 #endif // QEVDEVKEYBOARDHANDLER_P_H 231