From c00f366afc08db92ee4d356e6650894332010e0e Mon Sep 17 00:00:00 2001 From: zbych Date: Mon, 7 Jan 2019 21:54:34 +0000 Subject: [PATCH] Bazaar/LinuxFrameBuffer: scancodes to letters translation git-svn-id: svn://ultimatepp.org/upp/trunk@12651 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- bazaar/LinuxFrameBuffer/Events.cpp | 14 +-- bazaar/LinuxFrameBuffer/Keys.cpp | 90 ++++++++++++++----- bazaar/LinuxFrameBuffer/LinuxFrameBuffer.cpp | 36 ++++++++ bazaar/LinuxFrameBuffer/LinuxFrameBuffer.h | 15 +++- bazaar/LinuxFrameBuffer/LinuxFrameBuffer.upp | 5 +- .../LinuxFrameBufferExample.upp | 4 +- bazaar/LinuxFrameBufferExample/test.cpp | 5 -- 7 files changed, 128 insertions(+), 41 deletions(-) delete mode 100644 bazaar/LinuxFrameBufferExample/test.cpp diff --git a/bazaar/LinuxFrameBuffer/Events.cpp b/bazaar/LinuxFrameBuffer/Events.cpp index 8959c22aa..66c0f1931 100644 --- a/bazaar/LinuxFrameBuffer/Events.cpp +++ b/bazaar/LinuxFrameBuffer/Events.cpp @@ -50,11 +50,15 @@ bool LinuxFrameBuffer::ProcessEvent(bool *quit) case KEY_LEFTSHIFT: CHMOD(input.keyboard.modkeys, KM_LSHIFT, pressed); break; case KEY_RIGHTSHIFT: CHMOD(input.keyboard.modkeys, KM_RSHIFT, pressed); break; } - auto upp_key = TranslateKeyEvent(key); - RDUMPHEX(key); - RDUMPHEX(upp_key); - Ctrl::DoKeyFB(upp_key | (!pressed ? K_KEYUP : 0), 1); - + + auto upp_scan = TranslateScanCode(key); + if (upp_scan) Ctrl::DoKeyFB(upp_scan | (!pressed ? K_KEYUP : 0), 1); + else { LOG(Format("Scan code %d was not translated to K_*, see input-event-codes.h", (int)key)); } + + if (pressed){ + WString txt = ScanCodeToUtf8(key).ToWString(); + for (int i = 0; i < txt.GetCount(); i++) Ctrl::DoKeyFB(txt[i], 1); + } } break; diff --git a/bazaar/LinuxFrameBuffer/Keys.cpp b/bazaar/LinuxFrameBuffer/Keys.cpp index a9926c9d5..60b1867a4 100644 --- a/bazaar/LinuxFrameBuffer/Keys.cpp +++ b/bazaar/LinuxFrameBuffer/Keys.cpp @@ -8,15 +8,30 @@ struct{ uint32 b; }static const libinput_key_map[] = { - { K_BACK, KEY_BACK }, { K_BACKSPACE, KEY_BACKSPACE }, { K_TAB, KEY_TAB }, { K_SPACE, KEY_SPACE }, { K_ENTER, KEY_ENTER }, + + { K_GRAVE, KEY_GRAVE }, + { K_MINUS, KEY_MINUS }, + { K_PLUS, KEY_EQUAL }, + { K_LBRACKET, KEY_LEFTBRACE }, + { K_RBRACKET, KEY_RIGHTBRACE }, + { K_BACKSLASH, KEY_BACKSLASH }, + { K_SEMICOLON, KEY_SEMICOLON }, + { K_QUOTEDBL, KEY_APOSTROPHE }, + { K_COMMA, KEY_COMMA }, + { K_PERIOD, KEY_DOT }, + { K_SLASH, KEY_SLASH }, - { K_SHIFT_KEY, KEY_LEFTSHIFT }, - { K_CTRL_KEY, KEY_LEFTCTRL }, - { K_ALT_KEY, KEY_LEFTALT }, + { K_SHIFT_LEFT, KEY_LEFTSHIFT }, + { K_CTRL_LEFT, KEY_LEFTCTRL }, + { K_ALT_LEFT, KEY_LEFTALT }, + + { K_SHIFT_RIGHT, KEY_RIGHTSHIFT}, + { K_CTRL_RIGHT, KEY_RIGHTCTRL}, + { K_ALT_RIGHT, KEY_RIGHTALT}, { K_CAPSLOCK, KEY_CAPSLOCK }, { K_ESCAPE, KEY_ESC }, @@ -31,19 +46,24 @@ struct{ { K_INSERT, KEY_INSERT }, { K_DELETE, KEY_DELETE }, - { K_NUMPAD0, KEY_NUMERIC_0 }, - { K_NUMPAD1, KEY_NUMERIC_1 }, - { K_NUMPAD2, KEY_NUMERIC_2 }, - { K_NUMPAD3, KEY_NUMERIC_3 }, - { K_NUMPAD4, KEY_NUMERIC_4 }, - { K_NUMPAD5, KEY_NUMERIC_5 }, - { K_NUMPAD6, KEY_NUMERIC_6 }, - { K_NUMPAD7, KEY_NUMERIC_7 }, - { K_NUMPAD8, KEY_NUMERIC_8 }, - { K_NUMPAD9, KEY_NUMERIC_9 }, + { K_DIVIDE, KEY_KPSLASH }, + { K_MULTIPLY, KEY_KPASTERISK }, + { K_SUBTRACT, KEY_KPMINUS }, + { K_ADD, KEY_KPPLUS }, + { K_ENTER, KEY_KPENTER }, + { K_DECIMAL, KEY_KPDOT }, + { K_NUMPAD0, KEY_KP0 }, + { K_NUMPAD1, KEY_KP1 }, + { K_NUMPAD2, KEY_KP2 }, + { K_NUMPAD3, KEY_KP3 }, + { K_NUMPAD4, KEY_KP4 }, + { K_NUMPAD5, KEY_KP5 }, + { K_NUMPAD6, KEY_KP6 }, + { K_NUMPAD7, KEY_KP7 }, + { K_NUMPAD8, KEY_KP8 }, + { K_NUMPAD9, KEY_KP9 }, - { K_A, KEY_A }, -// { 'a', KEY_A }, + { K_A, KEY_A }, { K_B, KEY_B }, { K_C, KEY_C }, { K_D, KEY_D }, @@ -79,23 +99,47 @@ struct{ { K_7, KEY_7 }, { K_8, KEY_8 }, { K_9, KEY_9 }, + + { K_F1, KEY_F1 }, + { K_F2, KEY_F2 }, + { K_F3, KEY_F3 }, + { K_F4, KEY_F4 }, + { K_F5, KEY_F5 }, + { K_F6, KEY_F6 }, + { K_F7, KEY_F7 }, + { K_F8, KEY_F8 }, + { K_F9, KEY_F9 }, + { K_F10, KEY_F10 }, + { K_F11, KEY_F11 }, + { K_F12, KEY_F12 }, }; -uint32 LinuxFrameBuffer::TranslateKeyEvent(uint32 chr) +uint32 LinuxFrameBuffer::TranslateScanCode(uint32 chr) { + uint32 out = 0; + for(auto& m : libinput_key_map){ if(chr == m.b){ - chr = m.a; + out = m.a; break; } } - if(chr == K_ALT_KEY || chr == K_CTRL_KEY || chr == K_SHIFT_KEY) return chr; + if(out == K_ALT_KEY || out == K_CTRL_KEY || out == K_SHIFT_KEY) return out; - if(GetCtrl()) chr |= K_CTRL; - if(GetAlt()) chr |= K_ALT; - if(GetShift()) chr |= K_SHIFT; - return chr; + if(GetCtrl()) out |= K_CTRL; + if(GetAlt()) out |= K_ALT; + if(GetShift()) out |= K_SHIFT; + + return out; +} + + +String LinuxFrameBuffer::ScanCodeToUtf8(uint32 chr) +{ + char buff[256]; + auto size = xkb_state_key_get_utf8(input.kb_state, chr + 8, buff, sizeof(buff)); + return String(buff, size); } diff --git a/bazaar/LinuxFrameBuffer/LinuxFrameBuffer.cpp b/bazaar/LinuxFrameBuffer/LinuxFrameBuffer.cpp index 740fd339b..d78d2cf55 100644 --- a/bazaar/LinuxFrameBuffer/LinuxFrameBuffer.cpp +++ b/bazaar/LinuxFrameBuffer/LinuxFrameBuffer.cpp @@ -34,6 +34,21 @@ LinuxFrameBuffer::~LinuxFrameBuffer() void LinuxFrameBuffer::Destroy() { + if (input.kb_state != nullptr){ + xkb_state_unref(input.kb_state); + input.kb_state = nullptr; + } + + if (input.kb_map != nullptr){ + xkb_keymap_unref(input.kb_map); + input.kb_map = nullptr; + } + + if (input.kb_ctx != nullptr){ + xkb_context_unref(input.kb_ctx); + input.kb_ctx = nullptr; + } + if (input.lib_inp != nullptr){ libinput_unref(input.lib_inp); input.lib_inp = nullptr; @@ -100,6 +115,27 @@ bool LinuxFrameBuffer::Create(const char * device) libinput_udev_assign_seat(input.lib_inp, "seat0"); libinput_dispatch(input.lib_inp); + + input.kb_ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + if (input.kb_ctx == nullptr){ + RLOG("xkb context error"); + Destroy(); + return false; + } + + input.kb_map = xkb_keymap_new_from_names(input.kb_ctx, nullptr, XKB_KEYMAP_COMPILE_NO_FLAGS); + if (input.kb_map == nullptr){ + RLOG("xkb map error"); + Destroy(); + return false; + } + + input.kb_state = xkb_state_new(input.kb_map); + if (input.kb_state == nullptr){ + RLOG("xkb state error"); + Destroy(); + return false; + } screen.image.Create(GetSize()); screen.painter.Create(screen.image, MODE_ANTIALIASED); diff --git a/bazaar/LinuxFrameBuffer/LinuxFrameBuffer.h b/bazaar/LinuxFrameBuffer/LinuxFrameBuffer.h index 6348b5bde..03f00fddf 100644 --- a/bazaar/LinuxFrameBuffer/LinuxFrameBuffer.h +++ b/bazaar/LinuxFrameBuffer/LinuxFrameBuffer.h @@ -4,6 +4,8 @@ #include #include #include +#include + namespace Upp { @@ -37,8 +39,12 @@ private: }screen; struct input_t{ - struct udev *udev; - struct libinput *lib_inp; + struct udev *udev; + struct libinput *lib_inp; + + struct xkb_context *kb_ctx; + struct xkb_keymap *kb_map; + struct xkb_state *kb_state; struct mouse_t{ uint32 buttons; @@ -53,10 +59,11 @@ private: keyboard_t(): modkeys(0) {} }keyboard; - input_t(): udev(nullptr), lib_inp(nullptr) {} + input_t(): udev(nullptr), lib_inp(nullptr), kb_ctx(nullptr), kb_map(nullptr), kb_state(nullptr) {} }input; - uint32 TranslateKeyEvent(uint32 chr); + uint32 TranslateScanCode(uint32 chr); + String ScanCodeToUtf8(uint32 chr); public: bool Create(const char * device); diff --git a/bazaar/LinuxFrameBuffer/LinuxFrameBuffer.upp b/bazaar/LinuxFrameBuffer/LinuxFrameBuffer.upp index ad741635b..d0626dedf 100644 --- a/bazaar/LinuxFrameBuffer/LinuxFrameBuffer.upp +++ b/bazaar/LinuxFrameBuffer/LinuxFrameBuffer.upp @@ -1,6 +1,9 @@ description "Linux Frame Buffer backend implemented using VirtualGui\377"; -library(LINUX) "udev input"; +uses + VirtualGui; + +library(LINUX) "udev input xkbcommon"; options(GCC) -Wreturn-type; diff --git a/bazaar/LinuxFrameBufferExample/LinuxFrameBufferExample.upp b/bazaar/LinuxFrameBufferExample/LinuxFrameBufferExample.upp index 73c9a60c0..31d6fad8c 100644 --- a/bazaar/LinuxFrameBufferExample/LinuxFrameBufferExample.upp +++ b/bazaar/LinuxFrameBufferExample/LinuxFrameBufferExample.upp @@ -4,9 +4,7 @@ uses CtrlLib, RichEdit, plugin/DroidFonts, - VirtualGui, - LinuxFrameBuffer, - VirtualGui; + LinuxFrameBuffer; file main.cpp, diff --git a/bazaar/LinuxFrameBufferExample/test.cpp b/bazaar/LinuxFrameBufferExample/test.cpp deleted file mode 100644 index 8437a52ed..000000000 --- a/bazaar/LinuxFrameBufferExample/test.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include - -#include - -void Foo() {} \ No newline at end of file