diff options
author | Robert Griebl <rgriebl@trolltech.com> | 2009-03-03 17:36:58 (GMT) |
---|---|---|
committer | Robert Griebl <rgriebl@trolltech.com> | 2009-04-02 19:21:57 (GMT) |
commit | 3f51c30f030a5517273a62bdd48dfe96c98852ee (patch) | |
tree | aa40f43a4d2d0b8e68b8b4ebbd86113bc8bc4f60 | |
parent | 86723ca856dbd07bc7809ed9c3f9a219a99e67bd (diff) | |
download | Qt-3f51c30f030a5517273a62bdd48dfe96c98852ee.zip Qt-3f51c30f030a5517273a62bdd48dfe96c98852ee.tar.gz Qt-3f51c30f030a5517273a62bdd48dfe96c98852ee.tar.bz2 |
Keymap support for QWS.
This patch adds support for keymaps to the QWSKeyboardHandler. The keymaps
can be generated by the kmap2qmap tool (see tools/ directory). The source
keymaps can be standard Linux .kmap files.
Changes to Qt:
* completely refactored the Tty and Usb (now known as LinuxInput) handlers
* removed the LinuxIS plugin (handled by LinuxInput now)
* removed support for iPAQ, EBX and Zylonite keypads (obsolete hardware)
* removed support for RAW tty mode. This could be re-added, for non-Linux
systems by implementing a PC/AT scan-code to Linux keycode converter.
New features for Tty and LinuxInput (ex Usb) handlers:
* support for keymaps
QWS_KEYBOARD=..:keymap=/path/to/x.qmap:..
* support for dead keys and the compose key
* support for lock LEDs
* support for key repeat rates (in ms):
QWS_KEYBOARD=..:repeat-delay=x:repear-rate=y:..
* the default keymap supports latin1 composing via AltGr:
QWS_KEYBOARD=..:enable-compose:..
* ctrl+alt+backspace application zapping can be disabled:
QWS_KEYBOARD=..:disable-zap:..
* added virtual filter functions to both the Tty and the LinuxInput
handlers. (QWSKeyboardHandler::processKeycode should be virtual in the
first place, but that would be BIC)
Still missing:
* extended documentation for QWS_KEYBOARD
Reviewed-By: Paul Olav Tvete
Reviewed-By: Harald Fernengel
27 files changed, 2780 insertions, 1020 deletions
@@ -601,7 +601,7 @@ CFG_GFX_ON="linuxfb multiscreen" CFG_GFX_PLUGIN_AVAILABLE= CFG_GFX_PLUGIN= CFG_GFX_OFF= -CFG_KBD_AVAILABLE="tty usb sl5000 yopy vr41xx qvfb" +CFG_KBD_AVAILABLE="tty linuxinput sl5000 yopy vr41xx qvfb" CFG_KBD_ON="tty" #default, see QMakeVar above CFG_MOUSE_AVAILABLE="pc bus linuxtp yopy vr41xx tslib qvfb" CFG_MOUSE_ON="pc linuxtp" #default, see QMakeVar above diff --git a/src/gui/embedded/embedded.pri b/src/gui/embedded/embedded.pri index 95c4132..4a9aa3f 100644 --- a/src/gui/embedded/embedded.pri +++ b/src/gui/embedded/embedded.pri @@ -89,6 +89,8 @@ embedded { HEADERS += embedded/qscreendriverplugin_qws.h \ embedded/qscreendriverfactory_qws.h \ embedded/qkbd_qws.h \ + embedded/qkbd_qws_p.h \ + embedded/qkbd_defaultmap_qws_p.h \ embedded/qkbddriverplugin_qws.h \ embedded/qkbddriverfactory_qws.h \ embedded/qmouse_qws.h \ @@ -152,17 +154,11 @@ embedded { contains( kbd-drivers, tty ) { HEADERS +=embedded/qkbdtty_qws.h SOURCES +=embedded/qkbdtty_qws.cpp - !contains( kbd-drivers, pc101 ) { - kbd-drivers += pc101 - } } - contains( kbd-drivers, usb ) { - HEADERS +=embedded/qkbdusb_qws.h - SOURCES +=embedded/qkbdusb_qws.cpp - !contains( kbd-drivers, pc101 ) { - kbd-drivers += pc101 - } + contains( kbd-drivers, linuxinput ) { + HEADERS +=embedded/qkbdlinuxinput_qws.h + SOURCES +=embedded/qkbdlinuxinput_qws.cpp } contains( kbd-drivers, um ) { @@ -170,11 +166,6 @@ embedded { SOURCES +=embedded/qkbdum_qws.cpp } - contains( kbd-drivers, pc101 ) { - HEADERS +=embedded/qkbdpc101_qws.h - SOURCES +=embedded/qkbdpc101_qws.cpp - } - contains( kbd-drivers, yopy ) { HEADERS +=embedded/qkbdyopy_qws.h SOURCES +=embedded/qkbdyopy_qws.cpp diff --git a/src/gui/embedded/qkbd_defaultmap_qws_p.h b/src/gui/embedded/qkbd_defaultmap_qws_p.h new file mode 100644 index 0000000..34ce69e --- /dev/null +++ b/src/gui/embedded/qkbd_defaultmap_qws_p.h @@ -0,0 +1,744 @@ +#ifndef QWSKEYBOARDHANDLER_DEFAULTMAP_H +#define QWSKEYBOARDHANDLER_DEFAULTMAP_H + +const QWSKeyboard::Mapping QWSKbPrivate::s_keymap_default[] = { + { 1, 0xffff, 0x01000000, 0x00, 0x00, 0x0000 }, + { 2, 0x0031, 0x00000031, 0x00, 0x00, 0x0000 }, + { 2, 0x0021, 0x00000021, 0x01, 0x00, 0x0000 }, + { 3, 0x0032, 0x00000032, 0x00, 0x00, 0x0000 }, + { 3, 0x0040, 0x00000040, 0x01, 0x00, 0x0000 }, + { 3, 0x0040, 0x00000040, 0x02, 0x00, 0x0000 }, + { 4, 0x0033, 0x00000033, 0x00, 0x00, 0x0000 }, + { 4, 0x0023, 0x00000023, 0x01, 0x00, 0x0000 }, + { 4, 0xffff, 0x01000000, 0x04, 0x00, 0x0000 }, + { 5, 0x0034, 0x00000034, 0x00, 0x00, 0x0000 }, + { 5, 0x0024, 0x00000024, 0x01, 0x00, 0x0000 }, + { 5, 0x0024, 0x00000024, 0x02, 0x00, 0x0000 }, + { 5, 0x005c, 0x0400005c, 0x04, 0x00, 0x0000 }, + { 6, 0x0035, 0x00000035, 0x00, 0x00, 0x0000 }, + { 6, 0x0025, 0x00000025, 0x01, 0x00, 0x0000 }, + { 6, 0x005d, 0x0400005d, 0x04, 0x00, 0x0000 }, + { 7, 0x0036, 0x00000036, 0x00, 0x00, 0x0000 }, + { 7, 0x005e, 0x0000005e, 0x01, 0x00, 0x0000 }, + { 7, 0x005e, 0x01001252, 0x02, 0x01, 0x0000 }, + { 7, 0x005e, 0x0400005e, 0x04, 0x00, 0x0000 }, + { 8, 0x0037, 0x00000037, 0x00, 0x00, 0x0000 }, + { 8, 0x0026, 0x00000026, 0x01, 0x00, 0x0000 }, + { 8, 0x007b, 0x0000007b, 0x02, 0x00, 0x0000 }, + { 8, 0x005f, 0x0400005f, 0x04, 0x00, 0x0000 }, + { 9, 0x0038, 0x00000038, 0x00, 0x00, 0x0000 }, + { 9, 0x002a, 0x0000002a, 0x01, 0x00, 0x0000 }, + { 9, 0x005b, 0x0000005b, 0x02, 0x00, 0x0000 }, + { 9, 0xffff, 0x01000003, 0x04, 0x00, 0x0000 }, + { 10, 0x0039, 0x00000039, 0x00, 0x00, 0x0000 }, + { 10, 0x0028, 0x00000028, 0x01, 0x00, 0x0000 }, + { 10, 0x005d, 0x0000005d, 0x02, 0x00, 0x0000 }, + { 11, 0x0030, 0x00000030, 0x00, 0x00, 0x0000 }, + { 11, 0x0029, 0x00000029, 0x01, 0x00, 0x0000 }, + { 11, 0x007d, 0x0000007d, 0x02, 0x00, 0x0000 }, + { 12, 0x002d, 0x0000002d, 0x00, 0x00, 0x0000 }, + { 12, 0x005f, 0x0000005f, 0x01, 0x00, 0x0000 }, + { 12, 0x005c, 0x0000005c, 0x02, 0x00, 0x0000 }, + { 12, 0x005f, 0x0400005f, 0x04, 0x00, 0x0000 }, + { 12, 0x005f, 0x0400005f, 0x05, 0x00, 0x0000 }, + { 13, 0x003d, 0x0000003d, 0x00, 0x00, 0x0000 }, + { 13, 0x002b, 0x0000002b, 0x01, 0x00, 0x0000 }, + { 14, 0xffff, 0x01000003, 0x00, 0x00, 0x0000 }, + { 14, 0xffff, 0x01000000, 0x0c, 0x08, 0x0300 }, + { 15, 0xffff, 0x01000001, 0x00, 0x00, 0x0000 }, + { 16, 0x0071, 0x00000051, 0x00, 0x00, 0x0000 }, + { 16, 0x0051, 0x00000051, 0x01, 0x00, 0x0000 }, + { 16, 0x0071, 0x00000051, 0x02, 0x00, 0x0000 }, + { 16, 0x0051, 0x00000051, 0x03, 0x00, 0x0000 }, + { 16, 0x0071, 0x04000051, 0x04, 0x00, 0x0000 }, + { 16, 0x0071, 0x04000051, 0x05, 0x00, 0x0000 }, + { 16, 0x0071, 0x04000051, 0x06, 0x00, 0x0000 }, + { 16, 0x0071, 0x04000051, 0x07, 0x00, 0x0000 }, + { 16, 0x0071, 0x08000051, 0x08, 0x00, 0x0000 }, + { 16, 0x0071, 0x08000051, 0x09, 0x00, 0x0000 }, + { 16, 0x0071, 0x08000051, 0x0a, 0x00, 0x0000 }, + { 16, 0x0071, 0x08000051, 0x0b, 0x00, 0x0000 }, + { 16, 0x0071, 0x0c000051, 0x0c, 0x00, 0x0000 }, + { 16, 0x0071, 0x0c000051, 0x0d, 0x00, 0x0000 }, + { 16, 0x0071, 0x0c000051, 0x0e, 0x00, 0x0000 }, + { 16, 0x0071, 0x0c000051, 0x0f, 0x00, 0x0000 }, + { 17, 0x0077, 0x00000057, 0x00, 0x00, 0x0000 }, + { 17, 0x0057, 0x00000057, 0x01, 0x00, 0x0000 }, + { 17, 0x0077, 0x00000057, 0x02, 0x00, 0x0000 }, + { 17, 0x0057, 0x00000057, 0x03, 0x00, 0x0000 }, + { 17, 0x0077, 0x04000057, 0x04, 0x00, 0x0000 }, + { 17, 0x0077, 0x04000057, 0x05, 0x00, 0x0000 }, + { 17, 0x0077, 0x04000057, 0x06, 0x00, 0x0000 }, + { 17, 0x0077, 0x04000057, 0x07, 0x00, 0x0000 }, + { 17, 0x0077, 0x08000057, 0x08, 0x00, 0x0000 }, + { 17, 0x0077, 0x08000057, 0x09, 0x00, 0x0000 }, + { 17, 0x0077, 0x08000057, 0x0a, 0x00, 0x0000 }, + { 17, 0x0077, 0x08000057, 0x0b, 0x00, 0x0000 }, + { 17, 0x0077, 0x0c000057, 0x0c, 0x00, 0x0000 }, + { 17, 0x0077, 0x0c000057, 0x0d, 0x00, 0x0000 }, + { 17, 0x0077, 0x0c000057, 0x0e, 0x00, 0x0000 }, + { 17, 0x0077, 0x0c000057, 0x0f, 0x00, 0x0000 }, + { 18, 0x0065, 0x00000045, 0x00, 0x00, 0x0000 }, + { 18, 0x0045, 0x00000045, 0x01, 0x00, 0x0000 }, + { 18, 0x0065, 0x00000045, 0x02, 0x00, 0x0000 }, + { 18, 0x0045, 0x00000045, 0x03, 0x00, 0x0000 }, + { 18, 0x0065, 0x04000045, 0x04, 0x00, 0x0000 }, + { 18, 0x0065, 0x04000045, 0x05, 0x00, 0x0000 }, + { 18, 0x0065, 0x04000045, 0x06, 0x00, 0x0000 }, + { 18, 0x0065, 0x04000045, 0x07, 0x00, 0x0000 }, + { 18, 0x0065, 0x08000045, 0x08, 0x00, 0x0000 }, + { 18, 0x0065, 0x08000045, 0x09, 0x00, 0x0000 }, + { 18, 0x0065, 0x08000045, 0x0a, 0x00, 0x0000 }, + { 18, 0x0065, 0x08000045, 0x0b, 0x00, 0x0000 }, + { 18, 0x0065, 0x0c000045, 0x0c, 0x00, 0x0000 }, + { 18, 0x0065, 0x0c000045, 0x0d, 0x00, 0x0000 }, + { 18, 0x0065, 0x0c000045, 0x0e, 0x00, 0x0000 }, + { 18, 0x0065, 0x0c000045, 0x0f, 0x00, 0x0000 }, + { 19, 0x0072, 0x00000052, 0x00, 0x00, 0x0000 }, + { 19, 0x0052, 0x00000052, 0x01, 0x00, 0x0000 }, + { 19, 0x0072, 0x00000052, 0x02, 0x00, 0x0000 }, + { 19, 0x0052, 0x00000052, 0x03, 0x00, 0x0000 }, + { 19, 0x0072, 0x04000052, 0x04, 0x00, 0x0000 }, + { 19, 0x0072, 0x04000052, 0x05, 0x00, 0x0000 }, + { 19, 0x0072, 0x04000052, 0x06, 0x00, 0x0000 }, + { 19, 0x0072, 0x04000052, 0x07, 0x00, 0x0000 }, + { 19, 0x0072, 0x08000052, 0x08, 0x00, 0x0000 }, + { 19, 0x0072, 0x08000052, 0x09, 0x00, 0x0000 }, + { 19, 0x0072, 0x08000052, 0x0a, 0x00, 0x0000 }, + { 19, 0x0072, 0x08000052, 0x0b, 0x00, 0x0000 }, + { 19, 0x0072, 0x0c000052, 0x0c, 0x00, 0x0000 }, + { 19, 0x0072, 0x0c000052, 0x0d, 0x00, 0x0000 }, + { 19, 0x0072, 0x0c000052, 0x0e, 0x00, 0x0000 }, + { 19, 0x0072, 0x0c000052, 0x0f, 0x00, 0x0000 }, + { 20, 0x0074, 0x00000054, 0x00, 0x00, 0x0000 }, + { 20, 0x0054, 0x00000054, 0x01, 0x00, 0x0000 }, + { 20, 0x0074, 0x00000054, 0x02, 0x00, 0x0000 }, + { 20, 0x0054, 0x00000054, 0x03, 0x00, 0x0000 }, + { 20, 0x0074, 0x04000054, 0x04, 0x00, 0x0000 }, + { 20, 0x0074, 0x04000054, 0x05, 0x00, 0x0000 }, + { 20, 0x0074, 0x04000054, 0x06, 0x00, 0x0000 }, + { 20, 0x0074, 0x04000054, 0x07, 0x00, 0x0000 }, + { 20, 0x0074, 0x08000054, 0x08, 0x00, 0x0000 }, + { 20, 0x0074, 0x08000054, 0x09, 0x00, 0x0000 }, + { 20, 0x0074, 0x08000054, 0x0a, 0x00, 0x0000 }, + { 20, 0x0074, 0x08000054, 0x0b, 0x00, 0x0000 }, + { 20, 0x0074, 0x0c000054, 0x0c, 0x00, 0x0000 }, + { 20, 0x0074, 0x0c000054, 0x0d, 0x00, 0x0000 }, + { 20, 0x0074, 0x0c000054, 0x0e, 0x00, 0x0000 }, + { 20, 0x0074, 0x0c000054, 0x0f, 0x00, 0x0000 }, + { 21, 0x0079, 0x00000059, 0x00, 0x00, 0x0000 }, + { 21, 0x0059, 0x00000059, 0x01, 0x00, 0x0000 }, + { 21, 0x0079, 0x00000059, 0x02, 0x00, 0x0000 }, + { 21, 0x0059, 0x00000059, 0x03, 0x00, 0x0000 }, + { 21, 0x0079, 0x04000059, 0x04, 0x00, 0x0000 }, + { 21, 0x0079, 0x04000059, 0x05, 0x00, 0x0000 }, + { 21, 0x0079, 0x04000059, 0x06, 0x00, 0x0000 }, + { 21, 0x0079, 0x04000059, 0x07, 0x00, 0x0000 }, + { 21, 0x0079, 0x08000059, 0x08, 0x00, 0x0000 }, + { 21, 0x0079, 0x08000059, 0x09, 0x00, 0x0000 }, + { 21, 0x0079, 0x08000059, 0x0a, 0x00, 0x0000 }, + { 21, 0x0079, 0x08000059, 0x0b, 0x00, 0x0000 }, + { 21, 0x0079, 0x0c000059, 0x0c, 0x00, 0x0000 }, + { 21, 0x0079, 0x0c000059, 0x0d, 0x00, 0x0000 }, + { 21, 0x0079, 0x0c000059, 0x0e, 0x00, 0x0000 }, + { 21, 0x0079, 0x0c000059, 0x0f, 0x00, 0x0000 }, + { 22, 0x0075, 0x00000055, 0x00, 0x00, 0x0000 }, + { 22, 0x0055, 0x00000055, 0x01, 0x00, 0x0000 }, + { 22, 0x0075, 0x00000055, 0x02, 0x00, 0x0000 }, + { 22, 0x0055, 0x00000055, 0x03, 0x00, 0x0000 }, + { 22, 0x0075, 0x04000055, 0x04, 0x00, 0x0000 }, + { 22, 0x0075, 0x04000055, 0x05, 0x00, 0x0000 }, + { 22, 0x0075, 0x04000055, 0x06, 0x00, 0x0000 }, + { 22, 0x0075, 0x04000055, 0x07, 0x00, 0x0000 }, + { 22, 0x0075, 0x08000055, 0x08, 0x00, 0x0000 }, + { 22, 0x0075, 0x08000055, 0x09, 0x00, 0x0000 }, + { 22, 0x0075, 0x08000055, 0x0a, 0x00, 0x0000 }, + { 22, 0x0075, 0x08000055, 0x0b, 0x00, 0x0000 }, + { 22, 0x0075, 0x0c000055, 0x0c, 0x00, 0x0000 }, + { 22, 0x0075, 0x0c000055, 0x0d, 0x00, 0x0000 }, + { 22, 0x0075, 0x0c000055, 0x0e, 0x00, 0x0000 }, + { 22, 0x0075, 0x0c000055, 0x0f, 0x00, 0x0000 }, + { 23, 0x0069, 0x00000049, 0x00, 0x00, 0x0000 }, + { 23, 0x0049, 0x00000049, 0x01, 0x00, 0x0000 }, + { 23, 0x0069, 0x00000049, 0x02, 0x00, 0x0000 }, + { 23, 0x0049, 0x00000049, 0x03, 0x00, 0x0000 }, + { 23, 0x0069, 0x04000049, 0x04, 0x00, 0x0000 }, + { 23, 0x0069, 0x04000049, 0x05, 0x00, 0x0000 }, + { 23, 0x0069, 0x04000049, 0x06, 0x00, 0x0000 }, + { 23, 0x0069, 0x04000049, 0x07, 0x00, 0x0000 }, + { 23, 0x0069, 0x08000049, 0x08, 0x00, 0x0000 }, + { 23, 0x0069, 0x08000049, 0x09, 0x00, 0x0000 }, + { 23, 0x0069, 0x08000049, 0x0a, 0x00, 0x0000 }, + { 23, 0x0069, 0x08000049, 0x0b, 0x00, 0x0000 }, + { 23, 0x0069, 0x0c000049, 0x0c, 0x00, 0x0000 }, + { 23, 0x0069, 0x0c000049, 0x0d, 0x00, 0x0000 }, + { 23, 0x0069, 0x0c000049, 0x0e, 0x00, 0x0000 }, + { 23, 0x0069, 0x0c000049, 0x0f, 0x00, 0x0000 }, + { 24, 0x006f, 0x0000004f, 0x00, 0x00, 0x0000 }, + { 24, 0x004f, 0x0000004f, 0x01, 0x00, 0x0000 }, + { 24, 0x006f, 0x0000004f, 0x02, 0x00, 0x0000 }, + { 24, 0x004f, 0x0000004f, 0x03, 0x00, 0x0000 }, + { 24, 0x006f, 0x0400004f, 0x04, 0x00, 0x0000 }, + { 24, 0x006f, 0x0400004f, 0x05, 0x00, 0x0000 }, + { 24, 0x006f, 0x0400004f, 0x06, 0x00, 0x0000 }, + { 24, 0x006f, 0x0400004f, 0x07, 0x00, 0x0000 }, + { 24, 0x006f, 0x0800004f, 0x08, 0x00, 0x0000 }, + { 24, 0x006f, 0x0800004f, 0x09, 0x00, 0x0000 }, + { 24, 0x006f, 0x0800004f, 0x0a, 0x00, 0x0000 }, + { 24, 0x006f, 0x0800004f, 0x0b, 0x00, 0x0000 }, + { 24, 0x006f, 0x0c00004f, 0x0c, 0x00, 0x0000 }, + { 24, 0x006f, 0x0c00004f, 0x0d, 0x00, 0x0000 }, + { 24, 0x006f, 0x0c00004f, 0x0e, 0x00, 0x0000 }, + { 24, 0x006f, 0x0c00004f, 0x0f, 0x00, 0x0000 }, + { 25, 0x0070, 0x00000050, 0x00, 0x00, 0x0000 }, + { 25, 0x0050, 0x00000050, 0x01, 0x00, 0x0000 }, + { 25, 0x0070, 0x00000050, 0x02, 0x00, 0x0000 }, + { 25, 0x0050, 0x00000050, 0x03, 0x00, 0x0000 }, + { 25, 0x0070, 0x04000050, 0x04, 0x00, 0x0000 }, + { 25, 0x0070, 0x04000050, 0x05, 0x00, 0x0000 }, + { 25, 0x0070, 0x04000050, 0x06, 0x00, 0x0000 }, + { 25, 0x0070, 0x04000050, 0x07, 0x00, 0x0000 }, + { 25, 0x0070, 0x08000050, 0x08, 0x00, 0x0000 }, + { 25, 0x0070, 0x08000050, 0x09, 0x00, 0x0000 }, + { 25, 0x0070, 0x08000050, 0x0a, 0x00, 0x0000 }, + { 25, 0x0070, 0x08000050, 0x0b, 0x00, 0x0000 }, + { 25, 0x0070, 0x0c000050, 0x0c, 0x00, 0x0000 }, + { 25, 0x0070, 0x0c000050, 0x0d, 0x00, 0x0000 }, + { 25, 0x0070, 0x0c000050, 0x0e, 0x00, 0x0000 }, + { 25, 0x0070, 0x0c000050, 0x0f, 0x00, 0x0000 }, + { 26, 0x005b, 0x0000005b, 0x00, 0x00, 0x0000 }, + { 26, 0x007b, 0x0000007b, 0x01, 0x00, 0x0000 }, + { 26, 0xffff, 0x01000000, 0x04, 0x00, 0x0000 }, + { 27, 0x005d, 0x0000005d, 0x00, 0x00, 0x0000 }, + { 27, 0x007d, 0x0000007d, 0x01, 0x00, 0x0000 }, + { 27, 0x007e, 0x0000007e, 0x02, 0x00, 0x0000 }, + { 27, 0x005d, 0x0400005d, 0x04, 0x00, 0x0000 }, + { 28, 0xffff, 0x01000004, 0x00, 0x00, 0x0000 }, + { 28, 0x006d, 0x0c00004d, 0x08, 0x00, 0x0000 }, + { 29, 0xffff, 0x01000021, 0x00, 0x04, 0x0004 }, + { 30, 0x0061, 0x00000041, 0x00, 0x00, 0x0000 }, + { 30, 0x0041, 0x00000041, 0x01, 0x00, 0x0000 }, + { 30, 0x0061, 0x00000041, 0x02, 0x00, 0x0000 }, + { 30, 0x0041, 0x00000041, 0x03, 0x00, 0x0000 }, + { 30, 0x0061, 0x04000041, 0x04, 0x00, 0x0000 }, + { 30, 0x0061, 0x04000041, 0x05, 0x00, 0x0000 }, + { 30, 0x0061, 0x04000041, 0x06, 0x00, 0x0000 }, + { 30, 0x0061, 0x04000041, 0x07, 0x00, 0x0000 }, + { 30, 0x0061, 0x08000041, 0x08, 0x00, 0x0000 }, + { 30, 0x0061, 0x08000041, 0x09, 0x00, 0x0000 }, + { 30, 0x0061, 0x08000041, 0x0a, 0x00, 0x0000 }, + { 30, 0x0061, 0x08000041, 0x0b, 0x00, 0x0000 }, + { 30, 0x0061, 0x0c000041, 0x0c, 0x00, 0x0000 }, + { 30, 0x0061, 0x0c000041, 0x0d, 0x00, 0x0000 }, + { 30, 0x0061, 0x0c000041, 0x0e, 0x00, 0x0000 }, + { 30, 0x0061, 0x0c000041, 0x0f, 0x00, 0x0000 }, + { 31, 0x0073, 0x00000053, 0x00, 0x00, 0x0000 }, + { 31, 0x0053, 0x00000053, 0x01, 0x00, 0x0000 }, + { 31, 0x0073, 0x00000053, 0x02, 0x00, 0x0000 }, + { 31, 0x0053, 0x00000053, 0x03, 0x00, 0x0000 }, + { 31, 0x0073, 0x04000053, 0x04, 0x00, 0x0000 }, + { 31, 0x0073, 0x04000053, 0x05, 0x00, 0x0000 }, + { 31, 0x0073, 0x04000053, 0x06, 0x00, 0x0000 }, + { 31, 0x0073, 0x04000053, 0x07, 0x00, 0x0000 }, + { 31, 0x0073, 0x08000053, 0x08, 0x00, 0x0000 }, + { 31, 0x0073, 0x08000053, 0x09, 0x00, 0x0000 }, + { 31, 0x0073, 0x08000053, 0x0a, 0x00, 0x0000 }, + { 31, 0x0073, 0x08000053, 0x0b, 0x00, 0x0000 }, + { 31, 0x0073, 0x0c000053, 0x0c, 0x00, 0x0000 }, + { 31, 0x0073, 0x0c000053, 0x0d, 0x00, 0x0000 }, + { 31, 0x0073, 0x0c000053, 0x0e, 0x00, 0x0000 }, + { 31, 0x0073, 0x0c000053, 0x0f, 0x00, 0x0000 }, + { 32, 0x0064, 0x00000044, 0x00, 0x00, 0x0000 }, + { 32, 0x0044, 0x00000044, 0x01, 0x00, 0x0000 }, + { 32, 0x0064, 0x00000044, 0x02, 0x00, 0x0000 }, + { 32, 0x0044, 0x00000044, 0x03, 0x00, 0x0000 }, + { 32, 0x0064, 0x04000044, 0x04, 0x00, 0x0000 }, + { 32, 0x0064, 0x04000044, 0x05, 0x00, 0x0000 }, + { 32, 0x0064, 0x04000044, 0x06, 0x00, 0x0000 }, + { 32, 0x0064, 0x04000044, 0x07, 0x00, 0x0000 }, + { 32, 0x0064, 0x08000044, 0x08, 0x00, 0x0000 }, + { 32, 0x0064, 0x08000044, 0x09, 0x00, 0x0000 }, + { 32, 0x0064, 0x08000044, 0x0a, 0x00, 0x0000 }, + { 32, 0x0064, 0x08000044, 0x0b, 0x00, 0x0000 }, + { 32, 0x0064, 0x0c000044, 0x0c, 0x00, 0x0000 }, + { 32, 0x0064, 0x0c000044, 0x0d, 0x00, 0x0000 }, + { 32, 0x0064, 0x0c000044, 0x0e, 0x00, 0x0000 }, + { 32, 0x0064, 0x0c000044, 0x0f, 0x00, 0x0000 }, + { 33, 0x0066, 0x00000046, 0x00, 0x00, 0x0000 }, + { 33, 0x0046, 0x00000046, 0x01, 0x00, 0x0000 }, + { 33, 0x0066, 0x00000046, 0x02, 0x00, 0x0000 }, + { 33, 0x0046, 0x00000046, 0x03, 0x00, 0x0000 }, + { 33, 0x0066, 0x04000046, 0x04, 0x00, 0x0000 }, + { 33, 0x0066, 0x04000046, 0x05, 0x00, 0x0000 }, + { 33, 0x0066, 0x04000046, 0x06, 0x00, 0x0000 }, + { 33, 0x0066, 0x04000046, 0x07, 0x00, 0x0000 }, + { 33, 0x0066, 0x08000046, 0x08, 0x00, 0x0000 }, + { 33, 0x0066, 0x08000046, 0x09, 0x00, 0x0000 }, + { 33, 0x0066, 0x08000046, 0x0a, 0x00, 0x0000 }, + { 33, 0x0066, 0x08000046, 0x0b, 0x00, 0x0000 }, + { 33, 0x0066, 0x0c000046, 0x0c, 0x00, 0x0000 }, + { 33, 0x0066, 0x0c000046, 0x0d, 0x00, 0x0000 }, + { 33, 0x0066, 0x0c000046, 0x0e, 0x00, 0x0000 }, + { 33, 0x0066, 0x0c000046, 0x0f, 0x00, 0x0000 }, + { 34, 0x0067, 0x00000047, 0x00, 0x00, 0x0000 }, + { 34, 0x0047, 0x00000047, 0x01, 0x00, 0x0000 }, + { 34, 0x0067, 0x00000047, 0x02, 0x00, 0x0000 }, + { 34, 0x0047, 0x00000047, 0x03, 0x00, 0x0000 }, + { 34, 0x0067, 0x04000047, 0x04, 0x00, 0x0000 }, + { 34, 0x0067, 0x04000047, 0x05, 0x00, 0x0000 }, + { 34, 0x0067, 0x04000047, 0x06, 0x00, 0x0000 }, + { 34, 0x0067, 0x04000047, 0x07, 0x00, 0x0000 }, + { 34, 0x0067, 0x08000047, 0x08, 0x00, 0x0000 }, + { 34, 0x0067, 0x08000047, 0x09, 0x00, 0x0000 }, + { 34, 0x0067, 0x08000047, 0x0a, 0x00, 0x0000 }, + { 34, 0x0067, 0x08000047, 0x0b, 0x00, 0x0000 }, + { 34, 0x0067, 0x0c000047, 0x0c, 0x00, 0x0000 }, + { 34, 0x0067, 0x0c000047, 0x0d, 0x00, 0x0000 }, + { 34, 0x0067, 0x0c000047, 0x0e, 0x00, 0x0000 }, + { 34, 0x0067, 0x0c000047, 0x0f, 0x00, 0x0000 }, + { 35, 0x0068, 0x00000048, 0x00, 0x00, 0x0000 }, + { 35, 0x0048, 0x00000048, 0x01, 0x00, 0x0000 }, + { 35, 0x0068, 0x00000048, 0x02, 0x00, 0x0000 }, + { 35, 0x0048, 0x00000048, 0x03, 0x00, 0x0000 }, + { 35, 0x0068, 0x04000048, 0x04, 0x00, 0x0000 }, + { 35, 0x0068, 0x04000048, 0x05, 0x00, 0x0000 }, + { 35, 0x0068, 0x04000048, 0x06, 0x00, 0x0000 }, + { 35, 0x0068, 0x04000048, 0x07, 0x00, 0x0000 }, + { 35, 0x0068, 0x08000048, 0x08, 0x00, 0x0000 }, + { 35, 0x0068, 0x08000048, 0x09, 0x00, 0x0000 }, + { 35, 0x0068, 0x08000048, 0x0a, 0x00, 0x0000 }, + { 35, 0x0068, 0x08000048, 0x0b, 0x00, 0x0000 }, + { 35, 0x0068, 0x0c000048, 0x0c, 0x00, 0x0000 }, + { 35, 0x0068, 0x0c000048, 0x0d, 0x00, 0x0000 }, + { 35, 0x0068, 0x0c000048, 0x0e, 0x00, 0x0000 }, + { 35, 0x0068, 0x0c000048, 0x0f, 0x00, 0x0000 }, + { 36, 0x006a, 0x0000004a, 0x00, 0x00, 0x0000 }, + { 36, 0x004a, 0x0000004a, 0x01, 0x00, 0x0000 }, + { 36, 0x006a, 0x0000004a, 0x02, 0x00, 0x0000 }, + { 36, 0x004a, 0x0000004a, 0x03, 0x00, 0x0000 }, + { 36, 0x006a, 0x0400004a, 0x04, 0x00, 0x0000 }, + { 36, 0x006a, 0x0400004a, 0x05, 0x00, 0x0000 }, + { 36, 0x006a, 0x0400004a, 0x06, 0x00, 0x0000 }, + { 36, 0x006a, 0x0400004a, 0x07, 0x00, 0x0000 }, + { 36, 0x006a, 0x0800004a, 0x08, 0x00, 0x0000 }, + { 36, 0x006a, 0x0800004a, 0x09, 0x00, 0x0000 }, + { 36, 0x006a, 0x0800004a, 0x0a, 0x00, 0x0000 }, + { 36, 0x006a, 0x0800004a, 0x0b, 0x00, 0x0000 }, + { 36, 0x006a, 0x0c00004a, 0x0c, 0x00, 0x0000 }, + { 36, 0x006a, 0x0c00004a, 0x0d, 0x00, 0x0000 }, + { 36, 0x006a, 0x0c00004a, 0x0e, 0x00, 0x0000 }, + { 36, 0x006a, 0x0c00004a, 0x0f, 0x00, 0x0000 }, + { 37, 0x006b, 0x0000004b, 0x00, 0x00, 0x0000 }, + { 37, 0x004b, 0x0000004b, 0x01, 0x00, 0x0000 }, + { 37, 0x006b, 0x0000004b, 0x02, 0x00, 0x0000 }, + { 37, 0x004b, 0x0000004b, 0x03, 0x00, 0x0000 }, + { 37, 0x006b, 0x0400004b, 0x04, 0x00, 0x0000 }, + { 37, 0x006b, 0x0400004b, 0x05, 0x00, 0x0000 }, + { 37, 0x006b, 0x0400004b, 0x06, 0x00, 0x0000 }, + { 37, 0x006b, 0x0400004b, 0x07, 0x00, 0x0000 }, + { 37, 0x006b, 0x0800004b, 0x08, 0x00, 0x0000 }, + { 37, 0x006b, 0x0800004b, 0x09, 0x00, 0x0000 }, + { 37, 0x006b, 0x0800004b, 0x0a, 0x00, 0x0000 }, + { 37, 0x006b, 0x0800004b, 0x0b, 0x00, 0x0000 }, + { 37, 0x006b, 0x0c00004b, 0x0c, 0x00, 0x0000 }, + { 37, 0x006b, 0x0c00004b, 0x0d, 0x00, 0x0000 }, + { 37, 0x006b, 0x0c00004b, 0x0e, 0x00, 0x0000 }, + { 37, 0x006b, 0x0c00004b, 0x0f, 0x00, 0x0000 }, + { 38, 0x006c, 0x0000004c, 0x00, 0x00, 0x0000 }, + { 38, 0x004c, 0x0000004c, 0x01, 0x00, 0x0000 }, + { 38, 0x006c, 0x0000004c, 0x02, 0x00, 0x0000 }, + { 38, 0x004c, 0x0000004c, 0x03, 0x00, 0x0000 }, + { 38, 0x006c, 0x0400004c, 0x04, 0x00, 0x0000 }, + { 38, 0x006c, 0x0400004c, 0x05, 0x00, 0x0000 }, + { 38, 0x006c, 0x0400004c, 0x06, 0x00, 0x0000 }, + { 38, 0x006c, 0x0400004c, 0x07, 0x00, 0x0000 }, + { 38, 0x006c, 0x0800004c, 0x08, 0x00, 0x0000 }, + { 38, 0x006c, 0x0800004c, 0x09, 0x00, 0x0000 }, + { 38, 0x006c, 0x0800004c, 0x0a, 0x00, 0x0000 }, + { 38, 0x006c, 0x0800004c, 0x0b, 0x00, 0x0000 }, + { 38, 0x006c, 0x0c00004c, 0x0c, 0x00, 0x0000 }, + { 38, 0x006c, 0x0c00004c, 0x0d, 0x00, 0x0000 }, + { 38, 0x006c, 0x0c00004c, 0x0e, 0x00, 0x0000 }, + { 38, 0x006c, 0x0c00004c, 0x0f, 0x00, 0x0000 }, + { 39, 0x003b, 0x0000003b, 0x00, 0x00, 0x0000 }, + { 39, 0x003a, 0x0000003a, 0x01, 0x00, 0x0000 }, + { 40, 0x0027, 0x00000027, 0x00, 0x00, 0x0000 }, + { 40, 0x0022, 0x00000022, 0x01, 0x00, 0x0000 }, + { 40, 0x0027, 0x01001251, 0x02, 0x01, 0x0000 }, + { 40, 0x0022, 0x01001257, 0x03, 0x01, 0x0000 }, + { 40, 0x0067, 0x04000047, 0x04, 0x00, 0x0000 }, + { 41, 0x0060, 0x00000060, 0x00, 0x00, 0x0000 }, + { 41, 0x007e, 0x0000007e, 0x01, 0x00, 0x0000 }, + { 41, 0x0060, 0x01001250, 0x02, 0x01, 0x0000 }, + { 41, 0x007e, 0x01001253, 0x03, 0x01, 0x0000 }, + { 42, 0xffff, 0x01000020, 0x00, 0x04, 0x0001 }, + { 43, 0x005c, 0x0000005c, 0x00, 0x00, 0x0000 }, + { 43, 0x007c, 0x0000007c, 0x01, 0x00, 0x0000 }, + { 43, 0x005c, 0x0400005c, 0x04, 0x00, 0x0000 }, + { 44, 0x007a, 0x0000005a, 0x00, 0x00, 0x0000 }, + { 44, 0x005a, 0x0000005a, 0x01, 0x00, 0x0000 }, + { 44, 0x007a, 0x0000005a, 0x02, 0x00, 0x0000 }, + { 44, 0x005a, 0x0000005a, 0x03, 0x00, 0x0000 }, + { 44, 0x007a, 0x0400005a, 0x04, 0x00, 0x0000 }, + { 44, 0x007a, 0x0400005a, 0x05, 0x00, 0x0000 }, + { 44, 0x007a, 0x0400005a, 0x06, 0x00, 0x0000 }, + { 44, 0x007a, 0x0400005a, 0x07, 0x00, 0x0000 }, + { 44, 0x007a, 0x0800005a, 0x08, 0x00, 0x0000 }, + { 44, 0x007a, 0x0800005a, 0x09, 0x00, 0x0000 }, + { 44, 0x007a, 0x0800005a, 0x0a, 0x00, 0x0000 }, + { 44, 0x007a, 0x0800005a, 0x0b, 0x00, 0x0000 }, + { 44, 0x007a, 0x0c00005a, 0x0c, 0x00, 0x0000 }, + { 44, 0x007a, 0x0c00005a, 0x0d, 0x00, 0x0000 }, + { 44, 0x007a, 0x0c00005a, 0x0e, 0x00, 0x0000 }, + { 44, 0x007a, 0x0c00005a, 0x0f, 0x00, 0x0000 }, + { 45, 0x0078, 0x00000058, 0x00, 0x00, 0x0000 }, + { 45, 0x0058, 0x00000058, 0x01, 0x00, 0x0000 }, + { 45, 0x0078, 0x00000058, 0x02, 0x00, 0x0000 }, + { 45, 0x0058, 0x00000058, 0x03, 0x00, 0x0000 }, + { 45, 0x0078, 0x04000058, 0x04, 0x00, 0x0000 }, + { 45, 0x0078, 0x04000058, 0x05, 0x00, 0x0000 }, + { 45, 0x0078, 0x04000058, 0x06, 0x00, 0x0000 }, + { 45, 0x0078, 0x04000058, 0x07, 0x00, 0x0000 }, + { 45, 0x0078, 0x08000058, 0x08, 0x00, 0x0000 }, + { 45, 0x0078, 0x08000058, 0x09, 0x00, 0x0000 }, + { 45, 0x0078, 0x08000058, 0x0a, 0x00, 0x0000 }, + { 45, 0x0078, 0x08000058, 0x0b, 0x00, 0x0000 }, + { 45, 0x0078, 0x0c000058, 0x0c, 0x00, 0x0000 }, + { 45, 0x0078, 0x0c000058, 0x0d, 0x00, 0x0000 }, + { 45, 0x0078, 0x0c000058, 0x0e, 0x00, 0x0000 }, + { 45, 0x0078, 0x0c000058, 0x0f, 0x00, 0x0000 }, + { 46, 0x0063, 0x00000043, 0x00, 0x00, 0x0000 }, + { 46, 0x0043, 0x00000043, 0x01, 0x00, 0x0000 }, + { 46, 0x0063, 0x00000043, 0x02, 0x00, 0x0000 }, + { 46, 0x0043, 0x00000043, 0x03, 0x00, 0x0000 }, + { 46, 0x0063, 0x04000043, 0x04, 0x00, 0x0000 }, + { 46, 0x0063, 0x04000043, 0x05, 0x00, 0x0000 }, + { 46, 0x0063, 0x04000043, 0x06, 0x00, 0x0000 }, + { 46, 0x0063, 0x04000043, 0x07, 0x00, 0x0000 }, + { 46, 0x0063, 0x08000043, 0x08, 0x00, 0x0000 }, + { 46, 0x0063, 0x08000043, 0x09, 0x00, 0x0000 }, + { 46, 0x0063, 0x08000043, 0x0a, 0x00, 0x0000 }, + { 46, 0x0063, 0x08000043, 0x0b, 0x00, 0x0000 }, + { 46, 0x0063, 0x0c000043, 0x0c, 0x00, 0x0000 }, + { 46, 0x0063, 0x0c000043, 0x0d, 0x00, 0x0000 }, + { 46, 0x0063, 0x0c000043, 0x0e, 0x00, 0x0000 }, + { 46, 0x0063, 0x0c000043, 0x0f, 0x00, 0x0000 }, + { 47, 0x0076, 0x00000056, 0x00, 0x00, 0x0000 }, + { 47, 0x0056, 0x00000056, 0x01, 0x00, 0x0000 }, + { 47, 0x0076, 0x00000056, 0x02, 0x00, 0x0000 }, + { 47, 0x0056, 0x00000056, 0x03, 0x00, 0x0000 }, + { 47, 0x0076, 0x04000056, 0x04, 0x00, 0x0000 }, + { 47, 0x0076, 0x04000056, 0x05, 0x00, 0x0000 }, + { 47, 0x0076, 0x04000056, 0x06, 0x00, 0x0000 }, + { 47, 0x0076, 0x04000056, 0x07, 0x00, 0x0000 }, + { 47, 0x0076, 0x08000056, 0x08, 0x00, 0x0000 }, + { 47, 0x0076, 0x08000056, 0x09, 0x00, 0x0000 }, + { 47, 0x0076, 0x08000056, 0x0a, 0x00, 0x0000 }, + { 47, 0x0076, 0x08000056, 0x0b, 0x00, 0x0000 }, + { 47, 0x0076, 0x0c000056, 0x0c, 0x00, 0x0000 }, + { 47, 0x0076, 0x0c000056, 0x0d, 0x00, 0x0000 }, + { 47, 0x0076, 0x0c000056, 0x0e, 0x00, 0x0000 }, + { 47, 0x0076, 0x0c000056, 0x0f, 0x00, 0x0000 }, + { 48, 0x0062, 0x00000042, 0x00, 0x00, 0x0000 }, + { 48, 0x0042, 0x00000042, 0x01, 0x00, 0x0000 }, + { 48, 0x0062, 0x00000042, 0x02, 0x00, 0x0000 }, + { 48, 0x0042, 0x00000042, 0x03, 0x00, 0x0000 }, + { 48, 0x0062, 0x04000042, 0x04, 0x00, 0x0000 }, + { 48, 0x0062, 0x04000042, 0x05, 0x00, 0x0000 }, + { 48, 0x0062, 0x04000042, 0x06, 0x00, 0x0000 }, + { 48, 0x0062, 0x04000042, 0x07, 0x00, 0x0000 }, + { 48, 0x0062, 0x08000042, 0x08, 0x00, 0x0000 }, + { 48, 0x0062, 0x08000042, 0x09, 0x00, 0x0000 }, + { 48, 0x0062, 0x08000042, 0x0a, 0x00, 0x0000 }, + { 48, 0x0062, 0x08000042, 0x0b, 0x00, 0x0000 }, + { 48, 0x0062, 0x0c000042, 0x0c, 0x00, 0x0000 }, + { 48, 0x0062, 0x0c000042, 0x0d, 0x00, 0x0000 }, + { 48, 0x0062, 0x0c000042, 0x0e, 0x00, 0x0000 }, + { 48, 0x0062, 0x0c000042, 0x0f, 0x00, 0x0000 }, + { 49, 0x006e, 0x0000004e, 0x00, 0x00, 0x0000 }, + { 49, 0x004e, 0x0000004e, 0x01, 0x00, 0x0000 }, + { 49, 0x006e, 0x0000004e, 0x02, 0x00, 0x0000 }, + { 49, 0x004e, 0x0000004e, 0x03, 0x00, 0x0000 }, + { 49, 0x006e, 0x0400004e, 0x04, 0x00, 0x0000 }, + { 49, 0x006e, 0x0400004e, 0x05, 0x00, 0x0000 }, + { 49, 0x006e, 0x0400004e, 0x06, 0x00, 0x0000 }, + { 49, 0x006e, 0x0400004e, 0x07, 0x00, 0x0000 }, + { 49, 0x006e, 0x0800004e, 0x08, 0x00, 0x0000 }, + { 49, 0x006e, 0x0800004e, 0x09, 0x00, 0x0000 }, + { 49, 0x006e, 0x0800004e, 0x0a, 0x00, 0x0000 }, + { 49, 0x006e, 0x0800004e, 0x0b, 0x00, 0x0000 }, + { 49, 0x006e, 0x0c00004e, 0x0c, 0x00, 0x0000 }, + { 49, 0x006e, 0x0c00004e, 0x0d, 0x00, 0x0000 }, + { 49, 0x006e, 0x0c00004e, 0x0e, 0x00, 0x0000 }, + { 49, 0x006e, 0x0c00004e, 0x0f, 0x00, 0x0000 }, + { 50, 0x006d, 0x0000004d, 0x00, 0x00, 0x0000 }, + { 50, 0x004d, 0x0000004d, 0x01, 0x00, 0x0000 }, + { 50, 0x006d, 0x0000004d, 0x02, 0x00, 0x0000 }, + { 50, 0x004d, 0x0000004d, 0x03, 0x00, 0x0000 }, + { 50, 0x006d, 0x0400004d, 0x04, 0x00, 0x0000 }, + { 50, 0x006d, 0x0400004d, 0x05, 0x00, 0x0000 }, + { 50, 0x006d, 0x0400004d, 0x06, 0x00, 0x0000 }, + { 50, 0x006d, 0x0400004d, 0x07, 0x00, 0x0000 }, + { 50, 0x006d, 0x0800004d, 0x08, 0x00, 0x0000 }, + { 50, 0x006d, 0x0800004d, 0x09, 0x00, 0x0000 }, + { 50, 0x006d, 0x0800004d, 0x0a, 0x00, 0x0000 }, + { 50, 0x006d, 0x0800004d, 0x0b, 0x00, 0x0000 }, + { 50, 0x006d, 0x0c00004d, 0x0c, 0x00, 0x0000 }, + { 50, 0x006d, 0x0c00004d, 0x0d, 0x00, 0x0000 }, + { 50, 0x006d, 0x0c00004d, 0x0e, 0x00, 0x0000 }, + { 50, 0x006d, 0x0c00004d, 0x0f, 0x00, 0x0000 }, + { 51, 0x002c, 0x0000002c, 0x00, 0x00, 0x0000 }, + { 51, 0x003c, 0x0000003c, 0x01, 0x00, 0x0000 }, + { 51, 0x002c, 0x0100125b, 0x02, 0x01, 0x0000 }, + { 52, 0x002e, 0x0000002e, 0x00, 0x00, 0x0000 }, + { 52, 0x003e, 0x0000003e, 0x01, 0x00, 0x0000 }, + { 52, 0xffff, 0x01001120, 0x02, 0x00, 0x0000 }, + { 53, 0x002f, 0x0000002f, 0x00, 0x00, 0x0000 }, + { 53, 0x003f, 0x0000003f, 0x01, 0x00, 0x0000 }, + { 53, 0xffff, 0x01000003, 0x04, 0x00, 0x0000 }, + { 54, 0xffff, 0x01000020, 0x00, 0x04, 0x0001 }, + { 55, 0x002a, 0x2000002a, 0x00, 0x00, 0x0000 }, + { 56, 0xffff, 0x01000023, 0x00, 0x04, 0x0008 }, + { 57, 0x0020, 0x00000020, 0x00, 0x00, 0x0000 }, + { 58, 0xffff, 0x01000024, 0x00, 0x00, 0x0000 }, + { 59, 0xffff, 0x01000030, 0x00, 0x00, 0x0000 }, + { 59, 0xffff, 0x0100003c, 0x01, 0x00, 0x0000 }, + { 59, 0xffff, 0x01000048, 0x04, 0x00, 0x0000 }, + { 59, 0xffff, 0x01000000, 0x0c, 0x08, 0x0100 }, + { 60, 0xffff, 0x01000031, 0x00, 0x00, 0x0000 }, + { 60, 0xffff, 0x0100003d, 0x01, 0x00, 0x0000 }, + { 60, 0xffff, 0x01000049, 0x04, 0x00, 0x0000 }, + { 60, 0xffff, 0x01000000, 0x0c, 0x08, 0x0101 }, + { 61, 0xffff, 0x01000032, 0x00, 0x00, 0x0000 }, + { 61, 0xffff, 0x0100003e, 0x01, 0x00, 0x0000 }, + { 61, 0xffff, 0x0100004a, 0x04, 0x00, 0x0000 }, + { 61, 0xffff, 0x01000000, 0x0c, 0x08, 0x0102 }, + { 62, 0xffff, 0x01000033, 0x00, 0x00, 0x0000 }, + { 62, 0xffff, 0x0100003f, 0x01, 0x00, 0x0000 }, + { 62, 0xffff, 0x0100004b, 0x04, 0x00, 0x0000 }, + { 62, 0xffff, 0x01000000, 0x0c, 0x08, 0x0103 }, + { 63, 0xffff, 0x01000034, 0x00, 0x00, 0x0000 }, + { 63, 0xffff, 0x01000040, 0x01, 0x00, 0x0000 }, + { 63, 0xffff, 0x0100004c, 0x04, 0x00, 0x0000 }, + { 63, 0xffff, 0x01000000, 0x0c, 0x08, 0x0104 }, + { 64, 0xffff, 0x01000035, 0x00, 0x00, 0x0000 }, + { 64, 0xffff, 0x01000041, 0x01, 0x00, 0x0000 }, + { 64, 0xffff, 0x0100004d, 0x04, 0x00, 0x0000 }, + { 64, 0xffff, 0x01000000, 0x0c, 0x08, 0x0105 }, + { 65, 0xffff, 0x01000036, 0x00, 0x00, 0x0000 }, + { 65, 0xffff, 0x01000042, 0x01, 0x00, 0x0000 }, + { 65, 0xffff, 0x0100004e, 0x04, 0x00, 0x0000 }, + { 65, 0xffff, 0x01000000, 0x0c, 0x08, 0x0106 }, + { 66, 0xffff, 0x01000037, 0x00, 0x00, 0x0000 }, + { 66, 0xffff, 0x01000043, 0x01, 0x00, 0x0000 }, + { 66, 0xffff, 0x0100004f, 0x04, 0x00, 0x0000 }, + { 66, 0xffff, 0x01000000, 0x0c, 0x08, 0x0107 }, + { 67, 0xffff, 0x01000038, 0x00, 0x00, 0x0000 }, + { 67, 0xffff, 0x01000044, 0x01, 0x00, 0x0000 }, + { 67, 0xffff, 0x01000050, 0x04, 0x00, 0x0000 }, + { 67, 0xffff, 0x01000000, 0x0c, 0x08, 0x0108 }, + { 68, 0xffff, 0x01000039, 0x00, 0x00, 0x0000 }, + { 68, 0xffff, 0x01000045, 0x01, 0x00, 0x0000 }, + { 68, 0xffff, 0x01000051, 0x04, 0x00, 0x0000 }, + { 68, 0xffff, 0x01000000, 0x0c, 0x08, 0x0109 }, + { 69, 0xffff, 0x01000025, 0x00, 0x00, 0x0000 }, + { 70, 0xffff, 0x01000026, 0x00, 0x00, 0x0000 }, + { 70, 0xffff, 0x01000026, 0x08, 0x00, 0x0000 }, + { 71, 0x0037, 0x20000037, 0x00, 0x00, 0x0000 }, + { 72, 0x0038, 0x20000038, 0x00, 0x00, 0x0000 }, + { 73, 0x0039, 0x20000039, 0x00, 0x00, 0x0000 }, + { 74, 0x002d, 0x2000002d, 0x00, 0x00, 0x0000 }, + { 75, 0x0034, 0x20000034, 0x00, 0x00, 0x0000 }, + { 76, 0x0035, 0x20000035, 0x00, 0x00, 0x0000 }, + { 77, 0x0036, 0x20000036, 0x00, 0x00, 0x0000 }, + { 78, 0x002b, 0x2000002b, 0x00, 0x00, 0x0000 }, + { 79, 0x0031, 0x20000031, 0x00, 0x00, 0x0000 }, + { 80, 0x0032, 0x20000032, 0x00, 0x00, 0x0000 }, + { 81, 0x0033, 0x20000033, 0x00, 0x00, 0x0000 }, + { 82, 0x0030, 0x20000030, 0x00, 0x00, 0x0000 }, + { 83, 0x002e, 0x2000002e, 0x00, 0x00, 0x0000 }, + { 83, 0xffff, 0x01000000, 0x06, 0x08, 0x0200 }, + { 83, 0xffff, 0x01000000, 0x0c, 0x08, 0x0200 }, + { 86, 0x003c, 0x0000003c, 0x00, 0x00, 0x0000 }, + { 86, 0x003e, 0x0000003e, 0x01, 0x00, 0x0000 }, + { 86, 0x007c, 0x0000007c, 0x02, 0x00, 0x0000 }, + { 87, 0xffff, 0x0100003a, 0x00, 0x00, 0x0000 }, + { 87, 0xffff, 0x01000046, 0x01, 0x00, 0x0000 }, + { 87, 0xffff, 0x01000052, 0x04, 0x00, 0x0000 }, + { 87, 0xffff, 0x01000000, 0x0c, 0x08, 0x010a }, + { 88, 0xffff, 0x0100003b, 0x00, 0x00, 0x0000 }, + { 88, 0xffff, 0x01000047, 0x01, 0x00, 0x0000 }, + { 88, 0xffff, 0x01000000, 0x0c, 0x08, 0x010b }, + { 96, 0xffff, 0x21000005, 0x00, 0x00, 0x0000 }, + { 97, 0xffff, 0x01000021, 0x00, 0x04, 0x0004 }, + { 98, 0x002f, 0x2000002f, 0x00, 0x00, 0x0000 }, + { 99, 0x005c, 0x0400005c, 0x00, 0x00, 0x0000 }, + { 100, 0xffff, 0x01001103, 0x00, 0x04, 0x0002 }, + { 102, 0xffff, 0x01000010, 0x00, 0x00, 0x0000 }, + { 103, 0xffff, 0x01000013, 0x00, 0x00, 0x0000 }, + { 104, 0xffff, 0x01000016, 0x00, 0x00, 0x0000 }, + { 105, 0xffff, 0x01000012, 0x00, 0x00, 0x0000 }, + { 105, 0xffff, 0x01000000, 0x0c, 0x08, 0x0180 }, + { 106, 0xffff, 0x01000014, 0x00, 0x00, 0x0000 }, + { 106, 0xffff, 0x01000000, 0x0c, 0x08, 0x0181 }, + { 107, 0xffff, 0x01000011, 0x00, 0x00, 0x0000 }, + { 108, 0xffff, 0x01000015, 0x00, 0x00, 0x0000 }, + { 109, 0xffff, 0x01000017, 0x00, 0x00, 0x0000 }, + { 110, 0xffff, 0x01000006, 0x00, 0x00, 0x0000 }, + { 111, 0xffff, 0x01000007, 0x00, 0x00, 0x0000 }, + { 111, 0xffff, 0x01000000, 0x06, 0x08, 0x0200 }, + { 111, 0xffff, 0x01000000, 0x0c, 0x08, 0x0200 }, + { 119, 0xffff, 0x01000008, 0x00, 0x00, 0x0000 }, +}; + +const QWSKeyboard::Composing QWSKbPrivate::s_keycompose_default[] = { + { 0x0060, 0x0041, 0x00c0 }, + { 0x0060, 0x0061, 0x00e0 }, + { 0x0027, 0x0041, 0x00c1 }, + { 0x0027, 0x0061, 0x00e1 }, + { 0x005e, 0x0041, 0x00c2 }, + { 0x005e, 0x0061, 0x00e2 }, + { 0x007e, 0x0041, 0x00c3 }, + { 0x007e, 0x0061, 0x00e3 }, + { 0x0022, 0x0041, 0x00c4 }, + { 0x0022, 0x0061, 0x00e4 }, + { 0x002d, 0x0061, 0x00aa }, + { 0x002d, 0x0041, 0x00aa }, + { 0x004f, 0x0041, 0x00c5 }, + { 0x006f, 0x0061, 0x00e5 }, + { 0x0030, 0x0041, 0x00c5 }, + { 0x0030, 0x0061, 0x00e5 }, + { 0x0041, 0x0041, 0x00c5 }, + { 0x0061, 0x0061, 0x00e5 }, + { 0x00b0, 0x0041, 0x00c5 }, + { 0x00b0, 0x0061, 0x00e5 }, + { 0x0041, 0x0045, 0x00c6 }, + { 0x0061, 0x0065, 0x00e6 }, + { 0x002c, 0x0043, 0x00c7 }, + { 0x002c, 0x0063, 0x00e7 }, + { 0x005e, 0x0043, 0x00c7 }, + { 0x005e, 0x0063, 0x00e7 }, + { 0x0060, 0x0045, 0x00c8 }, + { 0x0060, 0x0065, 0x00e8 }, + { 0x0027, 0x0045, 0x00c9 }, + { 0x0027, 0x0065, 0x00e9 }, + { 0x005e, 0x0045, 0x00ca }, + { 0x005e, 0x0065, 0x00ea }, + { 0x0022, 0x0045, 0x00cb }, + { 0x0022, 0x0065, 0x00eb }, + { 0x0060, 0x0049, 0x00cc }, + { 0x0060, 0x0069, 0x00ec }, + { 0x0027, 0x0049, 0x00cd }, + { 0x0027, 0x0069, 0x00ed }, + { 0x005e, 0x0049, 0x00ce }, + { 0x005e, 0x0069, 0x00ee }, + { 0x0022, 0x0049, 0x00cf }, + { 0x0022, 0x0069, 0x00ef }, + { 0x002d, 0x0044, 0x00d0 }, + { 0x002d, 0x0064, 0x00f0 }, + { 0x005e, 0x0044, 0x00d0 }, + { 0x005e, 0x0064, 0x00f0 }, + { 0x007e, 0x004e, 0x00d1 }, + { 0x007e, 0x006e, 0x00f1 }, + { 0x005e, 0x004e, 0x00d1 }, + { 0x005e, 0x006e, 0x00f1 }, + { 0x0060, 0x004f, 0x00d2 }, + { 0x0060, 0x006f, 0x00f2 }, + { 0x0027, 0x004f, 0x00d3 }, + { 0x0027, 0x006f, 0x00f3 }, + { 0x005e, 0x004f, 0x00d4 }, + { 0x005e, 0x006f, 0x00f4 }, + { 0x007e, 0x004f, 0x00d5 }, + { 0x007e, 0x006f, 0x00f5 }, + { 0x0022, 0x004f, 0x00d6 }, + { 0x0022, 0x006f, 0x00f6 }, + { 0x002f, 0x004f, 0x00d8 }, + { 0x002f, 0x006f, 0x00f8 }, + { 0x002d, 0x006f, 0x00ba }, + { 0x002d, 0x004f, 0x00ba }, + { 0x0060, 0x0055, 0x00d9 }, + { 0x0060, 0x0075, 0x00f9 }, + { 0x0027, 0x0055, 0x00da }, + { 0x0027, 0x0075, 0x00fa }, + { 0x005e, 0x0055, 0x00db }, + { 0x005e, 0x0075, 0x00fb }, + { 0x0022, 0x0055, 0x00dc }, + { 0x0022, 0x0075, 0x00fc }, + { 0x0027, 0x0059, 0x00dd }, + { 0x0027, 0x0079, 0x00fd }, + { 0x0054, 0x0048, 0x00de }, + { 0x0074, 0x0068, 0x00fe }, + { 0x0073, 0x0073, 0x00df }, + { 0x0022, 0x0079, 0x00ff }, + { 0x0073, 0x007a, 0x00df }, + { 0x006e, 0x006e, 0x00f1 }, + { 0x006e, 0x0068, 0x00f1 }, + { 0x004e, 0x0059, 0x00d1 }, + { 0x004e, 0x004e, 0x00d1 }, + { 0x004e, 0x0048, 0x00d1 }, + { 0x004e, 0x0079, 0x00d1 }, + { 0x004e, 0x006e, 0x00d1 }, + { 0x004e, 0x0068, 0x00d1 }, + { 0x002d, 0x004c, 0x00a3 }, + { 0x003c, 0x003c, 0x00ab }, + { 0x003e, 0x003e, 0x00bb }, + { 0x003f, 0x003f, 0x00bf }, + { 0x005e, 0x003f, 0x00bf }, + { 0x0021, 0x0021, 0x00a1 }, + { 0x005e, 0x0021, 0x00a1 }, + { 0x005e, 0x0031, 0x00b9 }, + { 0x005e, 0x0032, 0x00b2 }, + { 0x005e, 0x0033, 0x00b3 }, + { 0x002b, 0x002d, 0x00b1 }, + { 0x0063, 0x003d, 0x00a2 }, + { 0x0063, 0x002f, 0x00a2 }, + { 0x002f, 0x0063, 0x00a2 }, + { 0x002d, 0x0063, 0x00a2 }, + { 0x002d, 0x0043, 0x00a2 }, + { 0x004c, 0x003d, 0x00a3 }, + { 0x002d, 0x004c, 0x00a3 }, + { 0x002d, 0x006c, 0x00a3 }, + { 0x005e, 0x002a, 0x00d7 }, + { 0x005e, 0x0078, 0x00d7 }, + { 0x0078, 0x0078, 0x00d7 }, + { 0x005e, 0x002e, 0x00b7 }, + { 0x002e, 0x002e, 0x00b7 }, + { 0x005e, 0x002f, 0x00f7 }, + { 0x005e, 0x003a, 0x00f7 }, + { 0x002d, 0x003a, 0x00f7 }, + { 0x003a, 0x002d, 0x00f7 }, + { 0x0059, 0x003d, 0x00a5 }, + { 0x002d, 0x0059, 0x00a5 }, + { 0x002d, 0x006c, 0x00a5 }, + { 0x0028, 0x0063, 0x00a9 }, + { 0x0022, 0x0063, 0x00a9 }, + { 0x002d, 0x0061, 0x00aa }, + { 0x002d, 0x0041, 0x00aa }, + { 0x002d, 0x006f, 0x00ba }, + { 0x002d, 0x004f, 0x00ba }, + { 0x0028, 0x0072, 0x00ae }, + { 0x0022, 0x0072, 0x00ae }, + { 0x006d, 0x0075, 0x00b5 }, + { 0x0031, 0x0034, 0x0152 }, + { 0x0031, 0x0032, 0x0153 }, + { 0x0033, 0x0034, 0x0178 }, + { 0x0065, 0x003d, 0x20ac }, + { 0x002d, 0x0065, 0x20ac }, + { 0x002d, 0x0045, 0x20ac }, + { 0x0076, 0x0053, 0x0160 }, + { 0x005e, 0x0053, 0x0160 }, + { 0x0076, 0x0073, 0x0161 }, + { 0x005e, 0x0073, 0x0161 }, + { 0x0076, 0x005a, 0x017d }, + { 0x005e, 0x005a, 0x017d }, + { 0x0076, 0x007a, 0x017e }, + { 0x005e, 0x007a, 0x017e }, + { 0x004f, 0x0045, 0x0152 }, + { 0x004f, 0x0065, 0x0152 }, + { 0x006f, 0x0065, 0x0153 }, + { 0x0022, 0x0059, 0x0178 }, + { 0x0069, 0x006a, 0x00ff }, + { 0x0049, 0x004a, 0x0178 }, +}; + +#endif diff --git a/src/gui/embedded/qkbd_qws.cpp b/src/gui/embedded/qkbd_qws.cpp index 8cf87db..120d2a1 100644 --- a/src/gui/embedded/qkbd_qws.cpp +++ b/src/gui/embedded/qkbd_qws.cpp @@ -40,56 +40,216 @@ ****************************************************************************/ #include "qkbd_qws.h" +#include "qkbd_qws_p.h" #ifndef QT_NO_QWS_KEYBOARD +#include <QFile> +#include <QDataStream> + #include "qwindowsystem_qws.h" #include "qscreen_qws.h" #include "qtimer.h" #include <stdlib.h> +//#define QT_DEBUG_KEYMAP + + QT_BEGIN_NAMESPACE class QWSKbPrivate : public QObject { Q_OBJECT public: - QWSKbPrivate(QWSKeyboardHandler *h) { - handler = h; - arTimer = new QTimer(this); - arTimer->setSingleShot(true); - connect(arTimer, SIGNAL(timeout()), SLOT(autoRepeat())); - repeatdelay = 400; - repeatperiod = 80; + QWSKbPrivate(QWSKeyboardHandler *h, const QString &device) + : m_handler(h), m_modifiers(0), m_composing(0), m_dead_unicode(0xffff), + m_no_zap(false), m_do_compose(false), + m_keymap(0), m_keymap_size(0), m_keycompose(0), m_keycompose_size(0) + { + m_ar_timer = new QTimer(this); + m_ar_timer->setSingleShot(true); + connect(m_ar_timer, SIGNAL(timeout()), SLOT(autoRepeat())); + m_ar_delay = 400; + m_ar_period = 80; + + memset(m_locks, 0, sizeof(m_locks)); + + QString keymap; + QStringList args = device.split(QLatin1Char(':')); + foreach (const QString &arg, args) { + if (arg.startsWith(QLatin1String("keymap="))) + keymap = arg.mid(7); + else if (arg == QLatin1String("disable-zap")) + m_no_zap = true; + else if (arg == QLatin1String("enable-compose")) + m_do_compose = true; + else if (arg.startsWith(QLatin1String("repeat-delay="))) + m_ar_delay = arg.mid(13).toInt(); + else if (arg.startsWith(QLatin1String("repeat-rate="))) + m_ar_period = arg.mid(12).toInt(); + } + + if (keymap.isEmpty() || !loadKeymap(keymap)) + unloadKeymap(); } - void beginAutoRepeat(int uni, int code, Qt::KeyboardModifiers mod) { - unicode = uni; - keycode = code; - modifier = mod; - arTimer->start(repeatdelay); + ~QWSKbPrivate() + { + unloadKeymap(); } - void endAutoRepeat() { - arTimer->stop(); + + void beginAutoRepeat(int uni, int code, Qt::KeyboardModifiers mod) + { + m_ar_unicode = uni; + m_ar_keycode = code; + m_ar_modifier = mod; + m_ar_timer->start(m_ar_delay); } + void endAutoRepeat() + { + m_ar_timer->stop(); + } + + static Qt::KeyboardModifiers toQtModifiers(quint8 mod) + { + Qt::KeyboardModifiers qtmod = Qt::NoModifier; + + if (mod & (QWSKeyboard::ModShift | QWSKeyboard::ModShiftL | QWSKeyboard::ModShiftR)) + qtmod |= Qt::ShiftModifier; + if (mod & (QWSKeyboard::ModControl | QWSKeyboard::ModCtrlL | QWSKeyboard::ModCtrlR)) + qtmod |= Qt::ControlModifier; + if (mod & QWSKeyboard::ModAlt) + qtmod |= Qt::AltModifier; + + return qtmod; + } + + void unloadKeymap(); + bool loadKeymap(const QString &file); + private slots: - void autoRepeat() { - handler->processKeyEvent(unicode, keycode, modifier, false, true); - handler->processKeyEvent(unicode, keycode, modifier, true, true); - arTimer->start(repeatperiod); + void autoRepeat() + { + m_handler->processKeyEvent(m_ar_unicode, m_ar_keycode, m_ar_modifier, false, true); + m_handler->processKeyEvent(m_ar_unicode, m_ar_keycode, m_ar_modifier, true, true); + m_ar_timer->start(m_ar_period); } private: - QWSKeyboardHandler *handler; - int unicode; - int keycode; - Qt::KeyboardModifiers modifier; - int repeatdelay; - int repeatperiod; - QTimer *arTimer; + QWSKeyboardHandler *m_handler; + + // auto repeat simulation + int m_ar_unicode; + int m_ar_keycode; + Qt::KeyboardModifiers m_ar_modifier; + int m_ar_delay; + int m_ar_period; + QTimer *m_ar_timer; + + // keymap handling + quint8 m_modifiers; + quint8 m_locks[3]; + int m_composing; + quint16 m_dead_unicode; + + bool m_no_zap; + bool m_do_compose; + + const QWSKeyboard::Mapping *m_keymap; + int m_keymap_size; + const QWSKeyboard::Composing *m_keycompose; + int m_keycompose_size; + + static const QWSKeyboard::Mapping s_keymap_default[]; + static const QWSKeyboard::Composing s_keycompose_default[]; + + friend class QWSKeyboardHandler; }; +// simple builtin US keymap +#include "qkbd_defaultmap_qws_p.h" + +// the unloadKeymap() function needs to be AFTER the defaultmap include, +// since the sizeof(s_keymap_default) wouldn't work otherwise. + +void QWSKbPrivate::unloadKeymap() +{ + if (m_keymap && m_keymap != s_keymap_default) + delete [] m_keymap; + if (m_keycompose && m_keycompose != s_keycompose_default) + delete [] m_keycompose; + + m_keymap = s_keymap_default; + m_keymap_size = sizeof(s_keymap_default) / sizeof(s_keymap_default[0]); + m_keycompose = s_keycompose_default; + m_keycompose_size = sizeof(s_keycompose_default) / sizeof(s_keycompose_default[0]); + + // reset state, so we could switch keymaps at runtime + m_modifiers = 0; + memset(m_locks, 0, sizeof(m_locks)); + m_composing = 0; + m_dead_unicode = 0xffff; +} + +bool QWSKbPrivate::loadKeymap(const QString &file) +{ + QFile f(file); + + if (!f.open(QIODevice::ReadOnly)) { + qWarning("Could not open keymap file '%s'", qPrintable(file)); + return false; + } + + // .qmap files have a very simple structure: + // quint32 magic (QWSKeyboard::FileMagic) + // quint32 version (1) + // quint32 keymap_size (# of struct QWSKeyboard::Mappings) + // quint32 keycompose_size (# of struct QWSKeyboard::Composings) + // all QWSKeyboard::Mappings via QDataStream::operator(<<|>>) + // all QWSKeyboard::Composings via QDataStream::operator(<<|>>) + + quint32 qmap_magic, qmap_version, qmap_keymap_size, qmap_keycompose_size; + + QDataStream ds(&f); + + ds >> qmap_magic >> qmap_version >> qmap_keymap_size >> qmap_keycompose_size; + + if (ds.status() != QDataStream::Ok || qmap_magic != QWSKeyboard::FileMagic || qmap_version != 1 || qmap_keymap_size == 0) { + qWarning("'%s' is ot a valid.qmap keymap file.", qPrintable(file)); + return false; + } + + QWSKeyboard::Mapping *qmap_keymap = new QWSKeyboard::Mapping[qmap_keymap_size]; + QWSKeyboard::Composing *qmap_keycompose = qmap_keycompose_size ? new QWSKeyboard::Composing[qmap_keycompose_size] : 0; + + for (quint32 i = 0; i < qmap_keymap_size; ++i) + ds >> qmap_keymap[i]; + for (quint32 i = 0; i < qmap_keycompose_size; ++i) + ds >> qmap_keycompose[i]; + + if (ds.status() != QDataStream::Ok) { + delete [] qmap_keymap; + delete [] qmap_keycompose; + + qWarning("Keymap file '%s' can not be loaded.", qPrintable(file)); + return false; + } + + // unload currently active and clear state + unloadKeymap(); + + m_keymap = qmap_keymap; + m_keymap_size = qmap_keymap_size; + m_keycompose = qmap_keycompose; + m_keycompose_size = qmap_keycompose_size; + + m_do_compose = true; + + return true; +} + + /*! \class QWSKeyboardHandler \ingroup qws @@ -132,18 +292,29 @@ private: /*! - Constructs a keyboard driver. + Constructs a keyboard driver. The \a device argument is passed by the + QWS_KEYBOARD environment variable. Call the QWSServer::setKeyboardHandler() function to make the newly created keyboard driver, the primary driver. Note that the primary driver is controlled by the system, i.e., the system will delete it upon exit. */ +QWSKeyboardHandler::QWSKeyboardHandler(const QString &device) +{ + d = new QWSKbPrivate(this, device); +} + +/*! + \overload +*/ QWSKeyboardHandler::QWSKeyboardHandler() { - d = new QWSKbPrivate(this); + d = new QWSKbPrivate(this, QString()); } + + /*! Destroys this keyboard driver. @@ -172,7 +343,10 @@ QWSKeyboardHandler::~QWSKeyboardHandler() event is caused by an auto-repeat mechanism and not an actual key press. - \sa beginAutoRepeat(), endAutoRepeat(), transformDirKey() + Note that this function does not handle key mapping. Please use + processKeycode() if you need that functionality. + + \sa processKeycode(), beginAutoRepeat(), endAutoRepeat(), transformDirKey() */ void QWSKeyboardHandler::processKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat) @@ -241,6 +415,256 @@ void QWSKeyboardHandler::endAutoRepeat() d->endAutoRepeat(); } +/*! + \enum QWSKeyboardHandler::KeycodeAction + + This enum describes the various special actions that actual + QWSKeyboardHandler implementations have to take care of. + + \value None No further action required. + + \value CapsLockOn Set the state of the Caps lock LED to on. + \value CapsLockOff Set the state of the Caps lock LED to off. + \value NumLockOn Set the state of the Num lock LED to on. + \value NumLockOff Set the state of the Num lock LED to off. + \value ScrollLockOn Set the state of the Scroll lock LED to on. + \value ScrollLockOff Set the state of the Scroll lock LED to off. + + \value PreviousConsole Switch to the previous virtual console (by + default Ctrl+Alt+Left on Linux). + \value NextConsole Switch to the next virtual console (by default + Ctrl+Alt+Right on Linux). + \value SwitchConsoleFirst Switch to the first virtual console (0). + \value SwitchConsoleLast Switch to the last virtual console (255). + \value SwitchConsoleMask If the KeyAction value is between SwitchConsoleFirst + and SwitchConsoleLast, you can use this mask to get + the specific virtual console number to switch to. + + \value Reboot Reboot the machine - this is ignored in both the TTY and + LinuxInput handlers though (by default Ctrl+Alt+Del on Linux). + + \sa processKeycode() +*/ + +/*! + \fn QWSKeyboardHandler::KeycodeAction QWSKeyboardHandler::processKeycode(quint16 keycode, bool isPress, bool autoRepeat) + + Maps \a keycode according to a keymap and sends that key event to the + \l{Qt for Embedded Linux} server application. + + Please see the QWS_KEYBOARD documentation for a description on how to + create and use keymap files. + + The key event is identified by its \a keycode value and the \a isPress + and \a autoRepeat parameters. + + The \a keycode parameter is \bold NOT the Qt keycode value as defined by + the Qt::Key enum. This functions expects a standard Linux 16 bit kernel + keycode as it is used in the Linux Input Event sub-system. This + \a keycode is transformed to a Qt::Key code by using either a + compiled-in US keyboard layout or by dynamically loading a keymap at + startup which can be specified via the QWS_KEYBOARD environment + variable. + + The \a isPress parameter is true if the event is a key press event and + \a autoRepeat is true if the event is caused by an auto-repeat mechanism + and not an actual key press. + + The return value indicates if the actual QWSKeyboardHandler + implementation needs to take care of a special action, like console + switching or LED handling. + + Standard Linux console keymaps can be found at the + \l {http://lct.sourceforege.net}{LCT project} + + If standard Linux console keymaps are used, \a keycode must be one of the + standardized values defined in \c /usr/include/linux/input.h + + \sa processKeyEvent(), KeycodeAction +*/ + +QWSKeyboardHandler::KeycodeAction QWSKeyboardHandler::processKeycode(quint16 keycode, bool pressed, bool autorepeat) +{ + KeycodeAction result = None; + bool first_press = pressed && !autorepeat; + + const QWSKeyboard::Mapping *map_plain = 0; + const QWSKeyboard::Mapping *map_withmod = 0; + + // get a specific and plain mapping for the keycode and the current modifiers + for (int i = 0; i < d->m_keymap_size && !(map_plain && map_withmod); ++i) { + const QWSKeyboard::Mapping *m = d->m_keymap + i; + if (m->keycode == keycode) { + if (m->modifiers == 0) + map_plain = m; + + quint8 testmods = d->m_modifiers; + if (d->m_locks[0] /*CapsLock*/ && (m->flags & QWSKeyboard::IsLetter)) + testmods ^= QWSKeyboard::ModShift; + if (m->modifiers == testmods) + map_withmod = m; + } + } + +#ifdef QT_DEBUG_KEYMAP + qWarning("Processing key event: keycode=%3d, modifiers=%02x pressed=%d, autorepeat=%d | plain=%d, withmod=%d, size=%d", \ + keycode, d->m_modifiers, pressed ? 1 : 0, autorepeat ? 1 : 0, \ + map_plain ? map_plain - d->m_keymap : -1, \ + map_withmod ? map_withmod - d->m_keymap : -1, \ + d->m_keymap_size); +#endif + + const QWSKeyboard::Mapping *it = map_withmod ? map_withmod : map_plain; + + if (!it) { +#ifdef QT_DEBUG_KEYMAP + // we couldn't even find a plain mapping + qWarning("Could not find a suitable mapping for keycode: %3d, modifiers: %02x", keycode, d->m_modifiers); +#endif + return result; + } + + bool skip = false; + quint16 unicode = it->unicode; + quint32 qtcode = it->qtcode; + + if ((it->flags & QWSKeyboard::IsModifier) && it->special) { + // this is a modifier, i.e. Shift, Alt, ... + if (pressed) + d->m_modifiers |= quint8(it->special); + else + d->m_modifiers &= ~quint8(it->special); + } else if (qtcode >= Qt::Key_CapsLock && qtcode <= Qt::Key_ScrollLock) { + // (Caps|Num|Scroll)Lock + if (first_press) { + quint8 &lock = d->m_locks[qtcode - Qt::Key_CapsLock]; + lock ^= 1; + + switch (qtcode) { + case Qt::Key_CapsLock : result = lock ? CapsLockOn : CapsLockOff; break; + case Qt::Key_NumLock : result = lock ? NumLockOn : NumLockOff; break; + case Qt::Key_ScrollLock: result = lock ? ScrollLockOn : ScrollLockOff; break; + default : break; + } + } + } else if ((it->flags & QWSKeyboard::IsSystem) && it->special && first_press) { + switch (it->special) { + case QWSKeyboard::SystemReboot: + result = Reboot; + break; + + case QWSKeyboard::SystemZap: + if (!d->m_no_zap) + qApp->quit(); + break; + + case QWSKeyboard::SystemConsolePrevious: + result = PreviousConsole; + break; + + case QWSKeyboard::SystemConsoleNext: + result = NextConsole; + break; + + default: + if (it->special >= QWSKeyboard::SystemConsoleFirst && + it->special <= QWSKeyboard::SystemConsoleLast) { + result = KeycodeAction(SwitchConsoleFirst + ((it->special & QWSKeyboard::SystemConsoleMask) & SwitchConsoleMask)); + } + break; + } + + skip = true; // no need to tell QWS about it + } else if ((qtcode == Qt::Key_Multi_key) && d->m_do_compose) { + // the Compose key was pressed + if (first_press) + d->m_composing = 2; + skip = true; + } else if ((it->flags & QWSKeyboard::IsDead) && d->m_do_compose) { + // a Dead key was pressed + if (first_press && d->m_composing == 1 && d->m_dead_unicode == unicode) { // twice + d->m_composing = 0; + qtcode = Qt::Key_unknown; // otherwise it would be Qt::Key_Dead... + } else if (first_press && unicode != 0xffff) { + d->m_dead_unicode = unicode; + d->m_composing = 1; + skip = true; + } else { + skip = true; + } + } + + if (!skip) { + // a normal key was pressed + const int modmask = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier; + + // we couldn't find a specific mapping for the current modifiers, + // or that mapping didn't have special modifiers: + // so just report the plain mapping with additional modifiers. + if ((it == map_plain && it != map_withmod) || + (map_withmod && !(map_withmod->qtcode & modmask))) { + qtcode |= QWSKbPrivate::toQtModifiers(d->m_modifiers); + } + + if (d->m_composing == 2 && first_press && !(it->flags & QWSKeyboard::IsModifier)) { + // the last key press was the Compose key + if (unicode != 0xffff) { + int idx = 0; + // check if this code is in the compose table at all + for ( ; idx < d->m_keycompose_size; ++idx) { + if (d->m_keycompose[idx].first == unicode) + break; + } + if (idx < d->m_keycompose_size) { + // found it -> simulate a Dead key press + d->m_dead_unicode = unicode; + unicode = 0xffff; + d->m_composing = 1; + skip = true; + } else { + d->m_composing = 0; + } + } else { + d->m_composing = 0; + } + } else if (d->m_composing == 1 && first_press && !(it->flags & QWSKeyboard::IsModifier)) { + // the last key press was a Dead key + bool valid = false; + if (unicode != 0xffff) { + int idx = 0; + // check if this code is in the compose table at all + for ( ; idx < d->m_keycompose_size; ++idx) { + if (d->m_keycompose[idx].first == d->m_dead_unicode && d->m_keycompose[idx].second == unicode) + break; + } + if (idx < d->m_keycompose_size) { + quint16 composed = d->m_keycompose[idx].result; + if (composed != 0xffff) { + unicode = composed; + qtcode = Qt::Key_unknown; + valid = true; + } + } + } + if (!valid) { + unicode = d->m_dead_unicode; + qtcode = Qt::Key_unknown; + } + d->m_composing = 0; + } + + if (!skip) { +#ifdef QT_DEBUG_KEYMAP + qWarning("Processing: uni=%04x, qt=%08x, qtmod=%08x", unicode, qtcode & ~modmask, (qtcode & modmask)); +#endif + + // send the result to the QWS server + processKeyEvent(unicode, qtcode & ~modmask, Qt::KeyboardModifiers(qtcode & modmask), pressed, autorepeat); + } + } + return result; +} + QT_END_NAMESPACE #include "qkbd_qws.moc" diff --git a/src/gui/embedded/qkbd_qws.h b/src/gui/embedded/qkbd_qws.h index 8809f0a..171adc0 100644 --- a/src/gui/embedded/qkbd_qws.h +++ b/src/gui/embedded/qkbd_qws.h @@ -58,11 +58,33 @@ class Q_GUI_EXPORT QWSKeyboardHandler { public: QWSKeyboardHandler(); + QWSKeyboardHandler(const QString &device); virtual ~QWSKeyboardHandler(); virtual void processKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat); + enum KeycodeAction { + None = 0, + + CapsLockOff = 0x01000000, + CapsLockOn = 0x01000001, + NumLockOff = 0x02000000, + NumLockOn = 0x02000001, + ScrollLockOff = 0x03000000, + ScrollLockOn = 0x03000001, + + Reboot = 0x04000000, + + PreviousConsole = 0x05000000, + NextConsole = 0x05000001, + SwitchConsoleFirst = 0x06000000, + SwitchConsoleLast = 0x0600007f, + SwitchConsoleMask = 0x0000007f, + }; + + KeycodeAction processKeycode(quint16 keycode, bool pressed, bool autorepeat); + protected: int transformDirKey(int key); void beginAutoRepeat(int uni, int code, Qt::KeyboardModifiers mod); diff --git a/src/gui/embedded/qkbd_qws_p.h b/src/gui/embedded/qkbd_qws_p.h new file mode 100644 index 0000000..f7dcdaf --- /dev/null +++ b/src/gui/embedded/qkbd_qws_p.h @@ -0,0 +1,77 @@ +#ifndef QWSKEYBOARD_P_H +#define QWSKEYBOARD_P_H + +#include <QDataStream> + +namespace QWSKeyboard { + const quint32 FileMagic = 0x514d4150; // 'QMAP' + + struct Mapping { + quint16 keycode; + quint16 unicode; + quint32 qtcode; + quint8 modifiers; + quint8 flags; + quint16 special; + + }; + + enum Flags { + IsDead = 0x01, + IsLetter = 0x02, + IsModifier = 0x04, + IsSystem = 0x08, + }; + + enum System { + SystemConsoleFirst = 0x0100, + SystemConsoleMask = 0x007f, + SystemConsoleLast = 0x017f, + SystemConsolePrevious = 0x0180, + SystemConsoleNext = 0x0181, + SystemReboot = 0x0200, + SystemZap = 0x0300, + }; + + struct Composing { + quint16 first; + quint16 second; + quint16 result; + }; + + enum Modifiers { + ModPlain = 0x00, + ModShift = 0x01, + ModAltGr = 0x02, + ModControl = 0x04, + ModAlt = 0x08, + ModShiftL = 0x10, + ModShiftR = 0x20, + ModCtrlL = 0x40, + ModCtrlR = 0x80, + // ModCapsShift = 0x100, // not supported! + }; +}; + +inline QDataStream &operator>>(QDataStream &ds, QWSKeyboard::Mapping &m) +{ + return ds >> m.keycode >> m.unicode >> m.qtcode >> m.modifiers >> m.flags >> m.special; +} + +inline QDataStream &operator<<(QDataStream &ds, const QWSKeyboard::Mapping &m) +{ + return ds << m.keycode << m.unicode << m.qtcode << m.modifiers << m.flags << m.special; +} + +inline QDataStream &operator>>(QDataStream &ds, QWSKeyboard::Composing &c) +{ + return ds >> c.first >> c.second >> c.result; +} + +inline QDataStream &operator<<(QDataStream &ds, const QWSKeyboard::Composing &c) +{ + return ds << c.first << c.second << c.result; +} + + +#endif // QWSKEYBOARD_H diff --git a/src/gui/embedded/qkbddriverfactory_qws.cpp b/src/gui/embedded/qkbddriverfactory_qws.cpp index 1ade652..dbfac5c 100644 --- a/src/gui/embedded/qkbddriverfactory_qws.cpp +++ b/src/gui/embedded/qkbddriverfactory_qws.cpp @@ -45,7 +45,7 @@ #include "qapplication.h" #include "qkbdtty_qws.h" -#include "qkbdusb_qws.h" +#include "qkbdlinuxinput_qws.h" #include "qkbdum_qws.h" #include "qkbdsl5000_qws.h" #include "qkbdvfb_qws.h" @@ -121,9 +121,11 @@ QWSKeyboardHandler *QKbdDriverFactory::create(const QString& key, const QString& if (driver == QLatin1String("tty") || driver.isEmpty()) return new QWSTtyKeyboardHandler(device); # endif -# ifndef QT_NO_QWS_KBD_USB - if (driver == QLatin1String("usb")) - return new QWSUsbKeyboardHandler(device); +# ifndef QT_NO_QWS_KBD_LINUXINPUT + if (driver == QLatin1String("linuxinput") || \ + driver == QLatin1String("usb") || \ + driver == QLatin1String("linuxis")) + return new QWSLinuxInputKeyboardHandler(device); # endif # ifndef QT_NO_QWS_KBD_UM if (driver == QLatin1String("um") || driver == QLatin1String("qvfbkeyboard")) @@ -168,8 +170,8 @@ QStringList QKbdDriverFactory::keys() #ifndef QT_NO_QWS_KBD_TTY list << QLatin1String("TTY"); #endif -#ifndef QT_NO_QWS_KBD_USB - list << QLatin1String("USB"); +#ifndef QT_NO_QWS_KBD_LINUXINPUT + list << QLatin1String("LinuxInput"); #endif #ifndef QT_NO_QWS_KBD_UM list << QLatin1String("UM"); diff --git a/src/gui/embedded/qkbdlinuxinput_qws.cpp b/src/gui/embedded/qkbdlinuxinput_qws.cpp new file mode 100644 index 0000000..d04b09f --- /dev/null +++ b/src/gui/embedded/qkbdlinuxinput_qws.cpp @@ -0,0 +1,241 @@ +/**************************************************************************** +** +** 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 "qkbdlinuxinput_qws.h" + +#ifndef QT_NO_QWS_KEYBOARD + +#include <QSocketNotifier> +#include <QStringList> + +#include <qplatformdefs.h> + +#include <errno.h> +#include <termios.h> + +#include <linux/kd.h> +#include <linux/input.h> + +QT_BEGIN_NAMESPACE + + +class QWSLinuxInputKbPrivate : public QObject +{ + Q_OBJECT +public: + QWSLinuxInputKbPrivate(QWSLinuxInputKeyboardHandler *, const QString &); + ~QWSLinuxInputKbPrivate(); + +private: + void switchLed(int, bool); + +private Q_SLOTS: + void readKeycode(); + +private: + QWSLinuxInputKeyboardHandler *m_handler; + int m_fd; + int m_tty_fd; + struct termios m_tty_attr; +}; + +QWSLinuxInputKeyboardHandler::QWSLinuxInputKeyboardHandler(const QString &device) + : QWSKeyboardHandler(device) +{ + d = new QWSLinuxInputKbPrivate(this, device); +} + +QWSLinuxInputKeyboardHandler::~QWSLinuxInputKeyboardHandler() +{ + delete d; +} + +bool QWSLinuxInputKeyboardHandler::filterInputEvent(quint16 &, qint32 &) +{ + return false; +} + +QWSLinuxInputKbPrivate::QWSLinuxInputKbPrivate(QWSLinuxInputKeyboardHandler *h, const QString &device) + : m_handler(h), m_fd(-1), m_tty_fd(-1) + +{ + setObjectName(QLatin1String("LinuxInputSubsystem Keyboard Handler")); + + QString dev = QLatin1String("/dev/input/event1"); + int repeat_delay = -1; + int repeat_rate = -1; + + QStringList args = device.split(QLatin1Char(':')); + foreach (const QString &arg, args) { + if (arg.startsWith(QLatin1String("repeat_delay="))) + repeat_delay = arg.mid(13).toInt(); + else if (arg.startsWith(QLatin1String("repeat_rate="))) + repeat_rate = arg.mid(12).toInt(); + else if (arg.startsWith(QLatin1String("/dev/"))) + dev = arg; + } + + m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDWR, 0); + if (m_fd >= 0) { + if (repeat_delay > 0 && repeat_rate > 0) { + int kbdrep[2] = { repeat_delay, repeat_rate }; + ::ioctl(m_fd, EVIOCSREP, kbdrep); + } + + QSocketNotifier *notifier; + notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); + connect(notifier, SIGNAL(activated(int)), this, SLOT(readKeycode())); + + // play nice in case we are started from a shell (e.g. for debugging) + m_tty_fd = isatty(0) ? 0 : -1; + + if (m_tty_fd >= 0) { + // save tty config for restore. + tcgetattr(m_tty_fd, &m_tty_attr); + + struct ::termios termdata; + tcgetattr(m_tty_fd, &termdata); + + // setting this tranlation mode is also needed in INPUT mode to prevent + // the shell from also interpreting codes, if the process has a tty + // attached: e.g. Ctrl+C wouldn't copy, but kill the application. + ::ioctl(m_tty_fd, KDSKBMODE, K_MEDIUMRAW); + + // set the tty layer to pass-through + termdata.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP); + termdata.c_oflag = 0; + termdata.c_cflag = CREAD | CS8; + termdata.c_lflag = 0; + termdata.c_cc[VTIME]=0; + termdata.c_cc[VMIN]=1; + cfsetispeed(&termdata, 9600); + cfsetospeed(&termdata, 9600); + tcsetattr(m_tty_fd, TCSANOW, &termdata); + } + } else { + qWarning("Cannot open input device '%s': %s", qPrintable(dev), strerror(errno)); + return; + } +} + +QWSLinuxInputKbPrivate::~QWSLinuxInputKbPrivate() +{ + if (m_tty_fd >= 0) { + ::ioctl(m_tty_fd, KDSKBMODE, K_XLATE); + tcsetattr(m_tty_fd, TCSANOW, &m_tty_attr); + } + if (m_fd >= 0) + QT_CLOSE(m_fd); +} + +void QWSLinuxInputKbPrivate::switchLed(int led, bool state) +{ + struct ::input_event led_ie; + ::gettimeofday(&led_ie.time, 0); + led_ie.type = EV_LED; + led_ie.code = led; + led_ie.value = state; + + QT_WRITE(m_fd, &led_ie, sizeof(led_ie)); +} + +void QWSLinuxInputKbPrivate::readKeycode() +{ + struct ::input_event buffer[32]; + int n = 0; + + forever { + n = QT_READ(m_fd, reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n); + + if (n == 0) { + qWarning("Got EOF from the input device."); + return; + } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) { + qWarning("Could not read from input device: %s", strerror(errno)); + return; + } else if (n % sizeof(buffer[0]) == 0) { + break; + } + } + + n /= sizeof(buffer[0]); + + for (int i = 0; i < n; ++i) { + if (buffer[i].type != EV_KEY) + continue; + + quint16 code = buffer[i].code; + qint32 value = buffer[i].value; + + if (m_handler->filterInputEvent(code, value)) + continue; + + QWSKeyboardHandler::KeycodeAction ka; + ka = m_handler->processKeycode(code, value != 0, value == 2); + + switch (ka) { + case QWSKeyboardHandler::CapsLockOn: + case QWSKeyboardHandler::CapsLockOff: + switchLed(LED_CAPSL, ka == QWSKeyboardHandler::CapsLockOn); + break; + + case QWSKeyboardHandler::NumLockOn: + case QWSKeyboardHandler::NumLockOff: + switchLed(LED_NUML, ka == QWSKeyboardHandler::NumLockOn); + break; + + case QWSKeyboardHandler::ScrollLockOn: + case QWSKeyboardHandler::ScrollLockOff: + switchLed(LED_SCROLLL, ka == QWSKeyboardHandler::ScrollLockOn); + break; + + default: + // ignore console switching and reboot + break; + } + } +} + +QT_END_NAMESPACE + +#include "qkbdlinuxinput_qws.moc" + +#endif // QT_NO_QWS_KEYBOARD diff --git a/src/gui/embedded/qkbdusb_qws.h b/src/gui/embedded/qkbdlinuxinput_qws.h index 81d0103..5fa8214 100644 --- a/src/gui/embedded/qkbdusb_qws.h +++ b/src/gui/embedded/qkbdlinuxinput_qws.h @@ -39,10 +39,10 @@ ** ****************************************************************************/ -#ifndef QKBDUSB_QWS_H -#define QKBDUSB_QWS_H +#ifndef QKBDLINUXINPUT_QWS_H +#define QKBDLINUXINPUT_QWS_H -#include <QtGui/qkbdpc101_qws.h> +#include <QtGui/qkbd_qws.h> QT_BEGIN_HEADER @@ -52,21 +52,23 @@ QT_MODULE(Gui) #ifndef QT_NO_QWS_KEYBOARD -#ifndef QT_NO_QWS_KBD_USB +#ifndef QT_NO_QWS_KBD_LINUXINPUT -class QWSUsbKbPrivate; +class QWSLinuxInputKbPrivate; -class QWSUsbKeyboardHandler : public QWSPC101KeyboardHandler +class QWSLinuxInputKeyboardHandler : public QWSKeyboardHandler { public: - QWSUsbKeyboardHandler(const QString&); - virtual ~QWSUsbKeyboardHandler(); + QWSLinuxInputKeyboardHandler(const QString&); + virtual ~QWSLinuxInputKeyboardHandler(); + + virtual bool filterInputEvent(quint16 &input_code, qint32 &input_value); private: - QWSUsbKbPrivate *d; + QWSLinuxInputKbPrivate *d; }; -#endif // QT_NO_QWS_KBD_USB +#endif // QT_NO_QWS_KBD_LINUXINPUT #endif // QT_NO_QWS_KEYBOARD @@ -74,4 +76,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QKBDUSB_QWS_H +#endif // QKBDLINUXINPUT_QWS_H diff --git a/src/gui/embedded/qkbdsl5000_qws.cpp b/src/gui/embedded/qkbdsl5000_qws.cpp index bc412b6..1e8095e 100644 --- a/src/gui/embedded/qkbdsl5000_qws.cpp +++ b/src/gui/embedded/qkbdsl5000_qws.cpp @@ -195,6 +195,13 @@ static const int keyMSize = sizeof(sl5000KeyMap)/sizeof(QWSKeyMap)-1; QWSSL5000KeyboardHandler::QWSSL5000KeyboardHandler(const QString &device) : QWSTtyKeyboardHandler(device) { + shift = false; + alt = false; + ctrl = false; + extended = 0; + prevuni = 0; + prevkey = 0; + caps = false; meta = false; fn = false; numLock = false; @@ -220,7 +227,7 @@ const QWSKeyMap *QWSSL5000KeyboardHandler::keyMap() const return sl5000KeyMap; } -void QWSSL5000KeyboardHandler::doKey(uchar code) +bool QWSSL5000KeyboardHandler::filterKeycode(char &code) { int keyCode = Qt::Key_unknown; bool release = false; @@ -239,19 +246,19 @@ void QWSSL5000KeyboardHandler::doKey(uchar code) else if (code == 0x52) { unicode='Z'-'@'; scan=Qt::Key_Z; } // Undo if (scan) { processKeyEvent(unicode, scan, Qt::ControlModifier, !release, false); - return; + return true; } } if (code < keyMSize) { - keyCode = keyMap()[code].key_code; + keyCode = keyMap()[int(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 + return true; // 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; @@ -318,11 +325,11 @@ void QWSSL5000KeyboardHandler::doKey(uchar code) keyCode = Qt::Key_QuoteLeft; unicode = '`'; } else if (bCtrl) - unicode = keyMap()[code].ctrl_unicode ? keyMap()[code].ctrl_unicode : 0xffff; + unicode = keyMap()[int(code)].ctrl_unicode ? keyMap()[int(code)].ctrl_unicode : 0xffff; else if (bCaps) - unicode = keyMap()[code].shift_unicode ? keyMap()[code].shift_unicode : 0xffff; + unicode = keyMap()[int(code)].shift_unicode ? keyMap()[int(code)].shift_unicode : 0xffff; else - unicode = keyMap()[code].unicode ? keyMap()[code].unicode : 0xffff; + unicode = keyMap()[int(code)].unicode ? keyMap()[int(code)].unicode : 0xffff; } modifiers = 0; @@ -349,6 +356,8 @@ void QWSSL5000KeyboardHandler::doKey(uchar code) beginAutoRepeat(prevuni, prevkey, modifiers); else endAutoRepeat(); + + return true; } QT_END_NAMESPACE diff --git a/src/gui/embedded/qkbdsl5000_qws.h b/src/gui/embedded/qkbdsl5000_qws.h index 514d602..a96e038 100644 --- a/src/gui/embedded/qkbdsl5000_qws.h +++ b/src/gui/embedded/qkbdsl5000_qws.h @@ -52,7 +52,13 @@ QT_MODULE(Gui) #ifndef QT_NO_QWS_KBD_SL5000 -class QWSSL5000KbPrivate; +struct QWSKeyMap { + uint key_code; + ushort unicode; + ushort shift_unicode; + ushort ctrl_unicode; +}; + class QWSSL5000KeyboardHandler : public QWSTtyKeyboardHandler { @@ -60,14 +66,21 @@ public: explicit QWSSL5000KeyboardHandler(const QString&); virtual ~QWSSL5000KeyboardHandler(); - virtual void doKey(uchar scancode); + bool filterKeycode(char &keycode); virtual const QWSKeyMap *keyMap() const; private: + bool shift; + bool alt; + bool ctrl; + bool caps; + uint extended:2; + Qt::KeyboardModifiers modifiers; + int prevuni; + int prevkey; bool meta; bool fn; bool numLock; - QWSSL5000KbPrivate *d; }; #endif // QT_NO_QWS_KBD_SL5000 diff --git a/src/gui/embedded/qkbdtty_qws.cpp b/src/gui/embedded/qkbdtty_qws.cpp index b588e55..37ed510 100644 --- a/src/gui/embedded/qkbdtty_qws.cpp +++ b/src/gui/embedded/qkbdtty_qws.cpp @@ -43,64 +43,57 @@ #if !defined(QT_NO_QWS_KEYBOARD) && !defined(QT_NO_QWS_KBD_TTY) -#include "qscreen_qws.h" - -#include "qwindowsystem_qws.h" -#include "qapplication.h" -#include "qsocketnotifier.h" -#include "qnamespace.h" -#include "qtimer.h" -#include <private/qwssignalhandler_p.h> -#include <private/qwindowsurface_qws_p.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 <termios.h> +#include <QSocketNotifier> +#include <QStringList> -#include <qeventloop.h> +#include <qplatformdefs.h> -#ifdef Q_OS_LINUX -#include <sys/kd.h> -#include <sys/vt.h> -#endif +#include <errno.h> +#include <termios.h> -QT_BEGIN_NAMESPACE +#if defined Q_OS_LINUX +# include <linux/kd.h> +# include <linux/vt.h> //TODO: move vt handling somewhere else (QLinuxFbScreen?) -#define VTACQSIG SIGUSR1 -#define VTRELSIG SIGUSR2 +# include "qscreen_qws.h" +# include "qwindowsystem_qws.h" +# include "qapplication.h" +# include "private/qwindowsurface_qws_p.h" +# include "private/qwssignalhandler_p.h" -static int vtQws = 0; -static int kbdFD = -1; +# define VTACQSIG SIGUSR1 +# define VTRELSIG SIGUSR2 +#endif -//=========================================================================== -// -// Tty keyboard -// +QT_BEGIN_NAMESPACE class QWSTtyKbPrivate : public QObject { Q_OBJECT public: - QWSTtyKbPrivate(QWSPC101KeyboardHandler *, const QString &device); + QWSTtyKbPrivate(QWSTtyKeyboardHandler *handler, const QString &device); ~QWSTtyKbPrivate(); -private slots: - void readKeyboardData(); - void handleTtySwitch(int); +private: + void switchLed(char, bool); + void switchConsole(int vt); + +private Q_SLOTS: + void readKeycode(); + void handleConsoleSwitch(int sig); private: - QWSPC101KeyboardHandler *handler; - struct termios origTermData; + QWSTtyKeyboardHandler *m_handler; + int m_tty_fd; + struct termios m_tty_attr; + char m_last_keycode; + int m_vt_qws; }; + QWSTtyKeyboardHandler::QWSTtyKeyboardHandler(const QString &device) - : QWSPC101KeyboardHandler(device) + : QWSKeyboardHandler(device) { d = new QWSTtyKbPrivate(this, device); } @@ -110,59 +103,63 @@ QWSTtyKeyboardHandler::~QWSTtyKeyboardHandler() delete d; } -void QWSTtyKeyboardHandler::processKeyEvent(int unicode, int keycode, - Qt::KeyboardModifiers modifiers, bool isPress, - bool autoRepeat) +bool QWSTtyKeyboardHandler::filterKeycode(char &) { -#if defined(Q_OS_LINUX) - // Virtual console switching - int term = 0; - bool ctrl = modifiers & Qt::ControlModifier; - bool alt = modifiers & Qt::AltModifier; - if (ctrl && alt && keycode >= Qt::Key_F1 && keycode <= Qt::Key_F10) - term = keycode - Qt::Key_F1 + 1; - else if (ctrl && alt && keycode == Qt::Key_Left) - term = qMax(vtQws - 1, 1); - else if (ctrl && alt && keycode == Qt::Key_Right) - term = qMin(vtQws + 1, 10); - if (term && isPress) { - ioctl(kbdFD, VT_ACTIVATE, term); - return; - } -#endif - - QWSPC101KeyboardHandler::processKeyEvent(unicode, keycode, modifiers, - isPress, autoRepeat); + return false; } - -QWSTtyKbPrivate::QWSTtyKbPrivate(QWSPC101KeyboardHandler *h, const QString &device) : handler(h) +QWSTtyKbPrivate::QWSTtyKbPrivate(QWSTtyKeyboardHandler *h, const QString &device) + : m_handler(h), m_tty_fd(-1), m_last_keycode(0), m_vt_qws(0) { - kbdFD = ::open(device.isEmpty()?"/dev/tty0":device.toLatin1().constData(), O_RDWR|O_NDELAY, 0); + setObjectName(QLatin1String("TTY Keyboard Handler")); #ifndef QT_NO_QWS_SIGNALHANDLER QWSSignalHandler::instance()->addObject(this); #endif - if (kbdFD >= 0) { + QString dev = QLatin1String("/dev/tty0"); + int repeat_delay = -1; + int repeat_rate = -1; + + QStringList args = device.split(QLatin1Char(':')); + foreach (const QString &arg, args) { + if (arg.startsWith(QLatin1String("repeat_delay="))) + repeat_delay = arg.mid(13).toInt(); + else if (arg.startsWith(QLatin1String("repeat_rate="))) + repeat_rate = arg.mid(12).toInt(); + else if (arg.startsWith(QLatin1String("/dev/"))) + dev = arg; + } + + m_tty_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDWR, 0); + if (m_tty_fd >= 0) { + if (repeat_delay > 0 && repeat_rate > 0) { +#if defined(Q_OS_LINUX) + struct ::kbd_repeat kbdrep = { repeat_delay, repeat_rate }; + ::ioctl(m_tty_fd, KDKBDREP, &kbdrep); +#endif + } + QSocketNotifier *notifier; - notifier = new QSocketNotifier(kbdFD, QSocketNotifier::Read, this); - connect(notifier, SIGNAL(activated(int)),this, - SLOT(readKeyboardData())); + notifier = new QSocketNotifier(m_tty_fd, QSocketNotifier::Read, this); + connect(notifier, SIGNAL(activated(int)), this, SLOT(readKeycode())); - // save for restore. - tcgetattr(kbdFD, &origTermData); + // save tty config for restore. + tcgetattr(m_tty_fd, &m_tty_attr); - struct termios termdata; - tcgetattr(kbdFD, &termdata); + struct ::termios termdata; + tcgetattr(m_tty_fd, &termdata); #if defined(Q_OS_LINUX) -# ifdef QT_QWS_USE_KEYCODES - ioctl(kbdFD, KDSKBMODE, K_MEDIUMRAW); -# else - ioctl(kbdFD, KDSKBMODE, K_RAW); -# endif + // PLEASE NOTE: + // The tty keycode interface can only report keycodes 0x01 .. 0x7f + // KEY_MAX is however defined to 0x1ff. In practice this is sufficient + // for a PC style keyboard though. + // we don't support K_RAW anymore - if you need, you habe to add a + // scan- to keycode converter. + ::ioctl(m_tty_fd, KDSKBMODE, K_MEDIUMRAW); #endif + // set the tty layer to pass-through termdata.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP); termdata.c_oflag = 0; termdata.c_cflag = CREAD | CS8; @@ -171,50 +168,146 @@ QWSTtyKbPrivate::QWSTtyKbPrivate(QWSPC101KeyboardHandler *h, const QString &devi termdata.c_cc[VMIN]=1; cfsetispeed(&termdata, 9600); cfsetospeed(&termdata, 9600); - tcsetattr(kbdFD, TCSANOW, &termdata); + tcsetattr(m_tty_fd, TCSANOW, &termdata); #if defined(Q_OS_LINUX) - - connect(QApplication::instance(), SIGNAL(unixSignal(int)), this, SLOT(handleTtySwitch(int))); + // VT switching is handled via unix signals + connect(QApplication::instance(), SIGNAL(unixSignal(int)), this, SLOT(handleConsoleSwitch(int))); QApplication::instance()->watchUnixSignal(VTACQSIG, true); QApplication::instance()->watchUnixSignal(VTRELSIG, true); - struct vt_mode vtMode; - ioctl(kbdFD, VT_GETMODE, &vtMode); + struct ::vt_mode vtMode; + if (::ioctl(m_tty_fd, VT_GETMODE, &vtMode) == 0) { + vtMode.mode = VT_PROCESS; + vtMode.relsig = VTRELSIG; + vtMode.acqsig = VTACQSIG; - // let us control VT switching - vtMode.mode = VT_PROCESS; - vtMode.relsig = VTRELSIG; - vtMode.acqsig = VTACQSIG; - ioctl(kbdFD, VT_SETMODE, &vtMode); + if (::ioctl(m_tty_fd, VT_SETMODE, &vtMode) == 0) { + struct ::vt_stat vtStat; + ::memset(&vtStat, 0, sizeof(vtStat)); - struct vt_stat vtStat; - ioctl(kbdFD, VT_GETSTATE, &vtStat); - vtQws = vtStat.v_active; + if (::ioctl(m_tty_fd, VT_GETSTATE, &vtStat) == 0 ) { + m_vt_qws = vtStat.v_active; + } + } + } + + if (!m_vt_qws) + qWarning("Could not initialize virtual console switching"); #endif } else { - qCritical("Cannot open keyboard: %s", strerror(errno)); + qWarning("Cannot open input device '%s': %s", qPrintable(dev), strerror(errno)); + return; } } QWSTtyKbPrivate::~QWSTtyKbPrivate() { - if (kbdFD >= 0) { + if (m_tty_fd >= 0) { #if defined(Q_OS_LINUX) - ioctl(kbdFD, KDSKBMODE, K_XLATE); + ::ioctl(m_tty_fd, KDSKBMODE, K_XLATE); #endif - tcsetattr(kbdFD, TCSANOW, &origTermData); - ::close(kbdFD); - kbdFD = -1; + tcsetattr(m_tty_fd, TCSANOW, &m_tty_attr); } } -void QWSTtyKbPrivate::handleTtySwitch(int sig) + + +void QWSTtyKbPrivate::switchLed(char led, bool state) { #if defined(Q_OS_LINUX) + char ledstate; + + ::ioctl(m_tty_fd, KDGETLED, &ledstate); + if (state) + ledstate |= led; + else + ledstate &= ~led; + ::ioctl(m_tty_fd, KDSETLED, ledstate); +#endif +} + +void QWSTtyKbPrivate::readKeycode() +{ + char buffer[32]; + int n = 0; + + forever { + n = QT_READ(m_tty_fd, buffer + n, 32 - n); + + if (n == 0) { + qWarning("Got EOF from the input device."); + return; + } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) { + qWarning("Could not read from input device: %s", strerror(errno)); + return; + } else { + break; + } + } + + for (int i = 0; i < n; ++i) { + if (m_handler->filterKeycode(buffer[i])) + continue; + + QWSKeyboardHandler::KeycodeAction ka; + ka = m_handler->processKeycode(buffer[i] & 0x7f, (buffer[i] & 0x80) == 0x00, buffer[i] == m_last_keycode); + m_last_keycode = buffer[i]; + +qWarning("Special: %08x", ka); + switch (ka) { + case QWSKeyboardHandler::CapsLockOn: + case QWSKeyboardHandler::CapsLockOff: + switchLed(LED_CAP, ka == QWSKeyboardHandler::CapsLockOn); + break; + + case QWSKeyboardHandler::NumLockOn: + case QWSKeyboardHandler::NumLockOff: + switchLed(LED_NUM, ka == QWSKeyboardHandler::NumLockOn); + break; + + case QWSKeyboardHandler::ScrollLockOn: + case QWSKeyboardHandler::ScrollLockOff: + switchLed(LED_SCR, ka == QWSKeyboardHandler::ScrollLockOn); + break; + + case QWSKeyboardHandler::PreviousConsole: + switchConsole(qBound(1, m_vt_qws - 1, 10)); + break; + + case QWSKeyboardHandler::NextConsole: + switchConsole(qBound(1, m_vt_qws + 1, 10)); + break; + + default: + if (ka >= QWSKeyboardHandler::SwitchConsoleFirst && + ka <= QWSKeyboardHandler::SwitchConsoleLast) { + switchConsole(1 + (ka & QWSKeyboardHandler::SwitchConsoleMask)); + } + //ignore reboot + break; + } + } +} + + +void QWSTtyKbPrivate::switchConsole(int vt) +{ +#if defined(Q_OS_LINUX) + if (m_vt_qws && vt && (m_tty_fd >= 0 )) + ::ioctl(m_tty_fd, VT_ACTIVATE, vt); +#endif +} + +void QWSTtyKbPrivate::handleConsoleSwitch(int sig) +{ +#if defined(Q_OS_LINUX) + // received a notification from the kernel that the current VT is + // changing: either enable or disable QWS painting accordingly. + if (sig == VTACQSIG) { - if (ioctl(kbdFD, VT_RELDISP, VT_ACKACQ) == 0) { + if (::ioctl(m_tty_fd, VT_RELDISP, VT_ACKACQ) == 0) { qwsServer->enablePainting(true); qt_screen->restore(); qwsServer->resumeMouse(); @@ -236,9 +329,9 @@ void QWSTtyKbPrivate::handleTtySwitch(int sig) } if (!allWindowsHidden) { - ioctl(kbdFD, VT_RELDISP, 0); // abort console switch + ::ioctl(m_tty_fd, VT_RELDISP, 0); // abort console switch qwsServer->enablePainting(true); - } else if (ioctl(kbdFD, VT_RELDISP, 1) == 0) { + } else if (::ioctl(m_tty_fd, VT_RELDISP, 1) == 0) { qt_screen->save(); qwsServer->suspendMouse(); } else { @@ -248,14 +341,6 @@ void QWSTtyKbPrivate::handleTtySwitch(int sig) #endif } -void QWSTtyKbPrivate::readKeyboardData() -{ - unsigned char buf[81]; - int n = read(kbdFD, buf, 80); - for (int loop = 0; loop < n; loop++) - handler->doKey(buf[loop]); -} - QT_END_NAMESPACE #include "qkbdtty_qws.moc" diff --git a/src/gui/embedded/qkbdtty_qws.h b/src/gui/embedded/qkbdtty_qws.h index 4f93d6c..fc3eaa1 100644 --- a/src/gui/embedded/qkbdtty_qws.h +++ b/src/gui/embedded/qkbdtty_qws.h @@ -42,7 +42,7 @@ #ifndef QKBDTTY_QWS_H #define QKBDTTY_QWS_H -#include <QtGui/qkbdpc101_qws.h> +#include <QtGui/qkbd_qws.h> QT_BEGIN_HEADER @@ -56,15 +56,13 @@ QT_MODULE(Gui) class QWSTtyKbPrivate; -class QWSTtyKeyboardHandler : public QWSPC101KeyboardHandler +class QWSTtyKeyboardHandler : public QWSKeyboardHandler { public: explicit QWSTtyKeyboardHandler(const QString&); virtual ~QWSTtyKeyboardHandler(); -protected: - virtual void processKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers, - bool isPress, bool autoRepeat); + virtual bool filterKeycode(char &code); private: QWSTtyKbPrivate *d; diff --git a/src/gui/embedded/qkbdusb_qws.cpp b/src/gui/embedded/qkbdusb_qws.cpp deleted file mode 100644 index e35ac55..0000000 --- a/src/gui/embedded/qkbdusb_qws.cpp +++ /dev/null @@ -1,401 +0,0 @@ -/**************************************************************************** -** -** 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 "qkbdusb_qws.h" - -#ifndef QT_NO_QWS_KEYBOARD - -#include "qscreen_qws.h" - -#include "qwindowsystem_qws.h" -#include "qapplication.h" -#include "qsocketnotifier.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 <linux/input.h> - -#ifdef Q_OS_LINUX -#include <sys/kd.h> -#include <sys/vt.h> -#endif - -QT_BEGIN_NAMESPACE - -/* USB driver */ - - -class QWSUsbKbPrivate : public QObject -{ - Q_OBJECT -public: - QWSUsbKbPrivate(QWSPC101KeyboardHandler *, const QString &); - ~QWSUsbKbPrivate(); - -private slots: - void readKeyboardData(); - -private: - QWSPC101KeyboardHandler *handler; - int fd; -#ifdef QT_QWS_ZYLONITE - bool shift; -#endif -}; - -QWSUsbKeyboardHandler::QWSUsbKeyboardHandler(const QString &device) - : QWSPC101KeyboardHandler(device) -{ - d = new QWSUsbKbPrivate(this, device); -} - -QWSUsbKeyboardHandler::~QWSUsbKeyboardHandler() -{ - delete d; -} - -QWSUsbKbPrivate::QWSUsbKbPrivate(QWSPC101KeyboardHandler *h, const QString &device) : handler(h) -{ -#ifdef QT_QWS_ZYLONITE - shift = FALSE; -#endif - fd = ::open(device.isEmpty()?"/dev/input/event1":device.toLocal8Bit(),O_RDONLY, 0); - if (fd >= 0) { - QSocketNotifier *notifier; - notifier = new QSocketNotifier(fd, QSocketNotifier::Read, this); - connect(notifier, SIGNAL(activated(int)),this, - SLOT(readKeyboardData())); - } -} - -QWSUsbKbPrivate::~QWSUsbKbPrivate() -{ - ::close(fd); -} - -void QWSUsbKbPrivate::readKeyboardData() -{ - input_event event; - if (read(fd, &event, sizeof(input_event)) != sizeof(input_event)) - return; - - if (event.type != EV_KEY) - return; - -#ifdef QT_QWS_ZYLONITE - qDebug("keypressed: code=%03d (%s)\n",event.code,((event.value)!=0) ? "Down":"Up"); - int modifiers=0; - int unicode=0xffff; - int key_code=0; - - switch(event.code) - { - case 0xA2: - key_code = ((!shift) ? Qt::Key_0 : Qt::Key_Plus ); - unicode = ((!shift) ? 0x30 : 0x2B ); - break; - case 0x70: - key_code = ((!shift) ? Qt::Key_1 : Qt::Key_At ); - unicode = ((!shift) ? 0x31 : 0x40 ); - break; - case 0x72: - key_code = ((!shift) ? Qt::Key_2 : Qt::Key_Ampersand ); - unicode = ((!shift) ? 0x32 : 0x26 ); - break; - case 0x74: - key_code = ((!shift) ? Qt::Key_3 : Qt::Key_At ); - unicode = ((!shift) ? 0x33 : 0x3F ); - break; - case 0x80: - key_code = ((!shift) ? Qt::Key_4 : Qt::Key_Minus ); - unicode = ((!shift) ? 0x34 : 0x2D ); - break; - case 0x82: - key_code = ((!shift) ? Qt::Key_5 : Qt::Key_Apostrophe); - unicode = ((!shift) ? 0x35 : 0x27 ); - break; - case 0x84: - key_code = ((!shift) ? Qt::Key_6 : Qt::Key_Slash ); - unicode = ((!shift) ? 0x36 : 0x5C ); - break; - case 0x90: - key_code = ((!shift) ? Qt::Key_7 : Qt::Key_Colon ); - unicode = ((!shift) ? 0x37 : 0x3A ); - break; - case 0x92: - key_code = ((!shift) ? Qt::Key_8 : Qt::Key_Semicolon ); - unicode = ((!shift) ? 0x38 : 0x3B ); - break; - case 0x94: - key_code = ((!shift) ? Qt::Key_9 : Qt::Key_QuoteDbl ); - unicode = ((!shift) ? 0x39 : 0x22 ); - break; - case 0x0: - key_code = Qt::Key_A; - unicode = ((!shift) ? 0x61 : 0x41 ); - break; - case 0x10: - key_code = Qt::Key_B; - unicode = ((!shift) ? 0x62 : 0x42 ); - break; - case 0x20: - key_code = Qt::Key_C; - unicode = ((!shift) ? 0x63 : 0x43 ); - break; - case 0x30: - key_code = Qt::Key_D; - unicode = ((!shift) ? 0x64 : 0x44 ); - break; - case 0x40: - key_code = Qt::Key_E; - unicode = ((!shift) ? 0x65 : 0x45 ); - break; - case 0x50: - key_code = Qt::Key_F; - unicode = ((!shift) ? 0x66 : 0x46 ); - break; - case 0x01: - key_code = Qt::Key_G; - unicode = ((!shift) ? 0x67 : 0x47 ); - break; - case 0x11: - key_code = Qt::Key_H; - unicode = ((!shift) ? 0x68 : 0x48 ); - break; - case 0x21: - key_code = Qt::Key_I; - unicode = ((!shift) ? 0x69 : 0x49 ); - break; - case 0x31: - key_code = Qt::Key_J; - unicode = ((!shift) ? 0x6A : 0x4A ); - break; - case 0x41: - key_code = Qt::Key_K; - unicode = ((!shift) ? 0x6B : 0x4B ); - break; - case 0x51: - key_code = Qt::Key_L; - unicode = ((!shift) ? 0x6C : 0x4C ); - break; - case 0x02: - key_code = Qt::Key_M; - unicode = ((!shift) ? 0x6D : 0x4D ); - break; - case 0x12: - key_code = Qt::Key_N; - unicode = ((!shift) ? 0x6E : 0x4E ); - break; - case 0x22: - key_code = Qt::Key_O; - unicode = ((!shift) ? 0x6F : 0x4F ); - break; - case 0x32: - key_code = Qt::Key_P; - unicode = ((!shift) ? 0x70 : 0x50 ); - break; - case 0x42: - key_code = Qt::Key_Q; - unicode = ((!shift) ? 0x71 : 0x51 ); - break; - case 0x52: - key_code = Qt::Key_R; - unicode = ((!shift) ? 0x72 : 0x52 ); - break; - case 0x03: - key_code = Qt::Key_S; - unicode = ((!shift) ? 0x73 : 0x53 ); - break; - case 0x13: - key_code = Qt::Key_T; - unicode = ((!shift) ? 0x74 : 0x54 ); - break; - case 0x23: - key_code = Qt::Key_U; - unicode = ((!shift) ? 0x75 : 0x55 ); - break; - case 0x33: - key_code = Qt::Key_V; - unicode = ((!shift) ? 0x76 : 0x56 ); - break; - case 0x43: - key_code = Qt::Key_W; - unicode = ((!shift) ? 0x77 : 0x57 ); - break; - case 0x53: - key_code = Qt::Key_X; - unicode = ((!shift) ? 0x78 : 0x58 ); - break; - case 0x24: - key_code = Qt::Key_Y; - unicode = ((!shift) ? 0x79 : 0x59 ); - break; - case 0x34: - key_code = Qt::Key_Z; - unicode = ((!shift) ? 0x7A : 0x5A ); - break; - case 0xA4: - key_code = ((!shift) ? Qt::Key_NumberSign : Qt::Key_Period); - unicode = ((!shift) ? 0x23 : 0x2E ); - break; - case 0xA0: - key_code = ((!shift) ? Qt::Key_Asterisk : Qt::Key_NumberSign ); - unicode = ((!shift) ? 0x2A : 0x2C ); - break; - case 0x25: - key_code = Qt::Key_Space; - unicode = 0x20; - break; - case 0x06: - key_code = Qt::Key_Up; - unicode = 0xffff; modifiers |= Qt::KeypadModifier; - break; - case 0x16: - key_code = Qt::Key_Down; - unicode = 0xffff; modifiers |= Qt::KeypadModifier; - break; - case 0x26: - key_code = Qt::Key_Left; - unicode = 0xffff; modifiers |= Qt::KeypadModifier; - break; - case 0x36: - key_code = Qt::Key_Right; - unicode = 0xffff; modifiers |= Qt::KeypadModifier; - break; - case 0x46: - key_code = Qt::Key_Select; - unicode = 0xffff; modifiers |= Qt::KeypadModifier; - break; - case 0x61: - key_code = Qt::Key_No; - unicode = 0xffff; modifiers |= Qt::KeypadModifier; - break; - case 0x60: - key_code = Qt::Key_Call; - unicode = 0xffff; modifiers |= Qt::KeypadModifier; - break; - case 0x55: - key_code = Qt::Key_Hangup; - unicode = 0xffff; modifiers |= Qt::KeypadModifier; - break; - case 0x62: - key_code = Qt::Key_Context1; - unicode = 0xffff; modifiers |= Qt::KeypadModifier; - break; - case 0x63: - key_code = Qt::Key_No; - unicode = 0xffff; modifiers |= Qt::KeypadModifier; - break; - case 0x05: - key_code = Qt::Key_Home; - unicode = 0xffff; modifiers |= Qt::KeypadModifier; - break; - case 0x15: - key_code = Qt::Key_Shift; - unicode = 0xffff; modifiers |= Qt::ShiftModifier; - if(event.value==0) break; - if(shift) { - shift = FALSE; - qWarning("Caps Off!"); - } else { - shift = TRUE; - qWarning("Caps On!"); - } - break; - case 0x1C: - key_code = ((!shift) ? Qt::Key_Back : Qt::Key_Enter ); - unicode = 0xffff; modifiers |= Qt::KeypadModifier; - break; - case 0x19: - key_code = Qt::Key_Context2; - unicode = 0xffff; modifiers |= Qt::KeypadModifier; - break; - case 0x1A: - key_code = Qt::Key_Context3; - unicode = 0xffff; modifiers |= Qt::KeypadModifier; - break; - case 0x1B: - key_code = Qt::Key_Context4; - unicode = 0xffff; modifiers |= Qt::KeypadModifier; - break; - } - if(shift) modifiers |= Qt::ShiftModifier; - handler->processKeyEvent(unicode, key_code, (Qt::KeyboardModifiers)modifiers, event.value!=0, false); -#else - - int key=event.code; -#ifndef QT_QWS_USE_KEYCODES - // Handle SOME keys, otherwise it's useless. - - if(key==103) { - handler->processKeyEvent(0, Qt::Key_Up, 0, event.value!=0, false); - } else if(key==106) { - handler->processKeyEvent(0, Qt::Key_Right, 0, event.value!=0, false ); - } else if(key==108) { - handler->processKeyEvent(0, Qt::Key_Down, 0, event.value!=0, false); - } else if(key==105) { - handler->processKeyEvent(0, Qt::Key_Left, 0, event.value!=0, false); - } else - -#endif - - { - if(event.value == 0) { - key=key | 0x80; - } - handler->doKey(key); - } -#endif -} - -QT_END_NAMESPACE - -#include "qkbdusb_qws.moc" - -#endif // QT_NO_QWS_KEYBOARD diff --git a/src/plugins/kbddrivers/kbddrivers.pro b/src/plugins/kbddrivers/kbddrivers.pro index 6605972..a34b780 100644 --- a/src/plugins/kbddrivers/kbddrivers.pro +++ b/src/plugins/kbddrivers/kbddrivers.pro @@ -1,6 +1,5 @@ TEMPLATE = subdirs -contains(kbd-plugins, usb): SUBDIRS += usb +contains(kbd-plugins, linuxinput): SUBDIRS += linuxinput contains(kbd-plugins, sl5000): SUBDIRS += sl5000 contains(kbd-plugins, vr41xx): SUBDIRS += vr41xx contains(kbd-plugins, yopy): SUBDIRS += yopy -contains(kbd-plugins, linuxis): SUBDIRS += linuxis diff --git a/src/plugins/kbddrivers/linuxinput/linuxinput.pro b/src/plugins/kbddrivers/linuxinput/linuxinput.pro new file mode 100644 index 0000000..862a220 --- /dev/null +++ b/src/plugins/kbddrivers/linuxinput/linuxinput.pro @@ -0,0 +1,14 @@ +TARGET = qlinuxinputkbddriver +include(../../qpluginbase.pri) + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/kbddrivers +target.path = $$[QT_INSTALL_PLUGINS]/kbddrivers +INSTALLS += target + +DEFINES += QT_QWS_KBD_LINUXINPUT + +HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qkbdlinuxinput_qws.h + +SOURCES = main.cpp \ + $$QT_SOURCE_TREE/src/gui/embedded/qkbdlinuxinput_qws.cpp + diff --git a/src/plugins/kbddrivers/usb/main.cpp b/src/plugins/kbddrivers/linuxinput/main.cpp index 1d6ab89..45d06c4 100644 --- a/src/plugins/kbddrivers/usb/main.cpp +++ b/src/plugins/kbddrivers/linuxinput/main.cpp @@ -40,38 +40,38 @@ ****************************************************************************/ #include <qkbddriverplugin_qws.h> -#include <qkbdusb_qws.h> +#include <qkbdlinuxinput_qws.h> QT_BEGIN_NAMESPACE -class QUsbKbdDriver : public QKbdDriverPlugin +class QLinuxInputKbdDriver : public QKbdDriverPlugin { public: - QUsbKbdDriver(); + QLinuxInputKbdDriver(); QStringList keys() const; QWSKeyboardHandler* create(const QString &driver, const QString &device); }; -QUsbKbdDriver::QUsbKbdDriver() +QLinuxInputKbdDriver::QLinuxInputKbdDriver() : QKbdDriverPlugin() { } -QStringList QUsbKbdDriver::keys() const +QStringList QLinuxInputKbdDriver::keys() const { - return (QStringList() << QLatin1String("Usb")); + return (QStringList() << QLatin1String("LinuxInput")); } -QWSKeyboardHandler* QUsbKbdDriver::create(const QString &driver, - const QString &device) +QWSKeyboardHandler* QLinuxInputKbdDriver::create(const QString &driver, + const QString &device) { Q_UNUSED(device); - if (driver.compare(QLatin1String("Usb"), Qt::CaseInsensitive)) + if (driver.compare(QLatin1String("LinuxInput"), Qt::CaseInsensitive)) return 0; - return new QWSUsbKeyboardHandler(driver); + return new QWSLinuxInputKeyboardHandler(driver, device); } -Q_EXPORT_PLUGIN2(qwsusbkbddriver, QUsbKbdDriver) +Q_EXPORT_PLUGIN2(qwslinuxinputkbddriver, QLinuxInputKbdDriver) QT_END_NAMESPACE diff --git a/src/plugins/kbddrivers/linuxis/README b/src/plugins/kbddrivers/linuxis/README deleted file mode 100644 index 37a9a89..0000000 --- a/src/plugins/kbddrivers/linuxis/README +++ /dev/null @@ -1 +0,0 @@ -This is a keypad/only keyboard driver based on the Linux input subsystem. diff --git a/src/plugins/kbddrivers/linuxis/linuxis.pro b/src/plugins/kbddrivers/linuxis/linuxis.pro deleted file mode 100644 index 5e652b5..0000000 --- a/src/plugins/kbddrivers/linuxis/linuxis.pro +++ /dev/null @@ -1,11 +0,0 @@ -TARGET = linuxiskbdhandler -include(../../qpluginbase.pri) - -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/kbddrivers -target.path = $$[QT_INSTALL_PLUGINS]/kbddrivers -INSTALLS += target - -CONFIG+=no_tr - -HEADERS = linuxiskbddriverplugin.h linuxiskbdhandler.h -SOURCES = linuxiskbddriverplugin.cpp linuxiskbdhandler.cpp diff --git a/src/plugins/kbddrivers/linuxis/linuxiskbddriverplugin.cpp b/src/plugins/kbddrivers/linuxis/linuxiskbddriverplugin.cpp deleted file mode 100644 index 79cd298..0000000 --- a/src/plugins/kbddrivers/linuxis/linuxiskbddriverplugin.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the plugins 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 "linuxiskbddriverplugin.h" -#include "linuxiskbdhandler.h" - -#include <qdebug.h> -#if 1 -#define qLog(x) qDebug() -#else -#define qLog(x) while (0) qDebug() -#endif - -LinuxInputSubsystemKbdDriverPlugin::LinuxInputSubsystemKbdDriverPlugin( QObject *parent ) - : QKbdDriverPlugin( parent ) -{ -} - -LinuxInputSubsystemKbdDriverPlugin::~LinuxInputSubsystemKbdDriverPlugin() -{ -} - -QWSKeyboardHandler* LinuxInputSubsystemKbdDriverPlugin::create(const QString &driver, const QString &device) -{ - if (device.isEmpty()) { - return create( driver ); - } - if( driver.toLower() == "linuxis" || driver.toLower() == "linuxiskbdhandler" ) { - qLog(Input) << "Before call LinuxInputSubsystemKbdHandler(" << device << ")"; - return new LinuxInputSubsystemKbdHandler(device); - } - return 0; -} - -QWSKeyboardHandler* LinuxInputSubsystemKbdDriverPlugin::create( const QString &driver) -{ - if( driver.toLower() == "linuxis" || driver.toLower() == "linuxiskbdhandler" ) { - qLog(Input) << "Before call LinuxInputSubsystemKbdHandler()"; - return new LinuxInputSubsystemKbdHandler(); - } - return 0; -} - -QStringList LinuxInputSubsystemKbdDriverPlugin::keys() const -{ - return QStringList() << "linuxis" << "linuxiskbdhandler"; -} - -Q_EXPORT_PLUGIN2(qwslinuxiskbdhandler, LinuxInputSubsystemKbdDriverPlugin) diff --git a/src/plugins/kbddrivers/linuxis/linuxiskbddriverplugin.h b/src/plugins/kbddrivers/linuxis/linuxiskbddriverplugin.h deleted file mode 100644 index b5f599f..0000000 --- a/src/plugins/kbddrivers/linuxis/linuxiskbddriverplugin.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the plugins 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$ -** -****************************************************************************/ - -#ifndef LINUXISKBDDRIVERPLUGIN_H -#define LINUXISKBDDRIVERPLUGIN_H - -#include <QtGui/QWSKeyboardHandlerFactoryInterface> - -class LinuxInputSubsystemKbdDriverPlugin : public QKbdDriverPlugin { - Q_OBJECT -public: - LinuxInputSubsystemKbdDriverPlugin( QObject *parent = 0 ); - ~LinuxInputSubsystemKbdDriverPlugin(); - - QWSKeyboardHandler* create(const QString& driver, const QString& device); - QWSKeyboardHandler* create(const QString& driver); - QStringList keys()const; -}; - -#endif // LINUXISKBDDRIVERPLUGIN_H diff --git a/src/plugins/kbddrivers/linuxis/linuxiskbdhandler.cpp b/src/plugins/kbddrivers/linuxis/linuxiskbdhandler.cpp deleted file mode 100644 index 99b98b7..0000000 --- a/src/plugins/kbddrivers/linuxis/linuxiskbdhandler.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the plugins 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 "linuxiskbdhandler.h" - -#include <QSocketNotifier> - -#include <stdlib.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> - -#include <linux/input.h> -#include <linux/kd.h> - -#include <qdebug.h> -#if 1 -#define qLog(x) qDebug() -#else -#define qLog(x) while (0) qDebug() -#endif - -struct LinuxInputSubsystemKbdHandler::keytable_s LinuxInputSubsystemKbdHandler::keytable[] = { - { KEY_PAGEDOWN, 0xffff, Qt::Key_Context1 }, - { KEY_END, 0xffff, Qt::Key_Back }, - { KEY_RIGHTCTRL, 0xffff, Qt::Key_Home }, - { KEY_SPACE, 0xffff, Qt::Key_Menu }, - { KEY_ENTER, 0xffff, Qt::Key_Select }, - { KEY_UP, 0xffff, Qt::Key_Up }, - { KEY_LEFT, 0xffff, Qt::Key_Left }, - { KEY_RIGHT, 0xffff, Qt::Key_Right }, - { KEY_DOWN, 0xffff, Qt::Key_Down }, - { KEY_POWER, 0xffff, Qt::Key_Call }, - { KEY_BACKSPACE, 0xffff, Qt::Key_Backspace }, - { KEY_F1, 0xffff, Qt::Key_Hangup }, - { KEY_KP1, '1', Qt::Key_1 }, - { KEY_KP2, '2', Qt::Key_2 }, - { KEY_KP3, '3', Qt::Key_3 }, - { KEY_KP4, '4', Qt::Key_4 }, - { KEY_KP5, '5', Qt::Key_5 }, - { KEY_KP6, '6', Qt::Key_6 }, - { KEY_KP7, '7', Qt::Key_7 }, - { KEY_KP8, '8', Qt::Key_8 }, - { KEY_KP9, '9', Qt::Key_9 }, - { KEY_KP0, '0', Qt::Key_0 }, - { KEY_APOSTROPHE, '*', Qt::Key_Asterisk }, - { KEY_3, '#', Qt::Key_NumberSign }, - { KEY_F2, 0xffff, Qt::Key_F2 }, - { KEY_F3, 0xffff, Qt::Key_F3 }, - { KEY_F4, 0xffff, Qt::Key_F4 }, - { KEY_F5, 0xffff, Qt::Key_F5 }, - { KEY_F6, 0xffff, Qt::Key_F6 }, - { KEY_F7, 0xffff, Qt::Key_VolumeUp }, - { KEY_F8, 0xffff, Qt::Key_VolumeDown }, - { KEY_F9, 0xffff, Qt::Key_F9 }, - { 0, 0, Qt::Key_unknown }, -}; - -struct LinuxInputSubsystemKbdHandler::keymap_s LinuxInputSubsystemKbdHandler::keymap[KEY_MAX]; - -LinuxInputSubsystemKbdHandler::LinuxInputSubsystemKbdHandler(const QString &device) -{ - qLog(Input) << "Loaded LinuxInputSubsystem keypad plugin!"; - setObjectName( "LinuxInputSubsystem Keypad Handler" ); - kbdFD = ::open(device.toLocal8Bit().constData(), O_RDONLY, 0); - if (kbdFD >= 0) { - qLog(Input) << "Opened" << device << "as keypad input"; -#if 0 - struct kbd_repeat kbdrep; - kbdrep.delay = 500; /* ms */ - kbdrep.period = 250; /* ms */ - ioctl(kbdFD, KDKBDREP, &kbdrep); -#endif - m_notify = new QSocketNotifier( kbdFD, QSocketNotifier::Read, this ); - connect( m_notify, SIGNAL(activated(int)), this, SLOT(readKbdData())); - } else { - qWarning("Cannot open '%s' for keypad (%s)", - device.toLocal8Bit().constData(), strerror(errno)); - return; - } - shift = false; - - initmap(); -} - -LinuxInputSubsystemKbdHandler::~LinuxInputSubsystemKbdHandler() -{ -} - -void LinuxInputSubsystemKbdHandler::initmap() -{ - for (int i = 0; i < KEY_MAX; i++) { - keymap[i].unicode = 0xffff; - keymap[i].keycode = Qt::Key_unknown; - } - for (int i = 0; keytable[i].unicode; i++) { - int idx = keytable[i].code; - keymap[idx].unicode = keytable[i].unicode; - keymap[idx].keycode = keytable[i].keycode; - } -} - -void LinuxInputSubsystemKbdHandler::readKbdData() -{ - struct input_event *ie; - struct input_event iebuf[32]; - - uint n = ::read(kbdFD, iebuf, sizeof(iebuf)); - - bool pressed; - bool autorepeat; - int modifiers = 0; - int unicode, keycode; - - n /= sizeof(struct input_event); - ie = iebuf; - for (uint i = 0; i < n; i++) { - - pressed = ie->value != 0; - autorepeat = ie->value == 2; - qLog() << "keyEvent" << hex << ie->type << ie->code << ie->value; - unicode = keymap[ie->code].unicode; - keycode = keymap[ie->code].keycode; - - processKeyEvent(unicode, keycode, (Qt::KeyboardModifiers)modifiers, - pressed, autorepeat); - - ie++; - } - -} - diff --git a/src/plugins/kbddrivers/linuxis/linuxiskbdhandler.h b/src/plugins/kbddrivers/linuxis/linuxiskbdhandler.h deleted file mode 100644 index 3211309..0000000 --- a/src/plugins/kbddrivers/linuxis/linuxiskbdhandler.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the plugins 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$ -** -****************************************************************************/ - -#ifndef LINUXISKBDHANDLER_H -#define LINUXISKBDHANDLER_H - -#include <QObject> -#include <QWSKeyboardHandler> - -class QSocketNotifier; -class LinuxInputSubsystemKbdHandler : public QObject, public QWSKeyboardHandler { - Q_OBJECT -public: - LinuxInputSubsystemKbdHandler(const QString &device = QString("/dev/input/event0")); - ~LinuxInputSubsystemKbdHandler(); - - struct keytable_s { - int code; - int unicode; - int keycode; - }; - - struct keymap_s { - int unicode; - int keycode; - }; - -private: - void initmap(); - - QSocketNotifier *m_notify; - int kbdFD; - bool shift; - - static struct keytable_s keytable[]; - static struct keymap_s keymap[]; - -private Q_SLOTS: - void readKbdData(); -}; - -#endif // LINUXISKBDHANDLER_H diff --git a/src/plugins/kbddrivers/usb/usb.pro b/src/plugins/kbddrivers/usb/usb.pro deleted file mode 100644 index 4187255..0000000 --- a/src/plugins/kbddrivers/usb/usb.pro +++ /dev/null @@ -1,14 +0,0 @@ -TARGET = qusbkbddriver -include(../../qpluginbase.pri) - -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/kbddrivers -target.path = $$[QT_INSTALL_PLUGINS]/kbddrivers -INSTALLS += target - -DEFINES += QT_QWS_KBD_USB - -HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qkbdusb_qws.h - -SOURCES = main.cpp \ - $$QT_SOURCE_TREE/src/gui/embedded/qkbdusb_qws.cpp - diff --git a/tools/kmap2qmap/kmap2qmap.pro b/tools/kmap2qmap/kmap2qmap.pro new file mode 100644 index 0000000..cc8200b --- /dev/null +++ b/tools/kmap2qmap/kmap2qmap.pro @@ -0,0 +1,12 @@ + +TEMPLATE = app +DESTDIR = ../../bin +QT = core +CONFIG += console +CONFIG -= app_bundle + +DEPENDPATH += $$QT_SOURCE_TREE/src/gui/embedded +INCLUDEPATH += $$QT_SOURCE_TREE/src/gui/embedded + +# Input +SOURCES += main.cpp diff --git a/tools/kmap2qmap/main.cpp b/tools/kmap2qmap/main.cpp new file mode 100644 index 0000000..5e80b23 --- /dev/null +++ b/tools/kmap2qmap/main.cpp @@ -0,0 +1,948 @@ +#include <cstdio> + +#include <QFile> +#include <QFileInfo> +#include <QDir> +#include <QTextCodec> +#include <QList> +#include <QVector> +#include <QByteArray> +#include <QStringList> +#include <QTextStream> + +#include "qkbd_qws_p.h" + +using namespace std; + + +struct modifier_map_t { + const char *symbol; + quint8 modifier; + quint32 qtmodifier; +}; + +static const struct modifier_map_t modifier_map[] = { + { "plain", QWSKeyboard::ModPlain, Qt::NoModifier }, + { "shift", QWSKeyboard::ModShift, Qt::ShiftModifier }, + { "altgr", QWSKeyboard::ModAltGr, Qt::AltModifier }, + { "control", QWSKeyboard::ModControl, Qt::ControlModifier }, + { "alt", QWSKeyboard::ModAlt, Qt::AltModifier }, + { "meta", QWSKeyboard::ModAlt, Qt::AltModifier }, + { "shiftl", QWSKeyboard::ModShiftL, Qt::ShiftModifier }, + { "shiftr", QWSKeyboard::ModShiftR, Qt::ShiftModifier }, + { "ctrll", QWSKeyboard::ModCtrlL, Qt::ControlModifier }, + { "ctrlr", QWSKeyboard::ModCtrlR, Qt::ControlModifier }, +}; + +static const int modifier_map_size = sizeof(modifier_map)/sizeof(modifier_map_t); + + +struct symbol_map_t { + const char *symbol; + quint32 qtcode; +}; + +static const struct symbol_map_t symbol_map[] = { + { "space", Qt::Key_Space }, + { "exclam", Qt::Key_Exclam }, + { "quotedbl", Qt::Key_QuoteDbl }, + { "numbersign", Qt::Key_NumberSign }, + { "dollar", Qt::Key_Dollar }, + { "percent", Qt::Key_Percent }, + { "ampersand", Qt::Key_Ampersand }, + { "apostrophe", Qt::Key_Apostrophe }, + { "parenleft", Qt::Key_ParenLeft }, + { "parenright", Qt::Key_ParenRight }, + { "asterisk", Qt::Key_Asterisk }, + { "plus", Qt::Key_Plus }, + { "comma", Qt::Key_Comma }, + { "minus", Qt::Key_Minus }, + { "period", Qt::Key_Period }, + { "slash", Qt::Key_Slash }, + { "zero", Qt::Key_0 }, + { "one", Qt::Key_1 }, + { "two", Qt::Key_2 }, + { "three", Qt::Key_3 }, + { "four", Qt::Key_4 }, + { "five", Qt::Key_5 }, + { "six", Qt::Key_6 }, + { "seven", Qt::Key_7 }, + { "eight", Qt::Key_8 }, + { "nine", Qt::Key_9 }, + { "colon", Qt::Key_Colon }, + { "semicolon", Qt::Key_Semicolon }, + { "less", Qt::Key_Less }, + { "equal", Qt::Key_Equal }, + { "greater", Qt::Key_Greater }, + { "question", Qt::Key_Question }, + { "at", Qt::Key_At }, + { "bracketleft", Qt::Key_BracketLeft }, + { "backslash", Qt::Key_Backslash }, + { "bracketright", Qt::Key_BracketRight }, + { "asciicircum", Qt::Key_AsciiCircum }, + { "underscore", Qt::Key_Underscore }, + { "grave", Qt::Key_QuoteLeft }, + { "braceleft", Qt::Key_BraceLeft }, + { "bar", Qt::Key_Bar }, + { "braceright", Qt::Key_BraceRight }, + { "asciitilde", Qt::Key_AsciiTilde }, + { "nobreakspace", Qt::Key_nobreakspace }, + { "exclamdown", Qt::Key_exclamdown }, + { "cent", Qt::Key_cent }, + { "sterling", Qt::Key_sterling }, + { "currency", Qt::Key_currency }, + { "yen", Qt::Key_yen }, + { "brokenbar", Qt::Key_brokenbar }, + { "section", Qt::Key_section }, + { "diaeresis", Qt::Key_diaeresis }, + { "copyright", Qt::Key_copyright }, + { "ordfeminine", Qt::Key_ordfeminine }, + { "guillemotleft", Qt::Key_guillemotleft }, + { "notsign", Qt::Key_notsign }, + { "hyphen", Qt::Key_hyphen }, + { "registered", Qt::Key_registered }, + { "macron", Qt::Key_macron }, + { "degree", Qt::Key_degree }, + { "plusminus", Qt::Key_plusminus }, + { "twosuperior", Qt::Key_twosuperior }, + { "threesuperior", Qt::Key_threesuperior }, + { "acute", Qt::Key_acute }, + { "mu", Qt::Key_mu }, + { "paragraph", Qt::Key_paragraph }, + { "periodcentered", Qt::Key_periodcentered }, + { "cedilla", Qt::Key_cedilla }, + { "onesuperior", Qt::Key_onesuperior }, + { "masculine", Qt::Key_masculine }, + { "guillemotright", Qt::Key_guillemotright }, + { "onequarter", Qt::Key_onequarter }, + { "onehalf", Qt::Key_onehalf }, + { "threequarters", Qt::Key_threequarters }, + { "questiondown", Qt::Key_questiondown }, + { "Agrave", Qt::Key_Agrave }, + { "Aacute", Qt::Key_Aacute }, + { "Acircumflex", Qt::Key_Acircumflex }, + { "Atilde", Qt::Key_Atilde }, + { "Adiaeresis", Qt::Key_Adiaeresis }, + { "Aring", Qt::Key_Aring }, + { "AE", Qt::Key_AE }, + { "Ccedilla", Qt::Key_Ccedilla }, + { "Egrave", Qt::Key_Egrave }, + { "Eacute", Qt::Key_Eacute }, + { "Ecircumflex", Qt::Key_Ecircumflex }, + { "Ediaeresis", Qt::Key_Ediaeresis }, + { "Igrave", Qt::Key_Igrave }, + { "Iacute", Qt::Key_Iacute }, + { "Icircumflex", Qt::Key_Icircumflex }, + { "Idiaeresis", Qt::Key_Idiaeresis }, + { "ETH", Qt::Key_ETH }, + { "Ntilde", Qt::Key_Ntilde }, + { "Ograve", Qt::Key_Ograve }, + { "Oacute", Qt::Key_Oacute }, + { "Ocircumflex", Qt::Key_Ocircumflex }, + { "Otilde", Qt::Key_Otilde }, + { "Odiaeresis", Qt::Key_Odiaeresis }, + { "multiply", Qt::Key_multiply }, + { "Ooblique", Qt::Key_Ooblique }, + { "Ugrave", Qt::Key_Ugrave }, + { "Uacute", Qt::Key_Uacute }, + { "Ucircumflex", Qt::Key_Ucircumflex }, + { "Udiaeresis", Qt::Key_Udiaeresis }, + { "Yacute", Qt::Key_Yacute }, + { "THORN", Qt::Key_THORN }, + { "ssharp", Qt::Key_ssharp }, + + { "agrave", 0xe0 /*Qt::Key_agrave*/ }, + { "aacute", 0xe1 /*Qt::Key_aacute*/ }, + { "acircumflex", 0xe2 /*Qt::Key_acircumflex*/ }, + { "atilde", 0xe3 /*Qt::Key_atilde*/ }, + { "adiaeresis", 0xe4 /*Qt::Key_adiaeresis*/ }, + { "aring", 0xe5 /*Qt::Key_aring*/ }, + { "ae", 0xe6 /*Qt::Key_ae*/ }, + { "ccedilla", 0xe7 /*Qt::Key_ccedilla*/ }, + { "egrave", 0xe8 /*Qt::Key_egrave*/ }, + { "eacute", 0xe9 /*Qt::Key_eacute*/ }, + { "ecircumflex", 0xea /*Qt::Key_ecircumflex*/ }, + { "ediaeresis", 0xeb /*Qt::Key_ediaeresis*/ }, + { "igrave", 0xec /*Qt::Key_igrave*/ }, + { "iacute", 0xed /*Qt::Key_iacute*/ }, + { "icircumflex", 0xee /*Qt::Key_icircumflex*/ }, + { "idiaeresis", 0xef /*Qt::Key_idiaeresis*/ }, + { "eth", 0xf0 /*Qt::Key_eth*/ }, + { "ntilde", 0xf1 /*Qt::Key_ntilde*/ }, + { "ograve", 0xf2 /*Qt::Key_ograve*/ }, + { "oacute", 0xf3 /*Qt::Key_oacute*/ }, + { "ocircumflex", 0xf4 /*Qt::Key_ocircumflex*/ }, + { "otilde", 0xf5 /*Qt::Key_otilde*/ }, + { "odiaeresis", 0xf6 /*Qt::Key_odiaeresis*/ }, + { "division", Qt::Key_division }, + { "oslash", 0xf8 /*Qt::Key_oslash*/ }, + { "ugrave", 0xf9 /*Qt::Key_ugrave*/ }, + { "uacute", 0xfa /*Qt::Key_uacute*/ }, + { "ucircumflex", 0xfb /*Qt::Key_ucircumflex*/ }, + { "udiaeresis", 0xfc /*Qt::Key_udiaeresis*/ }, + { "yacute", 0xfd /*Qt::Key_yacute*/ }, + { "thorn", 0xfe /*Qt::Key_thorn*/ }, + { "ydiaeresis", Qt::Key_ydiaeresis }, + + { "F1", Qt::Key_F1 }, + { "F2", Qt::Key_F2 }, + { "F3", Qt::Key_F3 }, + { "F4", Qt::Key_F4 }, + { "F5", Qt::Key_F5 }, + { "F6", Qt::Key_F6 }, + { "F7", Qt::Key_F7 }, + { "F8", Qt::Key_F8 }, + { "F9", Qt::Key_F9 }, + { "F10", Qt::Key_F10 }, + { "F11", Qt::Key_F11 }, + { "F12", Qt::Key_F12 }, + { "F13", Qt::Key_F13 }, + { "F14", Qt::Key_F14 }, + { "F15", Qt::Key_F15 }, + { "F16", Qt::Key_F16 }, + { "F17", Qt::Key_F17 }, + { "F18", Qt::Key_F18 }, + { "F19", Qt::Key_F19 }, + { "F20", Qt::Key_F20 }, + { "F21", Qt::Key_F21 }, + { "F22", Qt::Key_F22 }, + { "F23", Qt::Key_F23 }, + { "F24", Qt::Key_F24 }, + { "F25", Qt::Key_F25 }, + { "F26", Qt::Key_F26 }, + { "F27", Qt::Key_F27 }, + { "F28", Qt::Key_F28 }, + { "F29", Qt::Key_F29 }, + { "F30", Qt::Key_F30 }, + { "F31", Qt::Key_F31 }, + { "F32", Qt::Key_F32 }, + { "F33", Qt::Key_F33 }, + { "F34", Qt::Key_F34 }, + { "F35", Qt::Key_F35 }, + + { "BackSpace", Qt::Key_Backspace }, + { "Tab", Qt::Key_Tab }, + { "Escape", Qt::Key_Escape }, + { "Delete", Qt::Key_Backspace }, // what's the difference between "Delete" and "BackSpace"?? + { "Return", Qt::Key_Return }, + { "Break", Qt::Key_unknown }, //TODO: why doesn't Qt support the 'Break' key? + { "Caps_Lock", Qt::Key_CapsLock }, + { "Num_Lock", Qt::Key_NumLock }, + { "Scroll_Lock", Qt::Key_ScrollLock }, + { "Caps_On", Qt::Key_CapsLock }, + { "Compose", Qt::Key_Multi_key }, + { "Bare_Num_Lock", Qt::Key_NumLock }, + { "Find", Qt::Key_Home }, + { "Insert", Qt::Key_Insert }, + { "Remove", Qt::Key_Delete }, + { "Select", Qt::Key_End }, + { "Prior", Qt::Key_PageUp }, + { "Next", Qt::Key_PageDown }, + { "Help", Qt::Key_Help }, + { "Pause", Qt::Key_Pause }, + + { "KP_0", Qt::Key_0 | Qt::KeypadModifier }, + { "KP_1", Qt::Key_1 | Qt::KeypadModifier }, + { "KP_2", Qt::Key_2 | Qt::KeypadModifier }, + { "KP_3", Qt::Key_3 | Qt::KeypadModifier }, + { "KP_4", Qt::Key_4 | Qt::KeypadModifier }, + { "KP_5", Qt::Key_5 | Qt::KeypadModifier }, + { "KP_6", Qt::Key_6 | Qt::KeypadModifier }, + { "KP_7", Qt::Key_7 | Qt::KeypadModifier }, + { "KP_8", Qt::Key_8 | Qt::KeypadModifier }, + { "KP_9", Qt::Key_9 | Qt::KeypadModifier }, + { "KP_Add", Qt::Key_Plus | Qt::KeypadModifier }, + { "KP_Subtract", Qt::Key_Minus | Qt::KeypadModifier }, + { "KP_Multiply", Qt::Key_Asterisk | Qt::KeypadModifier }, + { "KP_Divide", Qt::Key_Slash | Qt::KeypadModifier }, + { "KP_Enter", Qt::Key_Enter | Qt::KeypadModifier }, + { "KP_Comma", Qt::Key_Comma | Qt::KeypadModifier }, + { "KP_Period", Qt::Key_Period | Qt::KeypadModifier }, + { "KP_MinPlus", Qt::Key_plusminus | Qt::KeypadModifier }, + + { "dead_grave", Qt::Key_Dead_Grave }, + { "dead_acute", Qt::Key_Dead_Acute }, + { "dead_circumflex", Qt::Key_Dead_Circumflex }, + { "dead_tilde", Qt::Key_Dead_Tilde }, + { "dead_diaeresis", Qt::Key_Dead_Diaeresis }, + { "dead_cedilla", Qt::Key_Dead_Cedilla }, + + { "Down", Qt::Key_Down }, + { "Left", Qt::Key_Left }, + { "Right", Qt::Key_Right }, + { "Up", Qt::Key_Up }, + { "Shift", Qt::Key_Shift }, + { "AltGr", Qt::Key_AltGr }, + { "Control", Qt::Key_Control }, + { "Alt", Qt::Key_Alt }, + { "ShiftL", Qt::Key_Shift }, + { "ShiftR", Qt::Key_Shift }, + { "CtrlL", Qt::Key_Control }, + { "CtrlR", Qt::Key_Control }, +}; + +static const int symbol_map_size = sizeof(symbol_map)/sizeof(symbol_map_t); + + +struct symbol_dead_unicode_t { + quint32 dead; + quint16 unicode; +}; + +static const symbol_dead_unicode_t symbol_dead_unicode[] = { + { Qt::Key_Dead_Grave, '`' }, + { Qt::Key_Dead_Acute, '\'' }, + { Qt::Key_Dead_Circumflex, '^' }, + { Qt::Key_Dead_Tilde, '~' }, + { Qt::Key_Dead_Diaeresis, '"' }, + { Qt::Key_Dead_Cedilla, ',' }, +}; + +static const int symbol_dead_unicode_size = sizeof(symbol_dead_unicode)/sizeof(symbol_dead_unicode_t); + + +struct symbol_synonyms_t { + const char *from; + const char *to; +}; + +static const symbol_synonyms_t symbol_synonyms[] = { + { "Control_h", "BackSpace" }, + { "Control_i", "Tab" }, + { "Control_j", "Linefeed" }, + { "Home", "Find" }, + { "End", "Select" }, + { "PageUp", "Prior" }, + { "PageDown", "Next" }, + { "multiplication", "multiply" }, + { "pound", "sterling" }, + { "pilcrow", "paragraph" }, + { "Oslash", "Ooblique" }, + { "Shift_L", "ShiftL" }, + { "Shift_R", "ShiftR" }, + { "Control_L", "CtrlL" }, + { "Control_R", "CtrlR" }, + { "AltL", "Alt" }, + { "AltR", "AltGr" }, + { "Alt_L", "Alt" }, + { "Alt_R", "AltGr" }, + { "AltGr_L", "Alt" }, + { "AltGr_R", "AltGr" }, + { "tilde", "asciitilde" }, + { "circumflex", "asciicircum" }, + { "dead_ogonek", "dead_cedilla" }, + { "dead_caron", "dead_circumflex" }, + { "dead_breve", "dead_tilde" }, + { "dead_doubleacute", "dead_tilde" }, + { "no-break_space", "nobreakspace" }, + { "paragraph_sign", "section" }, + { "soft_hyphen", "hyphen" }, + { "rightanglequote", "guillemotright" }, +}; + +static const int symbol_synonyms_size = sizeof(symbol_synonyms)/sizeof(symbol_synonyms_t); + +// makes the generated array in --header mode a bit more human readable +static bool operator<(const QWSKeyboard::Mapping &m1, const QWSKeyboard::Mapping &m2) +{ + return m1.keycode != m2.keycode ? m1.keycode < m2.keycode : m1.modifiers < m2.modifiers; +} + +class KeymapParser { +public: + KeymapParser(); + ~KeymapParser(); + + bool parseKmap(QFile *kmap); + bool generateQmap(QFile *qmap); + bool generateHeader(QFile *qmap); + + int parseWarningCount() const { return m_warning_count; } + +private: + bool parseSymbol(const QByteArray &str, const QTextCodec *codec, quint16 &unicode, quint32 &qtcode, quint8 &flags, quint16 &special); + bool parseCompose(const QByteArray &str, const QTextCodec *codec, quint16 &unicode); + bool parseModifier(const QByteArray &str, quint8 &modifier); + + void updateMapping(quint16 keycode = 0, quint8 modifiers = 0, quint16 unicode = 0xffff, quint32 qtcode = Qt::Key_unknown, quint8 flags = 0, quint16 = 0); + + static quint32 toQtModifiers(quint8 modifiers); + static QList<QByteArray> tokenize(const QByteArray &line); + + +private: + QList<QWSKeyboard::Mapping> m_keymap; + QList<QWSKeyboard::Composing> m_keycompose; + + int m_warning_count; +}; + + + +int main(int argc, char **argv) +{ + int header = 0; + if (argc >= 2 && !qstrcmp(argv[1], "--header")) + header = 1; + + if (argc < (3 + header)) { + fprintf(stderr, "Usage: kmap2qmap [--header] <kmap> [<additional kmaps> ...] <qmap>\n"); + fprintf(stderr, " --header can be used to generate Qt's default compiled in qmap.\n"); + return 1; + } + + QVector<QFile *> kmaps(argc - header - 2); + for (int i = 0; i < kmaps.size(); ++i) { + kmaps [i] = new QFile(QString::fromLocal8Bit(argv[i + 1 + header])); + + if (!kmaps[i]->open(QIODevice::ReadOnly)) { + fprintf(stderr, "Could not read from '%s'.\n", argv[i + 1 + header]); + return 2; + } + } + QFile *qmap = new QFile(QString::fromLocal8Bit(argv[argc - 1])); + + if (!qmap->open(QIODevice::WriteOnly)) { + fprintf(stderr, "Could not write to '%s'.\n", argv[argc - 1]); + return 3; + } + + KeymapParser p; + + for (int i = 0; i < kmaps.size(); ++i) { + if (!p.parseKmap(kmaps[i])) { + fprintf(stderr, "Parsing kmap '%s' failed.\n", qPrintable(kmaps[i]->fileName())); + return 4; + } + } + + if (p.parseWarningCount()) { + fprintf(stderr, "\nParsing the specified keymap(s) produced %d warning(s).\n" \ + "Your generated qmap might not be complete.\n", \ + p.parseWarningCount()); + } + if (!(header ? p.generateHeader(qmap) : p.generateQmap(qmap))) { + fprintf(stderr, "Generating the qmap failed.\n"); + return 5; + } + + qDeleteAll(kmaps); + delete qmap; + + return 0; +} + + +KeymapParser::KeymapParser() + : m_warning_count(0) +{ } + + +KeymapParser::~KeymapParser() +{ } + + +bool KeymapParser::generateHeader(QFile *f) +{ + QTextStream ts(f); + + ts << "#ifndef QWSKEYBOARDHANDLER_DEFAULTMAP_H" << endl; + ts << "#define QWSKEYBOARDHANDLER_DEFAULTMAP_H" << endl << endl; + + ts << "const QWSKeyboard::Mapping QWSKbPrivate::s_keymap_default[] = {" << endl; + + for (int i = 0; i < m_keymap.size(); ++i) { + const QWSKeyboard::Mapping &m = m_keymap.at(i); + QString s; + s.sprintf(" { %3d, 0x%04x, 0x%08x, 0x%02x, 0x%02x, 0x%04x },\n", m.keycode, m.unicode, m.qtcode, m.modifiers, m.flags, m.special); + ts << s; + } + + ts << "};" << endl << endl; + + ts << "const QWSKeyboard::Composing QWSKbPrivate::s_keycompose_default[] = {" << endl; + + for (int i = 0; i < m_keycompose.size(); ++i) { + const QWSKeyboard::Composing &c = m_keycompose.at(i); + QString s; + s.sprintf(" { 0x%04x, 0x%04x, 0x%04x },\n", c.first, c.second, c.result); + ts << s; + } + ts << "};" << endl << endl; + + ts << "#endif" << endl; + + return (ts.status() == QTextStream::Ok); +} + + +bool KeymapParser::generateQmap(QFile *f) +{ + QDataStream ds(f); + + ds << quint32(QWSKeyboard::FileMagic) << quint32(1 /* version */) << quint32(m_keymap.size()) << quint32(m_keycompose.size()); + + if (ds.status() != QDataStream::Ok) + return false; + + for (int i = 0; i < m_keymap.size(); ++i) + ds << m_keymap[i]; + + for (int i = 0; i < m_keycompose.size(); ++i) + ds << m_keycompose[i]; + + return (ds.status() == QDataStream::Ok); +} + + +QList<QByteArray> KeymapParser::tokenize(const QByteArray &line) +{ + bool quoted = false, separator = true; + QList<QByteArray> result; + QByteArray token; + + for (int i = 0; i < line.length(); ++i) { + QChar c = line.at(i); + + if (!quoted && c == '#' && separator) + break; + else if (!quoted && c == '"' && separator) + quoted = true; + else if (quoted && c == '"') + quoted = false; + else if (!quoted && c.isSpace()) { + separator = true; + if (!token.isEmpty()) { + result.append(token); + token.truncate(0); + } + } + else { + separator = false; + token.append(c); + } + } + if (!token.isEmpty()) + result.append(token); + return result; +} + + +#define parseWarning(s) do { qWarning("Warning: keymap file '%s', line %d: %s", qPrintable(f->fileName()), lineno, s); ++m_warning_count; } while (false) + +bool KeymapParser::parseKmap(QFile *f) +{ + QByteArray line; + int lineno = 0; + QList<int> keymaps; + QTextCodec *codec = QTextCodec::codecForName("iso8859-1"); + + for (int i = 0; i <= 256; ++i) + keymaps << i; + + while (!f->atEnd() && !f->error()) { + line = f->readLine(); + lineno++; + + QList<QByteArray> tokens = tokenize(line); + + if (tokens.isEmpty()) + continue; + + if (tokens[0] == "keymaps") { + keymaps.clear(); + + if (tokens.count() > 1) { + foreach (const QByteArray §ion, tokens[1].split(',')) { + int dashpos = section.indexOf('-'); + + //qWarning("Section %s", section.constData()); + int end = section.mid(dashpos + 1).toInt(); + int start = end; + if (dashpos > 0) + start = section.left(dashpos).toInt(); + + if (start <= end && start >=0 && end <= 256) { + for (int i = start; i <= end; ++i) { + //qWarning("appending keymap %d", i); + keymaps.append(i); + } + } + else + parseWarning("keymaps has an invalid range"); + } + qSort(keymaps); + } + else + parseWarning("keymaps with more than one argument"); + } + else if (tokens[0] == "alt_is_meta") { + // simply ignore it for now + } + else if (tokens[0] == "include") { + if (tokens.count() == 2) { + QString incname = QString::fromLocal8Bit(tokens[1]); + bool found = false; + QList<QDir> searchpath; + QFileInfo fi(*f); + + if (!incname.endsWith(QLatin1String(".kmap")) && !incname.endsWith(QLatin1String(".inc"))) + incname.append(QLatin1String(".inc")); + + QDir d = fi.dir(); + searchpath << d; + if (d.cdUp() && d.cd(QLatin1String("include"))) + searchpath << d; + searchpath << QDir::current(); + + foreach (const QDir &path, searchpath) { + QFile f2(path.filePath(incname)); + //qWarning(" -- trying to include %s", qPrintable(f2.fileName())); + if (f2.open(QIODevice::ReadOnly)) { + if (!parseKmap(&f2)) + parseWarning("could not parse keymap include"); + found = true; + } + } + + if (!found) + parseWarning("could not locate keymap include"); + } else + parseWarning("include doesn't have exactly one argument"); + } + else if (tokens[0] == "charset") { + if (tokens.count() == 2) { + codec = QTextCodec::codecForName(tokens[1]); + if (!codec) { + parseWarning("could not parse codec definition"); + codec = QTextCodec::codecForName("iso8859-1"); + } + } else + parseWarning("codec doesn't habe exactly one argument"); + } + else if (tokens[0] == "strings") { + // simply ignore those - they have no meaning for QWS + } + else if (tokens[0] == "compose") { + if (tokens.count() == 5 && tokens[3] == "to") { + QWSKeyboard::Composing c = { 0xffff, 0xffff, 0xffff }; + + if (!parseCompose(tokens[1], codec, c.first)) + parseWarning("could not parse first compose symbol"); + if (!parseCompose(tokens[2], codec, c.second)) + parseWarning("could not parse second compose symbol"); + if (!parseCompose(tokens[4], codec, c.result)) + parseWarning("could not parse resulting compose symbol"); + + if (c.first != 0xffff && c.second != 0xffff && c.result != 0xffff) { + m_keycompose << c; + } + } else + parseWarning("non-standard compose line"); + } + else { + int kcpos = tokens.indexOf("keycode"); + + if (kcpos >= 0 && kcpos < (tokens.count()-3) && tokens[kcpos+2] == "=") { + quint16 keycode = tokens[kcpos+1].toInt(); + + if (keycode <= 0 || keycode > 0x1ff /* KEY_MAX */) { + parseWarning("keycode out of range [0..0x1ff]"); + break; + } + + bool line_modifiers = (kcpos > 0); + + quint8 modifiers = 0; //, modifiers_mask = 0xff; + for (int i = 0; i < kcpos; ++i) { + quint8 mod; + if (!parseModifier(tokens[i], mod)) { + parseWarning("unknown modifier prefix for keycode"); + continue; + } + modifiers |= mod; + } + + int kccount = tokens.count() - kcpos - 3; // 3 : 'keycode' 'X' '=' + + if (line_modifiers && kccount > 1) { + parseWarning("line has modifiers, but more than one keycode"); + break; + } + + // only process one symbol when a prefix modifer was specified + for (int i = 0; i < (line_modifiers ? 1 : kccount); ++i) { + if (!line_modifiers) + modifiers = keymaps[i]; + + quint32 qtcode; + quint16 unicode; + quint16 special; + quint8 flags; + if (!parseSymbol(tokens[i + kcpos + 3], codec, unicode, qtcode, flags, special)) { + parseWarning((QByteArray("symbol could not be parsed: ") + tokens[i + kcpos + 3]).constData()); + break; + } + + if (qtcode == Qt::Key_unknown && unicode == 0xffff) // VoidSymbol + continue; + + if (!line_modifiers && kccount == 1) { + if ((unicode >= 'A' && unicode <= 'Z') || (unicode >= 'a' && unicode <= 'z')) { + quint16 other_unicode = (unicode >= 'A' && unicode <= 'Z') ? unicode - 'A' + 'a' : unicode - 'a' + 'A'; + quint16 lower_unicode = (unicode >= 'A' && unicode <= 'Z') ? unicode - 'A' + 'a' : unicode; + + // a single a-z|A-Z value results in a very flags mapping: see below + + updateMapping(keycode, QWSKeyboard::ModPlain, unicode, qtcode, flags, 0); + + updateMapping(keycode, QWSKeyboard::ModShift, other_unicode, qtcode, flags, 0); + + updateMapping(keycode, QWSKeyboard::ModAltGr, unicode, qtcode, flags, 0); + updateMapping(keycode, QWSKeyboard::ModAltGr | QWSKeyboard::ModShift, other_unicode, qtcode, flags, 0); + + updateMapping(keycode, QWSKeyboard::ModControl, lower_unicode, qtcode | Qt::ControlModifier, flags, 0); + updateMapping(keycode, QWSKeyboard::ModControl | QWSKeyboard::ModShift, lower_unicode, qtcode | Qt::ControlModifier, flags, 0); + updateMapping(keycode, QWSKeyboard::ModControl | QWSKeyboard::ModAltGr, lower_unicode, qtcode | Qt::ControlModifier, flags, 0); + updateMapping(keycode, QWSKeyboard::ModControl | QWSKeyboard::ModAltGr | QWSKeyboard::ModShift, lower_unicode, qtcode | Qt::ControlModifier, flags, 0); + + updateMapping(keycode, QWSKeyboard::ModAlt, unicode, qtcode | Qt::AltModifier, flags, 0); + updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModShift, unicode, qtcode | Qt::AltModifier, flags, 0); + updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModAltGr, unicode, qtcode | Qt::AltModifier, flags, 0); + updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModAltGr | QWSKeyboard::ModShift, unicode, qtcode | Qt::AltModifier, flags, 0); + + updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModControl, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0); + updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModControl | QWSKeyboard::ModShift, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0); + updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModControl | QWSKeyboard::ModAltGr, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0); + updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModControl | QWSKeyboard::ModAltGr | QWSKeyboard::ModShift, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0); + } + else { + // a single value results in that mapping regardless of the modifier + //for (int mod = 0; mod <= 255; ++mod) + // updateMapping(keycode, quint8(mod), unicode, qtcode | toQtModifiers(mod), flags, special); + + // we can save a lot of space in the qmap, since we do that anyway in the kbd handler: + updateMapping(keycode, QWSKeyboard::ModPlain, unicode, qtcode, flags, special); + } + } + else { + // "normal" mapping + updateMapping(keycode, modifiers, unicode, qtcode, flags, special); + } + } + } + } + } + qSort(m_keymap); + return !m_keymap.isEmpty(); +} + + + +void KeymapParser::updateMapping(quint16 keycode, quint8 modifiers, quint16 unicode, quint32 qtcode, quint8 flags, quint16 special) +{ + for (int i = 0; i < m_keymap.size(); ++i) { + QWSKeyboard::Mapping &m = m_keymap[i]; + + if (m.keycode == keycode && m.modifiers == modifiers) { + m.unicode = unicode; + m.qtcode = qtcode; + m.flags = flags; + m.special = special; + return; + } + } + QWSKeyboard::Mapping m = { keycode, unicode, qtcode, modifiers, flags, special }; + m_keymap << m; +} + + +quint32 KeymapParser::toQtModifiers(quint8 modifiers) +{ + quint32 qtmodifiers = Qt::NoModifier; + + for (int i = 0; i < modifier_map_size; ++i) { + if (modifiers & modifier_map[i].modifier) + qtmodifiers |= modifier_map[i].qtmodifier; + } + return qtmodifiers; +} + + +bool KeymapParser::parseModifier(const QByteArray &str, quint8 &modifier) +{ + QByteArray lstr = str.toLower(); + + for (int i = 0; i < modifier_map_size; ++i) { + if (lstr == modifier_map[i].symbol) { + modifier = modifier_map[i].modifier; + return true; + } + } + return false; +} + + +bool KeymapParser::parseCompose(const QByteArray &str, const QTextCodec *codec, quint16 &unicode) +{ + if (str == "'\\''") { + unicode = '\''; + return true; + } else if (str.length() == 3 && str.startsWith('\'') && str.endsWith('\'')) { + QString temp = codec->toUnicode(str.constData() + 1, str.length() - 2); + if (temp.length() != 1) + return false; + unicode = temp[0].unicode(); + return true; + } else { + quint32 code = str.toUInt(); + if (code > 255) + return false; + char c[2]; + c[0] = char(code); + c[1] = 0; + QString temp = codec->toUnicode(c); + if (temp.length() != 1) + return false; + unicode = temp[0].unicode(); + return true; + } +} + + +bool KeymapParser::parseSymbol(const QByteArray &str, const QTextCodec * /*codec*/, quint16 &unicode, quint32 &qtcode, quint8 &flags, quint16 &special) +{ + flags = (str[0] == '+') ? QWSKeyboard::IsLetter : 0; + QByteArray sym = (flags & QWSKeyboard::IsLetter) ? str.right(str.length() - 1) : str; + + special = 0; + qtcode = Qt::Key_unknown; + unicode = 0xffff; + + if (sym == "VoidSymbol" || sym == "nul") + return true; + + bool try_to_find_qtcode = false; + + if (sym[0] >= '0' && sym[0] <= '9') { // kernel internal action number + return false; + } else if (sym.length() == 6 && sym[1] == '+' && (sym[0] == 'U' || sym[0] == 'u')) { // unicode + bool ok; + unicode = sym.mid(2).toUInt(&ok, 16); + if (!ok) + return false; + try_to_find_qtcode = true; + } else { // symbolic + for (int i = 0; i < symbol_synonyms_size; ++i) { + if (sym == symbol_synonyms[i].from) { + sym = symbol_synonyms[i].to; + break; + } + } + + quint32 qtmod = 0; + + // parse prepended modifiers + forever { + int underpos = sym.indexOf('_'); + + if (underpos <= 0) + break; + QByteArray modsym = sym.left(underpos); + QByteArray nomodsym = sym.mid(underpos + 1); + quint8 modifier = 0; + + if (!parseModifier(modsym, modifier)) + break; + + qtmod |= toQtModifiers(modifier); + sym = nomodsym; + } + + if (qtcode == Qt::Key_unknown) { + quint8 modcode; + // check if symbol is a modifier + if (parseModifier(sym, modcode)) { + special = modcode; + flags |= QWSKeyboard::IsModifier; + } + + // map symbol to Qt key code + for (int i = 0; i < symbol_map_size; ++i) { + if (sym == symbol_map[i].symbol) { + qtcode = symbol_map[i].qtcode; + break; + } + } + + // a-zA-Z is not in the table to save space + if (qtcode == Qt::Key_unknown && sym.length() == 1) { + char letter = sym.at(0); + + if (letter >= 'a' && letter <= 'z') { + qtcode = Qt::Key_A + letter - 'a'; + unicode = letter; + } + else if (letter >= 'A' && letter <= 'Z') { + qtcode = Qt::Key_A + letter - 'A'; + unicode = letter; + } + } + // System keys + if (qtcode == Qt::Key_unknown) { + quint16 sys = 0; + + if (sym == "Decr_Console") { + sys = QWSKeyboard::SystemConsolePrevious; + } else if (sym == "Incr_Console") { + sys = QWSKeyboard::SystemConsoleNext; + } else if (sym.startsWith("Console_")) { + int console = sym.mid(8).toInt() - 1; + if (console >= 0 && console <= (QWSKeyboard::SystemConsoleLast - QWSKeyboard::SystemConsoleFirst)) { + sys = QWSKeyboard::SystemConsoleFirst + console; + } + } else if (sym == "Boot") { + sys = QWSKeyboard::SystemReboot; + } else if (sym == "QtZap") { + sys = QWSKeyboard::SystemZap; + } + + if (sys) { + flags |= QWSKeyboard::IsSystem; + special = sys; + qtcode = Qt::Key_Escape; // just a dummy + } + } + + // map Qt key codes in the iso-8859-1 range to unicode + if (qtcode != Qt::Key_unknown && unicode == 0xffff) { + quint32 qtcode_no_mod = qtcode & ~(Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier); + if (qtcode_no_mod <= 0x000000ff) // iso-8859-1 + unicode = quint16(qtcode_no_mod); + } + + // flag dead keys + if (qtcode >= Qt::Key_Dead_Grave && qtcode <= Qt::Key_Dead_Horn) { + flags = QWSKeyboard::IsDead; + + for (int i = 0; i < symbol_dead_unicode_size; ++i) { + if (symbol_dead_unicode[i].dead == qtcode) { + unicode = symbol_dead_unicode[i].unicode; + break; + } + } + } + } + if ((qtcode == Qt::Key_unknown) && (unicode == 0xffff)) + return false; + + qtcode |= qtmod; + } + + // map unicode in the iso-8859-1 range to Qt key codes + if (unicode >= 0x0020 && unicode <= 0x00ff && qtcode == Qt::Key_unknown) + qtcode = unicode; // iso-8859-1 + + return true; +} + diff --git a/tools/tools.pro b/tools/tools.pro index ffc5d63..c76174c 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -22,6 +22,8 @@ mac { SUBDIRS += macdeployqt } +SUBDIRS += kmap2qmap + contains(QT_CONFIG, dbus):SUBDIRS += qdbus !wince*:contains(QT_CONFIG, xmlpatterns): SUBDIRS += xmlpatterns embedded: SUBDIRS += makeqpf |