summaryrefslogtreecommitdiffstats
path: root/src/gui/embedded/qkbdsl5000_qws.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/embedded/qkbdsl5000_qws.cpp')
-rw-r--r--src/gui/embedded/qkbdsl5000_qws.cpp356
1 files changed, 356 insertions, 0 deletions
diff --git a/src/gui/embedded/qkbdsl5000_qws.cpp b/src/gui/embedded/qkbdsl5000_qws.cpp
new file mode 100644
index 0000000..bc412b6
--- /dev/null
+++ b/src/gui/embedded/qkbdsl5000_qws.cpp
@@ -0,0 +1,356 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkbdsl5000_qws.h"
+
+#ifndef QT_NO_QWS_KBD_SL5000
+
+#include "qwindowsystem_qws.h"
+#include "qwsutils_qws.h"
+#include "qscreen_qws.h"
+
+#include "qapplication.h"
+#include "qnamespace.h"
+#include "qtimer.h"
+
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <signal.h>
+
+#include <asm/sharp_char.h>
+
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+static const QWSKeyMap sl5000KeyMap[] = {
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 00
+ { Qt::Key_A, 'a' , 'A' , 'A'-64 }, // 01
+ { Qt::Key_B, 'b' , 'B' , 'B'-64 }, // 02
+ { Qt::Key_C, 'c' , 'C' , 'C'-64 }, // 03
+ { Qt::Key_D, 'd' , 'D' , 'D'-64 }, // 04
+ { Qt::Key_E, 'e' , 'E' , 'E'-64 }, // 05
+ { Qt::Key_F, 'f' , 'F' , 'F'-64 }, // 06
+ { Qt::Key_G, 'g' , 'G' , 'G'-64 }, // 07
+ { Qt::Key_H, 'h' , 'H' , 'H'-64 }, // 08
+ { Qt::Key_I, 'i' , 'I' , 'I'-64 }, // 09
+ { Qt::Key_J, 'j' , 'J' , 'J'-64 }, // 0a 10
+ { Qt::Key_K, 'k' , 'K' , 'K'-64 }, // 0b
+ { Qt::Key_L, 'l' , 'L' , 'L'-64 }, // 0c
+ { Qt::Key_M, 'm' , 'M' , 'M'-64 }, // 0d
+ { Qt::Key_N, 'n' , 'N' , 'N'-64 }, // 0e
+ { Qt::Key_O, 'o' , 'O' , 'O'-64 }, // 0f
+ { Qt::Key_P, 'p' , 'P' , 'P'-64 }, // 10
+ { Qt::Key_Q, 'q' , 'Q' , 'Q'-64 }, // 11
+ { Qt::Key_R, 'r' , 'R' , 'R'-64 }, // 12
+ { Qt::Key_S, 's' , 'S' , 'S'-64 }, // 13
+ { Qt::Key_T, 't' , 'T' , 'T'-64 }, // 14 20
+ { Qt::Key_U, 'u' , 'U' , 'U'-64 }, // 15
+ { Qt::Key_V, 'v' , 'V' , 'V'-64 }, // 16
+ { Qt::Key_W, 'w' , 'W' , 'W'-64 }, // 17
+ { Qt::Key_X, 'x' , 'X' , 'X'-64 }, // 18
+ { Qt::Key_Y, 'y' , 'Y' , 'Y'-64 }, // 19
+ { Qt::Key_Z, 'z' , 'Z' , 'Z'-64 }, // 1a
+ { Qt::Key_Shift, 0xffff , 0xffff , 0xffff }, // 1b
+ { Qt::Key_Return, 13 , 13 , 0xffff }, // 1c
+ { Qt::Key_F11, 0xffff , 0xffff , 0xffff }, // 1d todo
+ { Qt::Key_F22, 0xffff , 0xffff , 0xffff }, // 1e 30
+ { Qt::Key_Backspace, 8 , 8 , 0xffff }, // 1f
+ { Qt::Key_F31, 0xffff , 0xffff , 0xffff }, // 20
+ { Qt::Key_F35, 0xffff , 0xffff , 0xffff }, // 21 light
+ { Qt::Key_Escape, 0xffff , 0xffff , 0xffff }, // 22
+
+ // Direction key code are for *UNROTATED* display.
+ { Qt::Key_Up, 0xffff , 0xffff , 0xffff }, // 23
+ { Qt::Key_Right, 0xffff , 0xffff , 0xffff }, // 24
+ { Qt::Key_Left, 0xffff , 0xffff , 0xffff }, // 25
+ { Qt::Key_Down, 0xffff , 0xffff , 0xffff }, // 26
+
+ { Qt::Key_F33, 0xffff , 0xffff , 0xffff }, // 27 OK
+ { Qt::Key_F12, 0xffff , 0xffff , 0xffff }, // 28 40 home
+ { Qt::Key_1, '1' , 'q' , 'Q'-64 }, // 29
+ { Qt::Key_2, '2' , 'w' , 'W'-64 }, // 2a
+ { Qt::Key_3, '3' , 'e' , 'E'-64 }, // 2b
+ { Qt::Key_4, '4' , 'r' , 'R'-64 }, // 2c
+ { Qt::Key_5, '5' , 't' , 'T'-64 }, // 2d
+ { Qt::Key_6, '6' , 'y' , 'Y'-64 }, // 2e
+ { Qt::Key_7, '7' , 'u' , 'U'-64 }, // 2f
+ { Qt::Key_8, '8' , 'i' , 'I'-64 }, // 30
+ { Qt::Key_9, '9' , 'o' , 'O'-64 }, // 31
+ { Qt::Key_0, '0' , 'p' , 'P'-64 }, // 32 50
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 33
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 34
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 35
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 36
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 37
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 38
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 39
+ { Qt::Key_Minus, '-' , 'b' , 'B'-64 }, // 3a
+ { Qt::Key_Plus, '+' , 'n' , 'N'-64 }, // 3b
+ { Qt::Key_CapsLock, 0xffff , 0xffff , 0xffff }, // 3c 60
+ { Qt::Key_At, '@' , 's' , 'S'-64 }, // 3d
+ { Qt::Key_Question, '?' , '?' , 0xffff }, // 3e
+ { Qt::Key_Comma, ',' , ',' , 0xffff }, // 3f
+ { Qt::Key_Period, '.' , '.' , 0xffff }, // 40
+ { Qt::Key_Tab, 9 , '\\' , 0xffff }, // 41
+ { Qt::Key_X, 0xffff , 'x' , 'X'-64 }, // 42
+ { Qt::Key_C, 0xffff , 'c' , 'C'-64 }, // 43
+ { Qt::Key_V, 0xffff , 'v' , 'V'-64 }, // 44
+ { Qt::Key_Slash, '/' , '/' , 0xffff }, // 45
+ { Qt::Key_Apostrophe, '\'' , '\'' , 0xffff }, // 46 70
+ { Qt::Key_Semicolon, ';' , ';' , 0xffff }, // 47
+ { Qt::Key_QuoteDbl, '\"' , '\"' , 0xffff }, // 48
+ { Qt::Key_Colon, ':' , ':' , 0xffff }, // 49
+ { Qt::Key_NumberSign, '#' , 'd' , 'D'-64 }, // 4a
+ { Qt::Key_Dollar, '$' , 'f' , 'F'-64 }, // 4b
+ { Qt::Key_Percent, '%' , 'g' , 'G'-64 }, // 4c
+ { Qt::Key_Underscore, '_' , 'h' , 'H'-64 }, // 4d
+ { Qt::Key_Ampersand, '&' , 'j' , 'J'-64 }, // 4e
+ { Qt::Key_Asterisk, '*' , 'k' , 'K'-64 }, // 4f
+ { Qt::Key_ParenLeft, '(' , 'l' , 'L'-64 }, // 50 80
+ { Qt::Key_Delete, '[' , '[' , '[' }, // 51
+ { Qt::Key_Z, 0xffff , 'z' , 'Z'-64 }, // 52
+ { Qt::Key_Equal, '=' , 'm' , 'M'-64 }, // 53
+ { Qt::Key_ParenRight, ')' , ']' , ']' }, // 54
+ { Qt::Key_AsciiTilde, '~' , '^' , '^' }, // 55
+ { Qt::Key_Less, '<' , '{' , '{' }, // 56
+ { Qt::Key_Greater, '>' , '}' , '}' }, // 57
+ { Qt::Key_F9, 0xffff , 0xffff , 0xffff }, // 58 datebook
+ { Qt::Key_F10, 0xffff , 0xffff , 0xffff }, // 59 address
+ { Qt::Key_F13, 0xffff , 0xffff , 0xffff }, // 5a 90 email
+ { Qt::Key_F30, ' ' , ' ' , 0xffff }, // 5b select
+ { Qt::Key_Space, ' ' , '|' , '`' }, // 5c
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 5d
+ { Qt::Key_Exclam, '!' , 'a' , 'A'-64 }, // 5e
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 5f
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 60
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 61
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 62
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 63
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 64
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 65
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 66
+ { Qt::Key_Meta, 0xffff , 0xffff , 0xffff }, // 67
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 68
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 69
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 6a
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 6b
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 6c
+ { Qt::Key_F34, 0xffff , 0xffff , 0xffff }, // 6d power
+ { Qt::Key_F13, 0xffff , 0xffff , 0xffff }, // 6e mail long
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 6f
+ { Qt::Key_NumLock, 0xffff , 0xffff , 0xffff }, // 70
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 71
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 72
+ { 0x20ac, 0xffff , 0x20ac , 0x20ac }, // 73 Euro sign
+ { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 74
+ { Qt::Key_F32, 0xffff , 0xffff , 0xffff }, // 75 Sync
+ { 0, 0xffff , 0xffff , 0xffff }
+};
+
+static const int keyMSize = sizeof(sl5000KeyMap)/sizeof(QWSKeyMap)-1;
+
+QWSSL5000KeyboardHandler::QWSSL5000KeyboardHandler(const QString &device)
+ : QWSTtyKeyboardHandler(device)
+{
+ meta = false;
+ fn = false;
+ numLock = false;
+
+ sharp_kbdctl_modifstat st;
+ int dev = ::open(device.isEmpty()?"/dev/sharp_kbdctl":device.toLocal8Bit().constData(), O_RDWR);
+ if (dev >= 0) {
+ memset(&st, 0, sizeof(st));
+ st.which = 3;
+ int ret = ioctl(dev, SHARP_KBDCTL_GETMODIFSTAT, (char*)&st);
+ if(!ret)
+ numLock = (bool)st.stat;
+ ::close(dev);
+ }
+}
+
+QWSSL5000KeyboardHandler::~QWSSL5000KeyboardHandler()
+{
+}
+
+const QWSKeyMap *QWSSL5000KeyboardHandler::keyMap() const
+{
+ return sl5000KeyMap;
+}
+
+void QWSSL5000KeyboardHandler::doKey(uchar code)
+{
+ int keyCode = Qt::Key_unknown;
+ bool release = false;
+
+ if (code & 0x80) {
+ release = true;
+ code &= 0x7f;
+ }
+
+ if (fn && !meta && (code >= 0x42 && code <= 0x52)) {
+ ushort unicode=0;
+ int scan=0;
+ if (code == 0x42) { unicode='X'-'@'; scan=Qt::Key_X; } // Cut
+ else if (code == 0x43) { unicode='C'-'@'; scan=Qt::Key_C; } // Copy
+ else if (code == 0x44) { unicode='V'-'@'; scan=Qt::Key_V; } // Paste
+ else if (code == 0x52) { unicode='Z'-'@'; scan=Qt::Key_Z; } // Undo
+ if (scan) {
+ processKeyEvent(unicode, scan, Qt::ControlModifier, !release, false);
+ return;
+ }
+ }
+
+ if (code < keyMSize) {
+ keyCode = keyMap()[code].key_code;
+ }
+
+ bool repeatable = true;
+
+ if (release && (keyCode == Qt::Key_F34 || keyCode == Qt::Key_F35))
+ return; // no release for power and light keys
+ if (keyCode >= Qt::Key_F1 && keyCode <= Qt::Key_F35
+ || keyCode == Qt::Key_Escape || keyCode == Qt::Key_Home
+ || keyCode == Qt::Key_Shift || keyCode == Qt::Key_Meta)
+ repeatable = false;
+
+ if (qt_screen->isTransformed()
+ && keyCode >= Qt::Key_Left && keyCode <= Qt::Key_Down)
+ {
+ keyCode = transformDirKey(keyCode);
+ }
+
+ // Ctrl-Alt-Delete exits qws
+ if (ctrl && alt && keyCode == Qt::Key_Delete) {
+ qApp->quit();
+ }
+
+ if (keyCode == Qt::Key_F22) { /* Fn key */
+ fn = !release;
+ } else if (keyCode == Qt::Key_NumLock) {
+ if (release)
+ numLock = !numLock;
+ } else if (keyCode == Qt::AltModifier) {
+ alt = !release;
+ } else if (keyCode == Qt::ControlModifier) {
+ ctrl = !release;
+ } else if (keyCode == Qt::ShiftModifier) {
+ shift = !release;
+ } else if (keyCode == Qt::MetaModifier) {
+ meta = !release;
+ } else if (keyCode == Qt::Key_CapsLock && release) {
+ caps = !caps;
+ }
+ if (keyCode != Qt::Key_unknown) {
+ bool bAlt = alt;
+ bool bCtrl = ctrl;
+ bool bShift = shift;
+ int unicode = 0;
+ if (code < keyMSize) {
+ bool bCaps = caps ^ shift;
+ if (fn) {
+ if (shift) {
+ bCaps = bShift = false;
+ bCtrl = true;
+ }
+ if (meta) {
+ bCaps = bShift = true;
+ bAlt = true;
+ }
+ } else if (meta) {
+ bCaps = bShift = true;
+ }
+ if (code > 40 && caps) {
+ // fn-keys should only react to shift, not caps
+ bCaps = bShift = shift;
+ }
+ if (numLock) {
+ if (keyCode != Qt::Key_Space && keyCode != Qt::Key_Tab)
+ bCaps = bShift = false;
+ }
+ if (keyCode == Qt::Key_Delete && (bAlt || bCtrl)) {
+ keyCode = Qt::Key_BraceLeft;
+ unicode = '[';
+ bCaps = bShift = bAlt = bCtrl = false;
+ } else if (keyCode == Qt::Key_F31 && bCtrl) {
+ keyCode = Qt::Key_QuoteLeft;
+ unicode = '`';
+ } else if (bCtrl)
+ unicode = keyMap()[code].ctrl_unicode ? keyMap()[code].ctrl_unicode : 0xffff;
+ else if (bCaps)
+ unicode = keyMap()[code].shift_unicode ? keyMap()[code].shift_unicode : 0xffff;
+ else
+ unicode = keyMap()[code].unicode ? keyMap()[code].unicode : 0xffff;
+ }
+
+ modifiers = 0;
+ if (bAlt) modifiers |= Qt::AltModifier;
+ if (bCtrl) modifiers |= Qt::ControlModifier;
+ if (bShift) modifiers |= Qt::ShiftModifier;
+
+ // looks wrong -- WWA
+ bool repeat = false;
+ if (prevuni == unicode && prevkey == keyCode && !release)
+ repeat = true;
+
+ processKeyEvent(unicode, keyCode, modifiers, !release, repeat);
+
+ if (!release) {
+ prevuni = unicode;
+ prevkey = keyCode;
+ } else {
+ prevkey = prevuni = 0;
+ }
+ }
+
+ if (repeatable && !release)
+ beginAutoRepeat(prevuni, prevkey, modifiers);
+ else
+ endAutoRepeat();
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_QWS_KBD_SL5000