I’m implementing a virtual keyboard using QML.
So far I literally map the char to print for the different key maps (w/o shift, with shift, with Alt Gr, etc.).
So I have to write down all the chars for different layouts somewhere in the code.
Especially for layouts and languages where two or more key presses generate a more complex char like pressing ` followed by a to get à becomes very nasty.
So I think this is a sub-optimal approach and there is a much cleverer solution to just provide the scan codes (as provided by ‘showkey -s’ in Linux) and to use the systems locale settings to get the correct char printed in let’s say a QQuick LineEdit.
What would be the best/correct way tho pass the scan codes to the system to generate “real” key events and how could I “receive” them in my code.
System is Linux. C++ backend would by fine. Guess QML alone won’t be capable … May It be clever to generate an own keyboard input device for this ?
Or could I inject the scan codes into the existing keyboard device to simulate the presses ?
Advertisement
Answer
Following code derived from
using libevdev
seems to point into the right direction.
It allows to send scan codes to a newly created keyboard device (needs root).
#include <stdio.h> #include <libevdev/libevdev.h> #include <libevdev/libevdev-uinput.h> #include <unistd.h> int main() { int err; struct libevdev *dev; struct libevdev_uinput *uidev; dev = libevdev_new(); libevdev_set_name(dev, "fake keyboard device"); libevdev_enable_event_type(dev, EV_KEY); for(uint key = 1; key < 255; ++key) { libevdev_enable_event_code(dev, EV_KEY, key, nullptr); } err = libevdev_uinput_create_from_device(dev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev); if (err != 0) { return err; } sleep(1); libevdev_uinput_write_event(uidev, EV_KEY, KEY_LEFTSHIFT, 1); libevdev_uinput_write_event(uidev, EV_KEY, KEY_A, 1); //libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0); libevdev_uinput_write_event(uidev, EV_KEY, KEY_A, 0); //libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0); libevdev_uinput_write_event(uidev, EV_KEY, KEY_B, 1); //libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0); libevdev_uinput_write_event(uidev, EV_KEY, KEY_B, 0); //libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0); libevdev_uinput_write_event(uidev, EV_KEY, KEY_LEFTSHIFT, 0); libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0); sleep(1); libevdev_uinput_destroy(uidev); printf("nCompleten"); }