1 /****************************************************************************
2 **
3 ** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the plugins 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 QBSDKEYBOARD_H
41 #define QBSDKEYBOARD_H
42 
43 #include <qobject.h>
44 #include <QDataStream>
45 #include <QVector>
46 
47 QT_BEGIN_NAMESPACE
48 
49 class QSocketNotifier;
50 
51 struct termios;
52 
53 enum {
54     Bsd_NoKeyMode       = -1
55 };
56 
57 namespace QBsdKeyboardMap {
58     const quint32 FileMagic = 0x514d4150; // 'QMAP'
59 
60     struct Mapping {
61         quint16 keycode;
62         quint16 unicode;
63         quint32 qtcode;
64         quint8 modifiers;
65         quint8 flags;
66         quint16 special;
67 
68     };
69 
70     enum Flags {
71         NoFlags    = 0x00,
72         IsLetter   = 0x01,
73         IsModifier = 0x02
74     };
75 
76     enum Modifiers {
77         ModPlain   = 0x00,
78         ModShift   = 0x01,
79         ModAltGr   = 0x02,
80         ModControl = 0x04,
81         ModAlt     = 0x08,
82         ModShiftL  = 0x10,
83         ModShiftR  = 0x20,
84         ModCtrlL   = 0x40,
85         ModCtrlR   = 0x80
86         // ModCapsShift = 0x100, // not supported!
87     };
88 }
89 
90 inline QDataStream &operator>>(QDataStream &ds, QBsdKeyboardMap::Mapping &m)
91 {
92     return ds >> m.keycode >> m.unicode >> m.qtcode >> m.modifiers >> m.flags >> m.special;
93 }
94 
95 class QBsdKeyboardHandler : public QObject
96 {
97     Q_OBJECT
98 
99 public:
100     QBsdKeyboardHandler(const QString &key, const QString &specification);
101     ~QBsdKeyboardHandler() override;
102 
toQtModifiers(quint8 mod)103     static Qt::KeyboardModifiers toQtModifiers(quint8 mod)
104     {
105         Qt::KeyboardModifiers qtmod = Qt::NoModifier;
106 
107         if (mod & (QBsdKeyboardMap::ModShift | QBsdKeyboardMap::ModShiftL | QBsdKeyboardMap::ModShiftR))
108             qtmod |= Qt::ShiftModifier;
109         if (mod & (QBsdKeyboardMap::ModControl | QBsdKeyboardMap::ModCtrlL | QBsdKeyboardMap::ModCtrlR))
110             qtmod |= Qt::ControlModifier;
111         if (mod & QBsdKeyboardMap::ModAlt)
112             qtmod |= Qt::AltModifier;
113 
114         return qtmod;
115     }
116 
117 protected:
118     void switchLed(int led, bool state);
119     void processKeycode(quint16 keycode, bool pressed, bool autorepeat);
120     void processKeyEvent(int nativecode, int unicode, int qtcode,
121                          Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat);
122     void revertTTYSettings();
123     void resetKeymap();
124     void readKeyboardData();
125 
126 private:
127     QScopedPointer<QSocketNotifier> m_notifier;
128     QScopedPointer<termios> m_kbdOrigTty;
129     int m_origKbdMode = Bsd_NoKeyMode;
130     int m_fd = -1;
131     bool m_shouldClose = false;
132     QString m_spec;
133 
134     // keymap handling
135     quint8 m_modifiers = 0;
136     bool m_capsLock = false;
137     bool m_numLock = false;
138     bool m_scrollLock = false;
139 
140     QVector<QBsdKeyboardMap::Mapping> m_keymap;
141 };
142 
143 QT_END_NAMESPACE
144 
145 #endif // QBSDKEYBOARD_H
146