Qt 4.8
qdirectfbkeyboard.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qdirectfbkeyboard.h"
43 
44 #ifndef QT_NO_QWS_DIRECTFB
45 
46 #include "qdirectfbscreen.h"
47 #include <qobject.h>
48 #include <qsocketnotifier.h>
49 #include <qhash.h>
50 
51 #include <directfb.h>
52 #include <unistd.h>
53 #include <fcntl.h>
54 #include <errno.h>
55 
57 
58 class KeyMap : public QHash<DFBInputDeviceKeySymbol, Qt::Key>
59 {
60 public:
61  KeyMap();
62 };
63 
64 Q_GLOBAL_STATIC(KeyMap, keymap);
65 
67 {
68  Q_OBJECT
69 public:
72 
73  void suspend();
74  void resume();
75 
76 private:
78  IDirectFBEventBuffer *eventBuffer;
80  DFBEvent event;
81  int bytesRead;
82  int lastUnicode, lastKeycode;
83  Qt::KeyboardModifiers lastModifiers;
84 private Q_SLOTS:
85  void readKeyboardData();
86 };
87 
89  : handler(h), eventBuffer(0), keyboardNotifier(0), bytesRead(0),
90  lastUnicode(0), lastKeycode(0), lastModifiers(0)
91 {
93 
94  IDirectFB *fb = QDirectFBScreen::instance()->dfb();
95  if (!fb) {
96  qCritical("QDirectFBKeyboardHandler: DirectFB not initialized");
97  return;
98  }
99 
100  DFBResult result;
101  result = fb->CreateInputEventBuffer(fb, DICAPS_KEYS, DFB_TRUE,
102  &eventBuffer);
103  if (result != DFB_OK) {
104  DirectFBError("QDirectFBKeyboardHandler: "
105  "Unable to create input event buffer", result);
106  return;
107  }
108 
109  int fd;
110  result = eventBuffer->CreateFileDescriptor(eventBuffer, &fd);
111  if (result != DFB_OK) {
112  DirectFBError("QDirectFBKeyboardHandler: "
113  "Unable to create file descriptor", result);
114  return;
115  }
116 
117  int flags = ::fcntl(fd, F_GETFL, 0);
118  ::fcntl(fd, F_SETFL, flags | O_NONBLOCK);
119 
120  memset(&event, 0, sizeof(event));
121 
123  connect(keyboardNotifier, SIGNAL(activated(int)),
124  this, SLOT(readKeyboardData()));
125  resume();
126 }
127 
129 {
131 }
132 
134 {
135  eventBuffer->Reset(eventBuffer);
137 }
138 
140 {
141  if (eventBuffer)
142  eventBuffer->Release(eventBuffer);
143 }
144 
146 {
147  if(!qt_screen)
148  return;
149 
150  for (;;) {
151  // GetEvent returns DFB_UNSUPPORTED after CreateFileDescriptor().
152  // This seems stupid and I really hope it's a bug which will be fixed.
153 
154  // DFBResult ret = eventBuffer->GetEvent(eventBuffer, &event);
155 
156  char *buf = reinterpret_cast<char*>(&event);
157  int ret = ::read(keyboardNotifier->socket(),
158  buf + bytesRead, sizeof(DFBEvent) - bytesRead);
159  if (ret == -1) {
160  if (errno != EAGAIN)
161  qWarning("QDirectFBKeyboardHandlerPrivate::readKeyboardData(): %s",
162  strerror(errno));
163  return;
164  }
165 
166  Q_ASSERT(ret >= 0);
167  bytesRead += ret;
168  if (bytesRead < int(sizeof(DFBEvent)))
169  break;
170  bytesRead = 0;
171 
172  Q_ASSERT(event.clazz == DFEC_INPUT);
173 
174  const DFBInputEvent input = event.input;
175 
176  Qt::KeyboardModifiers modifiers = Qt::NoModifier;
177 
178  // Not implemented:
179  // if (input.modifiers & DIMM_SUPER)
180  // if (input.modifiers & DIMM_HYPER)
181 
182  if (!(input.flags & DIEF_KEYSYMBOL) ||
183  !(input.flags & DIEF_KEYID) ||
184  !(input.type & (DIET_KEYPRESS|DIET_KEYRELEASE)))
185  {
186  static bool first = true;
187  if (first) {
188  qWarning("QDirectFBKeyboardHandler - Getting unexpected non-keyboard related events");
189  first = false;
190  }
191  break;
192  }
193 
194  if (input.flags & DIEF_MODIFIERS) {
195  if (input.modifiers & DIMM_SHIFT)
196  modifiers |= Qt::ShiftModifier;
197  if (input.modifiers & DIMM_CONTROL)
198  modifiers |= Qt::ControlModifier;
199  if (input.modifiers & DIMM_ALT)
200  modifiers |= Qt::AltModifier;
201  if (input.modifiers & DIMM_ALTGR)
202  modifiers |= Qt::AltModifier;
203  if (input.modifiers & DIMM_META)
204  modifiers |= Qt::MetaModifier;
205  }
206 
207 
208  const bool press = input.type & DIET_KEYPRESS;
209  DFBInputDeviceKeySymbol symbol = input.key_symbol;
210  int unicode = -1;
211  int keycode = 0;
212 
213  keycode = keymap()->value(symbol);
214  if (DFB_KEY_TYPE(symbol) == DIKT_UNICODE)
215  unicode = symbol;
216 
217  if (unicode != -1 || keycode != 0) {
218  bool autoRepeat = false;
219  if (press) {
220  if (unicode == lastUnicode && keycode == lastKeycode && modifiers == lastModifiers) {
221  autoRepeat = true;
222  } else {
223  lastUnicode = unicode;
225  lastModifiers = modifiers;
226  }
227  } else {
228  lastUnicode = lastKeycode = -1;
229  lastModifiers = 0;
230  }
231  if (autoRepeat) {
232  handler->processKeyEvent(unicode, keycode,
233  modifiers, false, autoRepeat);
234 
235  }
236 
237  handler->processKeyEvent(unicode, keycode,
238  modifiers, press, autoRepeat);
239  }
240  }
241 }
242 
245 {
246  Q_UNUSED(device);
248 }
249 
251 {
252  delete d;
253 }
254 
256 {
257  insert(DIKS_BACKSPACE , Qt::Key_Backspace);
258  insert(DIKS_TAB , Qt::Key_Tab);
259  insert(DIKS_RETURN , Qt::Key_Return);
260  insert(DIKS_ESCAPE , Qt::Key_Escape);
261  insert(DIKS_DELETE , Qt::Key_Delete);
262 
263  insert(DIKS_CURSOR_LEFT , Qt::Key_Left);
264  insert(DIKS_CURSOR_RIGHT , Qt::Key_Right);
265  insert(DIKS_CURSOR_UP , Qt::Key_Up);
266  insert(DIKS_CURSOR_DOWN , Qt::Key_Down);
267  insert(DIKS_INSERT , Qt::Key_Insert);
268  insert(DIKS_HOME , Qt::Key_Home);
269  insert(DIKS_END , Qt::Key_End);
270  insert(DIKS_PAGE_UP , Qt::Key_PageUp);
271  insert(DIKS_PAGE_DOWN , Qt::Key_PageDown);
272  insert(DIKS_PRINT , Qt::Key_Print);
273  insert(DIKS_PAUSE , Qt::Key_Pause);
274  insert(DIKS_SELECT , Qt::Key_Select);
275  insert(DIKS_GOTO , Qt::Key_OpenUrl);
276  insert(DIKS_CLEAR , Qt::Key_Clear);
277  insert(DIKS_MENU , Qt::Key_Menu);
278  insert(DIKS_HELP , Qt::Key_Help);
279 
280  insert(DIKS_INTERNET , Qt::Key_HomePage);
281  insert(DIKS_MAIL , Qt::Key_LaunchMail);
282  insert(DIKS_FAVORITES , Qt::Key_Favorites);
283 
284  insert(DIKS_BACK , Qt::Key_Back);
285  insert(DIKS_FORWARD , Qt::Key_Forward);
286  insert(DIKS_VOLUME_UP , Qt::Key_VolumeUp);
287  insert(DIKS_VOLUME_DOWN , Qt::Key_VolumeDown);
288  insert(DIKS_MUTE , Qt::Key_VolumeMute);
289  insert(DIKS_PLAYPAUSE , Qt::Key_Pause);
290  insert(DIKS_PLAY , Qt::Key_MediaPlay);
291  insert(DIKS_STOP , Qt::Key_MediaStop);
292  insert(DIKS_RECORD , Qt::Key_MediaRecord);
293  insert(DIKS_PREVIOUS , Qt::Key_MediaPrevious);
294  insert(DIKS_NEXT , Qt::Key_MediaNext);
295 
296  insert(DIKS_F1 , Qt::Key_F1);
297  insert(DIKS_F2 , Qt::Key_F2);
298  insert(DIKS_F3 , Qt::Key_F3);
299  insert(DIKS_F4 , Qt::Key_F4);
300  insert(DIKS_F5 , Qt::Key_F5);
301  insert(DIKS_F6 , Qt::Key_F6);
302  insert(DIKS_F7 , Qt::Key_F7);
303  insert(DIKS_F8 , Qt::Key_F8);
304  insert(DIKS_F9 , Qt::Key_F9);
305  insert(DIKS_F10 , Qt::Key_F10);
306  insert(DIKS_F11 , Qt::Key_F11);
307  insert(DIKS_F12 , Qt::Key_F12);
308 
309  insert(DIKS_SHIFT , Qt::Key_Shift);
310  insert(DIKS_CONTROL , Qt::Key_Control);
311  insert(DIKS_ALT , Qt::Key_Alt);
312  insert(DIKS_ALTGR , Qt::Key_AltGr);
313 
314  insert(DIKS_META , Qt::Key_Meta);
315  insert(DIKS_SUPER , Qt::Key_Super_L); // ???
316  insert(DIKS_HYPER , Qt::Key_Hyper_L); // ???
317 
318  insert(DIKS_CAPS_LOCK , Qt::Key_CapsLock);
319  insert(DIKS_NUM_LOCK , Qt::Key_NumLock);
320  insert(DIKS_SCROLL_LOCK , Qt::Key_ScrollLock);
321 
322  insert(DIKS_DEAD_ABOVEDOT , Qt::Key_Dead_Abovedot);
323  insert(DIKS_DEAD_ABOVERING , Qt::Key_Dead_Abovering);
324  insert(DIKS_DEAD_ACUTE , Qt::Key_Dead_Acute);
325  insert(DIKS_DEAD_BREVE , Qt::Key_Dead_Breve);
326  insert(DIKS_DEAD_CARON , Qt::Key_Dead_Caron);
327  insert(DIKS_DEAD_CEDILLA , Qt::Key_Dead_Cedilla);
328  insert(DIKS_DEAD_CIRCUMFLEX , Qt::Key_Dead_Circumflex);
329  insert(DIKS_DEAD_DIAERESIS , Qt::Key_Dead_Diaeresis);
330  insert(DIKS_DEAD_DOUBLEACUTE , Qt::Key_Dead_Doubleacute);
331  insert(DIKS_DEAD_GRAVE , Qt::Key_Dead_Grave);
332  insert(DIKS_DEAD_IOTA , Qt::Key_Dead_Iota);
333  insert(DIKS_DEAD_MACRON , Qt::Key_Dead_Macron);
334  insert(DIKS_DEAD_OGONEK , Qt::Key_Dead_Ogonek);
335  insert(DIKS_DEAD_SEMIVOICED_SOUND , Qt::Key_Dead_Semivoiced_Sound);
336  insert(DIKS_DEAD_TILDE , Qt::Key_Dead_Tilde);
337  insert(DIKS_DEAD_VOICED_SOUND , Qt::Key_Dead_Voiced_Sound);
338  insert(DIKS_SPACE , Qt::Key_Space);
339  insert(DIKS_EXCLAMATION_MARK , Qt::Key_Exclam);
340  insert(DIKS_QUOTATION , Qt::Key_QuoteDbl);
341  insert(DIKS_NUMBER_SIGN , Qt::Key_NumberSign);
342  insert(DIKS_DOLLAR_SIGN , Qt::Key_Dollar);
343  insert(DIKS_PERCENT_SIGN , Qt::Key_Percent);
344  insert(DIKS_AMPERSAND , Qt::Key_Ampersand);
345  insert(DIKS_APOSTROPHE , Qt::Key_Apostrophe);
346  insert(DIKS_PARENTHESIS_LEFT , Qt::Key_ParenLeft);
347  insert(DIKS_PARENTHESIS_RIGHT , Qt::Key_ParenRight);
348  insert(DIKS_ASTERISK , Qt::Key_Asterisk);
349  insert(DIKS_PLUS_SIGN , Qt::Key_Plus);
350  insert(DIKS_COMMA , Qt::Key_Comma);
351  insert(DIKS_MINUS_SIGN , Qt::Key_Minus);
352  insert(DIKS_PERIOD , Qt::Key_Period);
353  insert(DIKS_SLASH , Qt::Key_Slash);
354  insert(DIKS_0 , Qt::Key_0);
355  insert(DIKS_1 , Qt::Key_1);
356  insert(DIKS_2 , Qt::Key_2);
357  insert(DIKS_3 , Qt::Key_3);
358  insert(DIKS_4 , Qt::Key_4);
359  insert(DIKS_5 , Qt::Key_5);
360  insert(DIKS_6 , Qt::Key_6);
361  insert(DIKS_7 , Qt::Key_7);
362  insert(DIKS_8 , Qt::Key_8);
363  insert(DIKS_9 , Qt::Key_9);
364  insert(DIKS_COLON , Qt::Key_Colon);
365  insert(DIKS_SEMICOLON , Qt::Key_Semicolon);
366  insert(DIKS_LESS_THAN_SIGN , Qt::Key_Less);
367  insert(DIKS_EQUALS_SIGN , Qt::Key_Equal);
368  insert(DIKS_GREATER_THAN_SIGN , Qt::Key_Greater);
369  insert(DIKS_QUESTION_MARK , Qt::Key_Question);
370  insert(DIKS_AT , Qt::Key_At);
371  insert(DIKS_CAPITAL_A , Qt::Key_A);
372  insert(DIKS_CAPITAL_B , Qt::Key_B);
373  insert(DIKS_CAPITAL_C , Qt::Key_C);
374  insert(DIKS_CAPITAL_D , Qt::Key_D);
375  insert(DIKS_CAPITAL_E , Qt::Key_E);
376  insert(DIKS_CAPITAL_F , Qt::Key_F);
377  insert(DIKS_CAPITAL_G , Qt::Key_G);
378  insert(DIKS_CAPITAL_H , Qt::Key_H);
379  insert(DIKS_CAPITAL_I , Qt::Key_I);
380  insert(DIKS_CAPITAL_J , Qt::Key_J);
381  insert(DIKS_CAPITAL_K , Qt::Key_K);
382  insert(DIKS_CAPITAL_L , Qt::Key_L);
383  insert(DIKS_CAPITAL_M , Qt::Key_M);
384  insert(DIKS_CAPITAL_N , Qt::Key_N);
385  insert(DIKS_CAPITAL_O , Qt::Key_O);
386  insert(DIKS_CAPITAL_P , Qt::Key_P);
387  insert(DIKS_CAPITAL_Q , Qt::Key_Q);
388  insert(DIKS_CAPITAL_R , Qt::Key_R);
389  insert(DIKS_CAPITAL_S , Qt::Key_S);
390  insert(DIKS_CAPITAL_T , Qt::Key_T);
391  insert(DIKS_CAPITAL_U , Qt::Key_U);
392  insert(DIKS_CAPITAL_V , Qt::Key_V);
393  insert(DIKS_CAPITAL_W , Qt::Key_W);
394  insert(DIKS_CAPITAL_X , Qt::Key_X);
395  insert(DIKS_CAPITAL_Y , Qt::Key_Y);
396  insert(DIKS_CAPITAL_Z , Qt::Key_Z);
397  insert(DIKS_SQUARE_BRACKET_LEFT , Qt::Key_BracketLeft);
398  insert(DIKS_BACKSLASH , Qt::Key_Backslash);
399  insert(DIKS_SQUARE_BRACKET_RIGHT , Qt::Key_BracketRight);
400  insert(DIKS_CIRCUMFLEX_ACCENT , Qt::Key_AsciiCircum);
401  insert(DIKS_UNDERSCORE , Qt::Key_Underscore);
402  insert(DIKS_SMALL_A , Qt::Key_A);
403  insert(DIKS_SMALL_B , Qt::Key_B);
404  insert(DIKS_SMALL_C , Qt::Key_C);
405  insert(DIKS_SMALL_D , Qt::Key_D);
406  insert(DIKS_SMALL_E , Qt::Key_E);
407  insert(DIKS_SMALL_F , Qt::Key_F);
408  insert(DIKS_SMALL_G , Qt::Key_G);
409  insert(DIKS_SMALL_H , Qt::Key_H);
410  insert(DIKS_SMALL_I , Qt::Key_I);
411  insert(DIKS_SMALL_J , Qt::Key_J);
412  insert(DIKS_SMALL_K , Qt::Key_K);
413  insert(DIKS_SMALL_L , Qt::Key_L);
414  insert(DIKS_SMALL_M , Qt::Key_M);
415  insert(DIKS_SMALL_N , Qt::Key_N);
416  insert(DIKS_SMALL_O , Qt::Key_O);
417  insert(DIKS_SMALL_P , Qt::Key_P);
418  insert(DIKS_SMALL_Q , Qt::Key_Q);
419  insert(DIKS_SMALL_R , Qt::Key_R);
420  insert(DIKS_SMALL_S , Qt::Key_S);
421  insert(DIKS_SMALL_T , Qt::Key_T);
422  insert(DIKS_SMALL_U , Qt::Key_U);
423  insert(DIKS_SMALL_V , Qt::Key_V);
424  insert(DIKS_SMALL_W , Qt::Key_W);
425  insert(DIKS_SMALL_X , Qt::Key_X);
426  insert(DIKS_SMALL_Y , Qt::Key_Y);
427  insert(DIKS_SMALL_Z , Qt::Key_Z);
428  insert(DIKS_CURLY_BRACKET_LEFT , Qt::Key_BraceLeft);
429  insert(DIKS_VERTICAL_BAR , Qt::Key_Bar);
430  insert(DIKS_CURLY_BRACKET_RIGHT , Qt::Key_BraceRight);
431  insert(DIKS_TILDE , Qt::Key_AsciiTilde);
432 }
433 
435 #include "qdirectfbkeyboard.moc"
436 #endif // QT_NO_QWS_DIRECTFB
Q_GUI_EXPORT QScreen * qt_screen
Definition: qscreen_qws.cpp:69
The QWSKeyboardHandler class is a base class for keyboard drivers in Qt for Embedded Linux...
Definition: qkbd_qws.h:57
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
int keycode
#define SLOT(a)
Definition: qobjectdefs.h:226
#define Q_SLOTS
Definition: qobjectdefs.h:71
The QString class provides a Unicode character string.
Definition: qstring.h:83
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
The QSocketNotifier class provides support for monitoring activity on a file descriptor.
#define SIGNAL(a)
Definition: qobjectdefs.h:227
QDirectFBKeyboardHandlerPrivate * d
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
Qt::KeyboardModifiers lastModifiers
Q_CORE_EXPORT void qWarning(const char *,...)
IDirectFB * dfb()
QDirectFBKeyboardHandler * handler
Q_GLOBAL_STATIC(KeyMap, keymap)
QDirectFBKeyboardHandlerPrivate(QDirectFBKeyboardHandler *handler)
#define Q_OBJECT
Definition: qobjectdefs.h:157
int fcntl(int, int,...)
void setEnabled(bool)
If enable is true, the notifier is enabled; otherwise the notifier is disabled.
static QDirectFBScreen * instance()
virtual void processKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat)
Sends a key event to the Qt for Embedded Linux server application.
Definition: qkbd_qws.cpp:363
QImageIOHandler * handler
IDirectFBEventBuffer * eventBuffer
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
Q_CORE_EXPORT void qCritical(const char *,...)
int errno
int socket() const
Returns the socket identifier specified to the constructor.
QDirectFBKeyboardHandler(const QString &device)