qt: Initial xkbcommon keyboard support for X11
This commit is contained in:
4
.ci/build.sh
Executable file → Normal file
4
.ci/build.sh
Executable file → Normal file
@@ -584,7 +584,7 @@ else
|
||||
# ...and the ones we do want listed. Non-dev packages fill missing spots on the list.
|
||||
libpkgs=""
|
||||
longest_libpkg=0
|
||||
for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev
|
||||
for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev
|
||||
do
|
||||
libpkgs="$libpkgs $pkg:$arch_deb"
|
||||
length=$(echo -n $pkg | sed 's/-dev$//' | sed "s/qtdeclarative/qt/" | wc -c)
|
||||
@@ -1014,7 +1014,7 @@ else
|
||||
mkdir -p "$icon_dir"
|
||||
cp -rp "$icon_size" "$icon_dir/apps"
|
||||
done
|
||||
project_icon=$(ls "$icon_base/"[0-9]*x[0-9]*/* | head -1 | grep -oP '/\K([^/]+)(?=\.[^\.]+$)')
|
||||
project_icon=$(find "$icon_base/"[0-9]*x[0-9]*/* -type f -name '*.png' -o -name '*.svg' | head -1 | grep -oP '/\K([^/]+)(?=\.[^\.]+$)')
|
||||
|
||||
# Archive executable, while also stripping it if requested.
|
||||
mkdir -p archive_tmp/usr/local/bin
|
||||
|
0
.ci/static2dll.sh
Executable file → Normal file
0
.ci/static2dll.sh
Executable file → Normal file
@@ -373,6 +373,21 @@ if (UNIX AND NOT APPLE AND NOT HAIKU)
|
||||
target_link_libraries(ui PUBLIC PkgConfig::LIBEVDEV)
|
||||
target_sources(ui PRIVATE evdev_mouse.cpp)
|
||||
endif()
|
||||
pkg_check_modules(XKBCOMMON IMPORTED_TARGET xkbcommon)
|
||||
if (XKBCOMMON_FOUND)
|
||||
target_compile_definitions(ui PRIVATE XKBCOMMON)
|
||||
target_link_libraries(ui PUBLIC PkgConfig::XKBCOMMON)
|
||||
target_sources(ui PRIVATE xkbcommon_keyboard.cpp)
|
||||
|
||||
if (X11_xcb_FOUND)
|
||||
pkg_check_modules(XKBCOMMON_X11 IMPORTED_TARGET xkbcommon-x11)
|
||||
if (XKBCOMMON_X11_FOUND)
|
||||
target_compile_definitions(ui PRIVATE XKBCOMMON_X11)
|
||||
target_link_libraries(ui PRIVATE X11::xcb PUBLIC PkgConfig::XKBCOMMON_X11)
|
||||
target_sources(ui PRIVATE xkbcommon_x11_keyboard.cpp)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(ECM NO_MODULE)
|
||||
if (ECM_FOUND)
|
||||
|
@@ -96,8 +96,11 @@ extern int qt_nvr_save(void);
|
||||
#include "qt_util.hpp"
|
||||
|
||||
#if defined __unix__ && !defined __HAIKU__
|
||||
# ifdef WAYLAND
|
||||
# include "wl_mouse.hpp"
|
||||
# ifdef XKBCOMMON
|
||||
# include "xkbcommon_keyboard.hpp"
|
||||
# ifdef XKBCOMMON_X11
|
||||
# include "xkbcommon_x11_keyboard.hpp"
|
||||
# endif
|
||||
# endif
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/keysym.h>
|
||||
@@ -648,6 +651,11 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
} else {
|
||||
ui->actionCursor_Puck->setChecked(true);
|
||||
}
|
||||
|
||||
#ifdef XKBCOMMON_X11
|
||||
if (QApplication::platformName().contains("xcb"))
|
||||
xkbcommon_x11_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1504,29 +1512,36 @@ x11_keycode_to_keysym(uint32_t keycode)
|
||||
#elif defined(__HAIKU__)
|
||||
finalkeycode = be_to_xt[keycode];
|
||||
#else
|
||||
static Display *x11display = nullptr;
|
||||
if (QApplication::platformName().contains("wayland")) {
|
||||
selected_keycode = x11_to_xt_2;
|
||||
} else if (QApplication::platformName().contains("eglfs")) {
|
||||
keycode -= 8;
|
||||
if (keycode <= 88)
|
||||
finalkeycode = keycode;
|
||||
else
|
||||
finalkeycode = evdev_to_xt[keycode];
|
||||
} else if (!x11display) {
|
||||
x11display = XOpenDisplay(nullptr);
|
||||
if (XKeysymToKeycode(x11display, XK_Home) == 110) {
|
||||
selected_keycode = x11_to_xt_2;
|
||||
} else if (XKeysymToKeycode(x11display, XK_Home) == 69) {
|
||||
selected_keycode = x11_to_xt_vnc;
|
||||
# ifdef XKBCOMMON
|
||||
if (xkbcommon_keymap) {
|
||||
finalkeycode = xkbcommon_translate(keycode);
|
||||
} else
|
||||
# endif
|
||||
{
|
||||
static Display *x11display = nullptr;
|
||||
if (QApplication::platformName().contains("eglfs")) {
|
||||
keycode -= 8;
|
||||
if (keycode <= 88)
|
||||
finalkeycode = keycode;
|
||||
else
|
||||
finalkeycode = evdev_to_xt[keycode];
|
||||
} else {
|
||||
if (QApplication::platformName().contains("wayland")) {
|
||||
selected_keycode = x11_to_xt_2;
|
||||
} else if (!x11display) {
|
||||
x11display = XOpenDisplay(nullptr);
|
||||
if (XKeysymToKeycode(x11display, XK_Home) == 110) {
|
||||
selected_keycode = x11_to_xt_2;
|
||||
} else if (XKeysymToKeycode(x11display, XK_Home) == 69) {
|
||||
selected_keycode = x11_to_xt_vnc;
|
||||
}
|
||||
}
|
||||
finalkeycode = selected_keycode[keycode];
|
||||
}
|
||||
}
|
||||
if (!QApplication::platformName().contains("eglfs"))
|
||||
finalkeycode = selected_keycode[keycode];
|
||||
#endif
|
||||
if (rctrl_is_lalt && finalkeycode == 0x11D) {
|
||||
if (rctrl_is_lalt && finalkeycode == 0x11D)
|
||||
finalkeycode = 0x38;
|
||||
}
|
||||
return finalkeycode;
|
||||
}
|
||||
|
||||
|
258
src/qt/xkbcommon_keyboard.cpp
Normal file
258
src/qt/xkbcommon_keyboard.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* xkbcommon keyboard input module.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2023 RichardG.
|
||||
*/
|
||||
extern "C" {
|
||||
#include <xkbcommon/xkbcommon-x11.h>
|
||||
};
|
||||
|
||||
#include <unordered_map>
|
||||
#include <QtDebug>
|
||||
|
||||
#define IS_HEX_DIGIT(c) ((((c) >= '0') && ((c) <= '9')) || (((c) >= 'A') && ((c) <= 'F')) || (((c) >= 'a') && ((c) <= 'f')))
|
||||
|
||||
std::unordered_map<std::string, uint16_t> xkb_keycodes{
|
||||
{"ESC", 0x01},
|
||||
{"AE01", 0x02},
|
||||
{"AE02", 0x03},
|
||||
{"AE03", 0x04},
|
||||
{"AE04", 0x05},
|
||||
{"AE05", 0x06},
|
||||
{"AE06", 0x07},
|
||||
{"AE07", 0x08},
|
||||
{"AE08", 0x09},
|
||||
{"AE09", 0x0a},
|
||||
{"AE10", 0x0b},
|
||||
{"AE11", 0x0c},
|
||||
{"AE12", 0x0d},
|
||||
{"BKSP", 0x0e},
|
||||
|
||||
{"TAB", 0x0f},
|
||||
{"AD01", 0x10},
|
||||
{"AD02", 0x11},
|
||||
{"AD03", 0x12},
|
||||
{"AD04", 0x13},
|
||||
{"AD05", 0x14},
|
||||
{"AD06", 0x15},
|
||||
{"AD07", 0x16},
|
||||
{"AD08", 0x17},
|
||||
{"AD09", 0x18},
|
||||
{"AD10", 0x19},
|
||||
{"AD11", 0x1a},
|
||||
{"AD12", 0x1b},
|
||||
{"RTRN", 0x1c},
|
||||
|
||||
{"LCTL", 0x1d},
|
||||
{"AC01", 0x1e},
|
||||
{"AC02", 0x1f},
|
||||
{"AC03", 0x20},
|
||||
{"AC04", 0x21},
|
||||
{"AC05", 0x22},
|
||||
{"AC06", 0x23},
|
||||
{"AC07", 0x24},
|
||||
{"AC08", 0x25},
|
||||
{"AC09", 0x26},
|
||||
{"AC10", 0x27},
|
||||
{"AC11", 0x28},
|
||||
|
||||
{"TLDE", 0x29},
|
||||
{"LFSH", 0x2a},
|
||||
{"BKSL", 0x2b},
|
||||
{"AB01", 0x2c},
|
||||
{"AB02", 0x2d},
|
||||
{"AB03", 0x2e},
|
||||
{"AB04", 0x2f},
|
||||
{"AB05", 0x30},
|
||||
{"AB06", 0x31},
|
||||
{"AB07", 0x32},
|
||||
{"AB08", 0x33},
|
||||
{"AB09", 0x34},
|
||||
{"AB10", 0x35},
|
||||
{"RTSH", 0x36},
|
||||
|
||||
{"KPMU", 0x37},
|
||||
{"LALT", 0x38},
|
||||
{"SPCE", 0x39},
|
||||
{"CAPS", 0x3a},
|
||||
{"FK01", 0x3b},
|
||||
{"FK02", 0x3c},
|
||||
{"FK03", 0x3d},
|
||||
{"FK04", 0x3e},
|
||||
{"FK05", 0x3f},
|
||||
{"FK06", 0x40},
|
||||
{"FK07", 0x41},
|
||||
{"FK08", 0x42},
|
||||
{"FK09", 0x43},
|
||||
{"FK10", 0x44},
|
||||
|
||||
{"NMLK", 0x45},
|
||||
{"SCLK", 0x46},
|
||||
{"FK14", 0x46}, /* F14 as Scroll Lock */
|
||||
{"KP7", 0x47},
|
||||
{"KP8", 0x48},
|
||||
{"KP9", 0x49},
|
||||
{"KPSU", 0x4a},
|
||||
{"KP4", 0x4b},
|
||||
{"KP5", 0x4c},
|
||||
{"KP6", 0x4d},
|
||||
{"KPAD", 0x4e},
|
||||
{"KP1", 0x4f},
|
||||
{"KP2", 0x50},
|
||||
{"KP3", 0x51},
|
||||
{"KP0", 0x52},
|
||||
{"KPDL", 0x53},
|
||||
|
||||
{"LSGT", 0x56},
|
||||
{"FK11", 0x57},
|
||||
{"FK12", 0x58},
|
||||
|
||||
/* Japanese keys. */
|
||||
{"HKTG", 0x70}, /* hiragana-katakana toggle... */
|
||||
{"HIRA", 0x70}, /* ...and individual keys */
|
||||
{"KATA", 0x70},
|
||||
{"AB11", 0x73}, /* \_ and Brazilian /? */
|
||||
{"HENK", 0x79},
|
||||
{"MUHE", 0x7b},
|
||||
{"AE13", 0x7d}, /* \| */
|
||||
{"KPPT", 0x7e}, /* Brazilian Num. */
|
||||
{"I06", 0x7e}, /* alias of KPPT on keycodes/xfree86 (i.e. X11 forwarding) */
|
||||
|
||||
/* Korean keys. */
|
||||
{"HJCV", 0xf1}, /* hancha toggle */
|
||||
{"HNGL", 0xf2}, /* latin toggle */
|
||||
|
||||
{"KPEN", 0x11c},
|
||||
{"RCTL", 0x11d},
|
||||
{"KPDV", 0x135},
|
||||
{"PRSC", 0x137},
|
||||
{"SYRQ", 0x137},
|
||||
{"FK13", 0x137}, /* F13 as SysRq */
|
||||
{"RALT", 0x138},
|
||||
{"PAUS", 0x146}, /* special case */
|
||||
{"FK15", 0x146}, /* F15 as Pause */
|
||||
{"HOME", 0x147},
|
||||
{"UP", 0x148},
|
||||
{"PGUP", 0x149},
|
||||
{"LEFT", 0x14b},
|
||||
{"RGHT", 0x14d},
|
||||
{"END", 0x14f},
|
||||
{"DOWN", 0x150},
|
||||
{"PGDN", 0x151},
|
||||
{"INS", 0x152},
|
||||
{"DELE", 0x153},
|
||||
|
||||
{"LWIN", 0x15b},
|
||||
{"RWIN", 0x15c},
|
||||
{"COMP", 0x15d},
|
||||
|
||||
/* Multimedia keys, using Linux evdev-specific keycodes where required. Guideline is to try
|
||||
and follow the Microsoft standard, then fill in some OEM-specific keys for redundancy sake.
|
||||
Keys marked with # are not translated into evdev codes by the standard atkbd driver. */
|
||||
{"KPEQ", 0x59}, /* Num= */
|
||||
{"FRNT", 0x101}, /* # Logitech Task Select */
|
||||
{"I224", 0x105}, /* CHAT# => Messenger/Files */
|
||||
{"I190", 0x107}, /* REDO */
|
||||
{"UNDO", 0x108},
|
||||
{"PAST", 0x10a}, /* # Paste */
|
||||
{"I185", 0x10b}, /* SCROLLUP# => normal speed */
|
||||
{"I173", 0x110}, /* PREVIOUSSONG */
|
||||
{"FIND", 0x112}, /* # Logitech */
|
||||
{"I156", 0x113}, /* PROG1# => Word */
|
||||
{"I157", 0x114}, /* PROG2# => Excel */
|
||||
{"I210", 0x115}, /* PROG3# => Calendar */
|
||||
{"I182", 0x116}, /* EXIT# => Log Off */
|
||||
{"CUT", 0x117},
|
||||
{"COPY", 0x118},
|
||||
{"I171", 0x119}, /* NEXTSONG */
|
||||
{"I162", 0x11e}, /* CYCLEWINDOWS => Application Right (no left counterpart) */
|
||||
{"MUTE", 0x120},
|
||||
{"I148", 0x121}, /* CALC */
|
||||
{"I172", 0x122}, /* PLAYPAUSE */
|
||||
{"I158", 0x123}, /* WWW# => Compaq online start */
|
||||
{"I174", 0x124}, /* STOPCD */
|
||||
{"I147", 0x126}, /* MENU# => Shortcut/Menu/Help for a few OEMs */
|
||||
{"VOL-", 0x12e},
|
||||
{"I168", 0x12f}, /* CLOSECD# => Logitech Eject */
|
||||
{"I169", 0x12f}, /* EJECTCD# => Logitech */
|
||||
{"I170", 0x12f}, /* EJECTCLOSECD# => Logitech */
|
||||
{"VOL+", 0x130},
|
||||
{"I180", 0x132}, /* HOMEPAGE */
|
||||
{"HELP", 0x13b}, /* # */
|
||||
{"I221", 0x13c}, /* SOUND# => My Music */
|
||||
{"I212", 0x13d}, /* DASHBOARD# => Task Pane */
|
||||
{"I189", 0x13e}, /* NEW# */
|
||||
{"OPEN", 0x13f}, /* # */
|
||||
{"I214", 0x140}, /* CLOSE# */
|
||||
{"I240", 0x141}, /* REPLY# */
|
||||
{"I241", 0x142}, /* FORWARDMAIL# */
|
||||
{"I239", 0x143}, /* SEND# */
|
||||
{"I159", 0x144}, /* MSDOS# */
|
||||
{"I120", 0x14c}, /* MACRO */
|
||||
{"I187", 0x14c}, /* KPLEFTPAREN# */
|
||||
{"I243", 0x155}, /* DOCUMENTS# => Logitech */
|
||||
{"I242", 0x157}, /* SAVE# */
|
||||
{"I218", 0x158}, /* PRINT# */
|
||||
{"POWR", 0x15e},
|
||||
{"I150", 0x15f}, /* SLEEP */
|
||||
{"I151", 0x163}, /* WAKEUP */
|
||||
{"I188", 0x164}, /* KPRIGHTPAREN# */
|
||||
{"I220", 0x164}, /* CAMERA# => My Pictures */
|
||||
{"I225", 0x165}, /* SEARCH */
|
||||
{"I164", 0x166}, /* BOOKMARKS => Favorites */
|
||||
{"I181", 0x167}, /* REFRESH */
|
||||
{"STOP", 0x168},
|
||||
{"I167", 0x169}, /* FORWARD */
|
||||
{"I166", 0x16a}, /* BACK */
|
||||
{"I165", 0x16b}, /* COMPUTER */
|
||||
{"I163", 0x16c}, /* MAIL */
|
||||
{"I223", 0x16c}, /* EMAIL# */
|
||||
{"I234", 0x16d}, /* MEDIA */
|
||||
{"I175", 0x178}, /* RECORD# => Logitech */
|
||||
{"I160", 0x17a}, /* COFFEE# */
|
||||
{"I186", 0x18b}, /* SCROLLDOWN# => normal speed */
|
||||
};
|
||||
struct xkb_keymap *xkbcommon_keymap = nullptr;
|
||||
|
||||
void
|
||||
xkbcommon_init(struct xkb_keymap *keymap)
|
||||
{
|
||||
xkbcommon_keymap = keymap;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
xkbcommon_translate(uint32_t keycode)
|
||||
{
|
||||
const char *key_name = xkb_keymap_key_get_name(xkbcommon_keymap, keycode);
|
||||
if (!key_name) {
|
||||
qWarning() << "XKB Keyboard: Unknown keycode" << Qt::hex << keycode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string key_name_s(key_name);
|
||||
uint16_t ret = xkb_keycodes[key_name_s];
|
||||
|
||||
/* Observed with multimedia keys on a Windows X11 client. */
|
||||
if (!ret && (key_name_s.length() == 3) && (key_name_s[0] == 'I') && IS_HEX_DIGIT(key_name_s[1]) && IS_HEX_DIGIT(key_name_s[2]))
|
||||
ret = 0x100 | stoi(key_name_s.substr(1), nullptr, 16);
|
||||
|
||||
if (!ret)
|
||||
qWarning() << "XKB Keyboard: Unknown key" << Qt::hex << keycode << "/" << QString::fromStdString(key_name_s);
|
||||
#if 0
|
||||
else
|
||||
qInfo() << "XKB Keyboard: Key" << Qt::hex << keycode << "/" << QString::fromStdString(key_name_s) << "scancode" << Qt::hex << ret;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
19
src/qt/xkbcommon_keyboard.hpp
Normal file
19
src/qt/xkbcommon_keyboard.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Definitions for xkbcommon keyboard input module.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2023 RichardG.
|
||||
*/
|
||||
extern void *xkbcommon_keymap;
|
||||
void xkbcommon_init(struct xkb_keymap *keymap);
|
||||
uint16_t xkbcommon_translate(uint32_t keycode);
|
85
src/qt/xkbcommon_x11_keyboard.cpp
Normal file
85
src/qt/xkbcommon_x11_keyboard.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* xkbcommon-x11 keyboard input module.
|
||||
*
|
||||
* Heavily inspired by libxkbcommon interactive-x11.c
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2023 RichardG.
|
||||
*/
|
||||
extern "C" {
|
||||
/* xkb.h has identifiers named "explicit", which is a C++ keyword now... */
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wkeyword-macro"
|
||||
#endif
|
||||
#define explicit explicit_
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#include <xcb/xkb.h>
|
||||
#undef explicit
|
||||
|
||||
#include <xkbcommon/xkbcommon-x11.h>
|
||||
};
|
||||
#include "xkbcommon_keyboard.hpp"
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
void
|
||||
xkbcommon_x11_init()
|
||||
{
|
||||
xcb_connection_t *conn;
|
||||
struct xkb_context *ctx;
|
||||
int32_t core_kbd_device_id;
|
||||
struct xkb_keymap *keymap;
|
||||
|
||||
conn = xcb_connect(NULL, NULL);
|
||||
if (!conn || xcb_connection_has_error(conn)) {
|
||||
qWarning() << "XKB Keyboard: X server connection failed with error" << (conn ? xcb_connection_has_error(conn) : -1);
|
||||
return;
|
||||
}
|
||||
|
||||
int ret = xkb_x11_setup_xkb_extension(conn,
|
||||
XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION,
|
||||
XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (!ret) {
|
||||
qWarning() << "XKB Keyboard: XKB extension setup failed";
|
||||
goto err_conn;
|
||||
}
|
||||
|
||||
ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if (!ctx) {
|
||||
qWarning() << "XKB Keyboard: XKB context creation failed";
|
||||
goto err_conn;
|
||||
}
|
||||
|
||||
core_kbd_device_id = xkb_x11_get_core_keyboard_device_id(conn);
|
||||
if (core_kbd_device_id == -1) {
|
||||
qWarning() << "XKB Keyboard: Core keyboard device not found";
|
||||
goto err_ctx;
|
||||
}
|
||||
|
||||
keymap = xkb_x11_keymap_new_from_device(ctx, conn, core_kbd_device_id, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
if (!keymap) {
|
||||
qWarning() << "XKB Keyboard: Keymap loading failed";
|
||||
goto err_ctx;
|
||||
}
|
||||
|
||||
xkbcommon_init(keymap);
|
||||
|
||||
err_ctx:
|
||||
xkb_context_unref(ctx);
|
||||
err_conn:
|
||||
xcb_disconnect(conn);
|
||||
}
|
17
src/qt/xkbcommon_x11_keyboard.hpp
Normal file
17
src/qt/xkbcommon_x11_keyboard.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Definitions for xkbcommon-x11 keyboard input module.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2023 RichardG.
|
||||
*/
|
||||
void xkbcommon_x11_init();
|
Reference in New Issue
Block a user