source: trunk/src/gui/embedded/qkbdqnx_qws.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 8.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qkbdqnx_qws.h"
43#include "QtCore/qsocketnotifier.h"
44#include "QtCore/qdebug.h"
45
46#include <sys/dcmd_input.h>
47#include <photon/keycodes.h>
48
49#include "qplatformdefs.h"
50#include <errno.h>
51
52
53QT_BEGIN_NAMESPACE
54
55/*!
56 \class QWSQnxKeyboardHandler
57 \preliminary
58 \ingroup qws
59 \since 4.6
60 \internal
61
62 \brief The QWSQnxKeyboardHandler class implements a keyboard driver
63 for the QNX \c{devi-hid} input manager.
64
65 To be able to compile this mouse handler, \l{Qt for Embedded Linux}
66 must be configured with the \c -qt-kbd-qnx option, see the
67 \l{Qt for Embedded Linux Character Input} documentation for details.
68
69 In order to use this keyboard handler, the \c{devi-hid} input manager
70 must be set up and run with the resource manager interface (option \c{-r}).
71 Also, Photon must not be running.
72
73 Example invocation from command line: \c{/usr/photon/bin/devi-hid -Pr kbd mouse}
74 Note that after running \c{devi-hid}, you will not be able to use the local
75 shell anymore. It is suggested to run the command in a shell scrip, that launches
76 a Qt application after invocation of \c{devi-hid}.
77
78 To make \l{Qt for Embedded Linux} explicitly choose the qnx keyboard
79 handler, set the QWS_KEYBOARD environment variable to \c{qnx}. By default,
80 the first keyboard device (\c{/dev/devi/keyboard0}) is used. To override, pass a device
81 name as the first and only parameter, for example
82 \c{QWS_KEYBOARD=qnx:/dev/devi/keyboard1; export QWS_KEYBOARD}.
83
84 \sa {Qt for Embedded Linux Character Input}, {Qt for Embedded Linux}
85*/
86
87/*!
88 Constructs a keyboard handler for the specified \a device, defaulting to
89 \c{/dev/devi/keyboard0}.
90
91 Note that you should never instanciate this class, instead let QKbdDriverFactory
92 handle the keyboard handlers.
93
94 \sa QKbdDriverFactory
95 */
96QWSQnxKeyboardHandler::QWSQnxKeyboardHandler(const QString &device)
97{
98 // open the keyboard device
99 keyboardFD = QT_OPEN(device.isEmpty() ? "/dev/devi/keyboard0" : device.toLatin1().constData(),
100 QT_OPEN_RDONLY);
101 if (keyboardFD == -1) {
102 qErrnoWarning(errno, "QWSQnxKeyboardHandler: Unable to open device");
103 return;
104 }
105
106 // create a socket notifier so we'll wake up whenever keyboard input is detected.
107 QSocketNotifier *notifier = new QSocketNotifier(keyboardFD, QSocketNotifier::Read, this);
108 connect(notifier, SIGNAL(activated(int)), SLOT(socketActivated()));
109
110 qDebug() << "QWSQnxKeyboardHandler: connected.";
111
112}
113
114/*!
115 Destroys this keyboard handler and closes the connection to the keyboard device.
116 */
117QWSQnxKeyboardHandler::~QWSQnxKeyboardHandler()
118{
119 QT_CLOSE(keyboardFD);
120}
121
122/*! \internal
123 Translates the QNX keyboard events to Qt keyboard events
124 */
125void QWSQnxKeyboardHandler::socketActivated()
126{
127 _keyboard_packet packet;
128
129 // read one keyboard event
130 int bytesRead = QT_READ(keyboardFD, &packet, sizeof(_keyboard_packet));
131 if (bytesRead == -1) {
132 qErrnoWarning(errno, "QWSQnxKeyboardHandler::socketActivated(): Unable to read data.");
133 return;
134 }
135
136 // the bytes read must be the size of a keyboard packet
137 Q_ASSERT(bytesRead == sizeof(_keyboard_packet));
138
139#if 0
140 qDebug() << "keyboard got scancode"
141 << hex << packet.data.modifiers
142 << packet.data.flags
143 << packet.data.key_cap
144 << packet.data.key_sym
145 << packet.data.key_scan;
146#endif
147
148 // QNX is nice enough to translate the raw keyboard data into a QNX data structure
149 // Now we just have to translate it into a format Qt understands.
150
151 // figure out whether it's a press
152 bool isPress = packet.data.key_cap & KEY_DOWN;
153 // figure out whether the key is still pressed and the key event is repeated
154 bool isRepeat = packet.data.key_cap & KEY_REPEAT;
155
156 Qt::Key key = Qt::Key_unknown;
157 int unicode = 0xffff;
158
159 // TODO - this switch is not complete!
160 switch (packet.data.key_scan) {
161 case KEYCODE_SPACE: key = Qt::Key_Space; unicode = 0x20; break;
162 case KEYCODE_F1: key = Qt::Key_F1; break;
163 case KEYCODE_F2: key = Qt::Key_F2; break;
164 case KEYCODE_F3: key = Qt::Key_F3; break;
165 case KEYCODE_F4: key = Qt::Key_F4; break;
166 case KEYCODE_F5: key = Qt::Key_F5; break;
167 case KEYCODE_F6: key = Qt::Key_F6; break;
168 case KEYCODE_F7: key = Qt::Key_F7; break;
169 case KEYCODE_F8: key = Qt::Key_F8; break;
170 case KEYCODE_F9: key = Qt::Key_F9; break;
171 case KEYCODE_F10: key = Qt::Key_F10; break;
172 case KEYCODE_F11: key = Qt::Key_F11; break;
173 case KEYCODE_F12: key = Qt::Key_F12; break;
174 case KEYCODE_BACKSPACE: key = Qt::Key_Backspace; break;
175 case KEYCODE_TAB: key = Qt::Key_Tab; break;
176 case KEYCODE_RETURN: key = Qt::Key_Return; break;
177 case KEYCODE_KP_ENTER: key = Qt::Key_Enter; break;
178 case KEYCODE_UP:
179 case KEYCODE_KP_UP:
180 key = Qt::Key_Up; break;
181 case KEYCODE_DOWN:
182 case KEYCODE_KP_DOWN:
183 key = Qt::Key_Down; break;
184 case KEYCODE_LEFT:
185 case KEYCODE_KP_LEFT:
186 key = Qt::Key_Left; break;
187 case KEYCODE_RIGHT:
188 case KEYCODE_KP_RIGHT:
189 key = Qt::Key_Right; break;
190 case KEYCODE_HOME:
191 case KEYCODE_KP_HOME:
192 key = Qt::Key_Home; break;
193 case KEYCODE_END:
194 case KEYCODE_KP_END:
195 key = Qt::Key_End; break;
196 case KEYCODE_PG_UP:
197 case KEYCODE_KP_PG_UP:
198 key = Qt::Key_PageUp; break;
199 case KEYCODE_PG_DOWN:
200 case KEYCODE_KP_PG_DOWN:
201 key = Qt::Key_PageDown; break;
202 case KEYCODE_INSERT:
203 case KEYCODE_KP_INSERT:
204 key = Qt::Key_Insert; break;
205 case KEYCODE_DELETE:
206 case KEYCODE_KP_DELETE:
207 key = Qt::Key_Delete; break;
208 case KEYCODE_ESCAPE:
209 key = Qt::Key_Escape; break;
210 default: // none of the above, try the key_scan directly
211 unicode = packet.data.key_scan;
212 break;
213 }
214
215 // figure out the modifiers that are currently pressed
216 Qt::KeyboardModifiers modifiers = Qt::NoModifier;
217 if (packet.data.flags & KEYMOD_SHIFT)
218 modifiers |= Qt::ShiftModifier;
219 if (packet.data.flags & KEYMOD_CTRL)
220 modifiers |= Qt::ControlModifier;
221 if (packet.data.flags & KEYMOD_ALT)
222 modifiers |= Qt::AltModifier;
223
224 // if the unicode value is not ascii, we ignore it.
225 // TODO - do a complete mapping between all QNX scan codes and Qt codes
226 if (unicode != 0xffff && !isascii(unicode))
227 return; // unprintable character
228
229 // call processKeyEvent. This is where all the magic happens to insert a
230 // key event into Qt's event loop.
231 // Note that for repeated key events, isPress must be true
232 // (on QNX, isPress is not set when the key event is repeated).
233 processKeyEvent(unicode, key, modifiers, isPress || isRepeat, isRepeat);
234}
235
236QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.