Bazaar/LinuxFrameBuffer: scancodes to letters translation

git-svn-id: svn://ultimatepp.org/upp/trunk@12651 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
zbych 2019-01-07 21:54:34 +00:00
parent e73d5db104
commit c00f366afc
7 changed files with 128 additions and 41 deletions

View file

@ -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;

View file

@ -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);
}

View file

@ -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);

View file

@ -4,6 +4,8 @@
#include <CtrlLib/CtrlLib.h>
#include <Painter/Painter.h>
#include <libinput.h>
#include <xkbcommon/xkbcommon.h>
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);

View file

@ -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;

View file

@ -4,9 +4,7 @@ uses
CtrlLib,
RichEdit,
plugin/DroidFonts,
VirtualGui,
LinuxFrameBuffer,
VirtualGui;
LinuxFrameBuffer;
file
main.cpp,

View file

@ -1,5 +0,0 @@
#include <xmmintrin.h>
#include <SDL.h>
void Foo() {}