mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 01:25:33 -07:00
Merge branch 'master' of ssh://github.com/86Box/86Box
# Conflicts: # src/qt/qt_mainwindow.cpp
This commit is contained in:
@@ -67,6 +67,8 @@ AppDir:
|
||||
- libxcb-shape0 # if QT:BOOL=ON
|
||||
- libxcb-shm0 # if QT:BOOL=ON
|
||||
- libxcb-xfixes0 # if QT:BOOL=ON
|
||||
- libxkbcommon-x11-0 # if QT:BOOL=ON
|
||||
- qtwayland5 # if QT:BOOL=ON
|
||||
- zlib1g
|
||||
files:
|
||||
exclude:
|
||||
|
||||
@@ -316,6 +316,9 @@ then
|
||||
pacman -S --needed --noconfirm "$pkg"
|
||||
done
|
||||
fi
|
||||
|
||||
# Clean pacman cache when running under Jenkins to save disk space.
|
||||
[ "$CI" = "true" ] && rm -rf /var/cache/pacman/pkg
|
||||
|
||||
# Generate a new freetype DLL for this architecture.
|
||||
rm -f "$freetype_dll"
|
||||
@@ -584,7 +587,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)
|
||||
@@ -629,7 +632,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
|
||||
set(ENV{PKG_CONFIG_PATH} "")
|
||||
set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/$libdir/pkgconfig:/usr/share/$libdir/pkgconfig")
|
||||
set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/$libdir/pkgconfig:/usr/share/$libdir/pkgconfig:/usr/share/pkgconfig")
|
||||
|
||||
include("$(realpath "$toolchain_file")")
|
||||
EOF
|
||||
@@ -948,7 +951,6 @@ else
|
||||
-S "$prefix" -B "$prefix_build" || exit 99
|
||||
cmake --build "$prefix_build" -j$(nproc) || exit 99
|
||||
cmake --install "$prefix_build" || exit 99
|
||||
cp -p "$cwd_root/archive_tmp/usr/bin/fluidsynth" fluidsynth
|
||||
|
||||
# Build SDL2 for joystick and FAudio support, with most components
|
||||
# disabled to remove the dependencies on PulseAudio and libdrm.
|
||||
|
||||
3
.github/workflows/cmake.yml
vendored
3
.github/workflows/cmake.yml
vendored
@@ -252,7 +252,10 @@ jobs:
|
||||
slug: -Qt
|
||||
packages: >-
|
||||
qtbase5-dev
|
||||
qtbase5-private-dev
|
||||
qttools5-dev
|
||||
libevdev-dev
|
||||
libxkbcommon-x11-dev
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -34,6 +34,8 @@ Makefile
|
||||
*.tar.*
|
||||
*.AppImage
|
||||
/appimage-builder-cache
|
||||
/appimage-build
|
||||
/AppImageBuilder-generated.yml
|
||||
|
||||
# Visual Studio Code
|
||||
/.vs
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <86box/device.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/nmi.h>
|
||||
@@ -265,9 +266,12 @@ reset_common(int hard)
|
||||
if (is286) {
|
||||
loadcs(0xF000);
|
||||
cpu_state.pc = 0xFFF0;
|
||||
rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
|
||||
if (is6117)
|
||||
rammask |= 0x03000000;
|
||||
if (hard) {
|
||||
rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
|
||||
if (is6117)
|
||||
rammask |= 0x03000000;
|
||||
mem_a20_key = mem_a20_alt = mem_a20_state = 0;
|
||||
}
|
||||
}
|
||||
idt.base = 0;
|
||||
cpu_state.flags = 2;
|
||||
@@ -315,6 +319,10 @@ reset_common(int hard)
|
||||
cache_index = 0;
|
||||
memset(_tr, 0x00, sizeof(_tr));
|
||||
memset(_cache, 0x00, sizeof(_cache));
|
||||
|
||||
/* If we have an AT or PS/2 keyboard controller, make sure the A20 state
|
||||
is correct. */
|
||||
kbc_at_a20_reset();
|
||||
}
|
||||
|
||||
if (!is286)
|
||||
|
||||
@@ -66,6 +66,7 @@ static uint8_t
|
||||
fake_shift_needed(uint16_t scan)
|
||||
{
|
||||
switch (scan) {
|
||||
case 0x137: /* Yes, Print Screen requires the fake shifts. */
|
||||
case 0x147:
|
||||
case 0x148:
|
||||
case 0x149:
|
||||
@@ -125,9 +126,13 @@ key_process(uint16_t scan, int down)
|
||||
void
|
||||
keyboard_input(int down, uint16_t scan)
|
||||
{
|
||||
/* Special case for E1 1D, translate it to 0100 - special case. */
|
||||
if ((scan >> 8) == 0xe1) {
|
||||
if ((scan & 0xff) == 0x1d)
|
||||
scan = 0x0100;
|
||||
/* Translate E0 xx scan codes to 01xx because we use 512-byte arrays for states
|
||||
and scan code sets. */
|
||||
if ((scan >> 8) == 0xe0) {
|
||||
} else if ((scan >> 8) == 0xe0) {
|
||||
scan &= 0x00ff;
|
||||
scan |= 0x0100; /* extended key code */
|
||||
} else if ((scan >> 8) != 0x01)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -152,8 +152,8 @@ mouse_close(void)
|
||||
static void
|
||||
mouse_timer_poll(void *priv)
|
||||
{
|
||||
/* Poll at 3600 Hz. */
|
||||
timer_on_auto(&mouse_timer, 277.0 + (7.0 / 9.0));
|
||||
/* Poll at 255 Hz, maximum supported by PS/2 mic. */
|
||||
timer_on_auto(&mouse_timer, 1000000.0 / 255.0);
|
||||
|
||||
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
|
||||
if (gdbstub_step == GDBSTUB_EXEC)
|
||||
@@ -186,8 +186,8 @@ mouse_reset(void)
|
||||
|
||||
timer_add(&mouse_timer, mouse_timer_poll, NULL, 0);
|
||||
|
||||
/* Poll at 3600 Hz. */
|
||||
timer_on_auto(&mouse_timer, 277.0 + (7.0 / 9.0));
|
||||
/* Poll at 255 Hz, maximum supported by PS/2 mic. */
|
||||
timer_on_auto(&mouse_timer, 1000000.0 / 255.0);
|
||||
}
|
||||
|
||||
/* Callback from the hardware driver. */
|
||||
|
||||
@@ -85,15 +85,24 @@ static void
|
||||
ps2_report_coordinates(mouse_t *dev, int cmd)
|
||||
{
|
||||
uint8_t buff[3] = { 0x08, 0x00, 0x00 };
|
||||
int temp_z;
|
||||
|
||||
if (dev->x > 255)
|
||||
if (dev->x > 255) {
|
||||
dev->x = 255;
|
||||
if (dev->x < -256)
|
||||
buff[0] |= 0x40;
|
||||
}
|
||||
if (dev->x < -256) {
|
||||
dev->x = -256;
|
||||
if (dev->y > 255)
|
||||
buff[0] |= 0x40;
|
||||
}
|
||||
if (dev->y > 255) {
|
||||
dev->y = 255;
|
||||
if (dev->y < -256)
|
||||
buff[0] |= 0x80;
|
||||
}
|
||||
if (dev->y < -256) {
|
||||
dev->y = -256;
|
||||
buff[0] |= 0x80;
|
||||
}
|
||||
if (dev->z < -8)
|
||||
dev->z = -8;
|
||||
if (dev->z > 7)
|
||||
@@ -124,13 +133,16 @@ ps2_report_coordinates(mouse_t *dev, int cmd)
|
||||
keyboard_at_adddata_mouse(buff[2]);
|
||||
}
|
||||
if (dev->flags & FLAG_INTMODE) {
|
||||
int temp_z = dev->z;
|
||||
temp_z = dev->z & 0x0f;
|
||||
if ((dev->flags & FLAG_5BTN)) {
|
||||
temp_z &= 0xF;
|
||||
if (mouse_buttons & 8)
|
||||
temp_z |= 0x10;
|
||||
if (mouse_buttons & 16)
|
||||
temp_z |= 0x20;
|
||||
} else {
|
||||
/* The wheel coordinate is sign-extended. */
|
||||
if (temp_z & 0x08)
|
||||
temp_z |= 0xf0;
|
||||
}
|
||||
if (cmd)
|
||||
keyboard_at_adddata_mouse_cmd(temp_z);
|
||||
@@ -262,16 +274,15 @@ mouse_reset:
|
||||
|
||||
dev->last_data[5] = val;
|
||||
|
||||
if (dev->last_data[0] == 0xf3 && dev->last_data[1] == 0xc8
|
||||
&& dev->last_data[2] == 0xf3 && dev->last_data[3] == 0xc8
|
||||
&& dev->last_data[4] == 0xf3 && dev->last_data[5] == 0x50
|
||||
&& mouse_get_buttons() == 5) {
|
||||
dev->flags |= FLAG_INTMODE | FLAG_5BTN;
|
||||
} else if (dev->last_data[0] == 0xf3 && dev->last_data[1] == 0xc8
|
||||
&& dev->last_data[2] == 0xf3 && dev->last_data[3] == 0x64
|
||||
&& dev->last_data[4] == 0xf3 && dev->last_data[5] == 0x50) {
|
||||
if ((dev->last_data[0] == 0xf3) && (dev->last_data[1] == 0xc8) &&
|
||||
(dev->last_data[2] == 0xf3) && (dev->last_data[3] == 0x64) &&
|
||||
(dev->last_data[4] == 0xf3) && (dev->last_data[5] == 0x50))
|
||||
dev->flags |= FLAG_INTMODE;
|
||||
}
|
||||
|
||||
if ((dev->flags & FLAG_INTMODE) && (dev->last_data[0] == 0xf3) && (dev->last_data[1] == 0xc8) &&
|
||||
(dev->last_data[2] == 0xf3) && (dev->last_data[3] == 0xc8) &&
|
||||
(dev->last_data[4] == 0xf3) && (dev->last_data[5] == 0x50))
|
||||
dev->flags |= FLAG_5BTN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ extern const device_t keyboard_xt_zenith_device;
|
||||
extern const device_t keyboard_xtclone_device;
|
||||
extern const device_t keyboard_at_device;
|
||||
extern const device_t keyboard_at_ami_device;
|
||||
extern const device_t keyboard_at_samsung_device;
|
||||
extern const device_t keyboard_at_tg_ami_device;
|
||||
extern const device_t keyboard_at_toshiba_device;
|
||||
extern const device_t keyboard_at_olivetti_device;
|
||||
extern const device_t keyboard_at_ncr_device;
|
||||
@@ -168,6 +168,8 @@ extern const device_t keyboard_ps2_ps1_device;
|
||||
extern const device_t keyboard_ps2_ps1_pci_device;
|
||||
extern const device_t keyboard_ps2_xi8088_device;
|
||||
extern const device_t keyboard_ps2_ami_device;
|
||||
extern const device_t keyboard_ps2_tg_ami_device;
|
||||
extern const device_t keyboard_ps2_tg_ami_green_device;
|
||||
extern const device_t keyboard_ps2_olivetti_device;
|
||||
extern const device_t keyboard_ps2_mca_device;
|
||||
extern const device_t keyboard_ps2_mca_2_device;
|
||||
@@ -177,6 +179,7 @@ extern const device_t keyboard_ps2_ami_pci_device;
|
||||
extern const device_t keyboard_ps2_intel_ami_pci_device;
|
||||
extern const device_t keyboard_ps2_acer_pci_device;
|
||||
extern const device_t keyboard_ps2_ali_pci_device;
|
||||
extern const device_t keyboard_ps2_tg_ami_pci_device;
|
||||
#endif /*EMU_DEVICE_H*/
|
||||
|
||||
extern void keyboard_init(void);
|
||||
@@ -207,6 +210,7 @@ extern void keyboard_at_set_mode(int ps2);
|
||||
extern uint8_t keyboard_at_get_mouse_scan(void);
|
||||
extern void keyboard_at_set_mouse_scan(uint8_t val);
|
||||
extern void keyboard_at_reset(void);
|
||||
extern void kbc_at_a20_reset(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ extern void pic_elcr_write(uint16_t port, uint8_t val, void *priv);
|
||||
extern uint8_t pic_elcr_read(uint16_t port, void *priv);
|
||||
|
||||
extern void pic_set_shadow(int sh);
|
||||
extern int pic_get_pci_flag(void);
|
||||
extern void pic_set_pci_flag(int pci);
|
||||
extern void pic_set_pci(void);
|
||||
extern void pic_init(void);
|
||||
|
||||
@@ -220,7 +220,7 @@ machine_at_spc6000a_init(const machine_t *model)
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
device_add(&keyboard_at_samsung_device);
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -404,7 +404,7 @@ machine_at_acerv10_init(const machine_t *model)
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&sis_85c461_device);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&keyboard_ps2_acer_pci_device);
|
||||
device_add(&ide_isa_2ch_device);
|
||||
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
@@ -1657,7 +1657,7 @@ machine_at_actionpc2600_init(const machine_t *model)
|
||||
device_add(&umc_8886af_device);
|
||||
device_add(&um8669f_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
device_add(&keyboard_at_ami_device);
|
||||
device_add(&keyboard_ps2_tg_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1782,7 +1782,7 @@ machine_at_tg486gp_init(const machine_t *model)
|
||||
device_add(&ali1435_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
device_add(&keyboard_ps2_ami_device);
|
||||
device_add(&keyboard_ps2_tg_ami_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1806,7 +1806,7 @@ machine_at_tg486g_init(const machine_t *model)
|
||||
device_add(&sis_85c471_device);
|
||||
device_add(&ide_isa_device);
|
||||
device_add(&fdc37c651_ide_device);
|
||||
device_add(&keyboard_ps2_intel_ami_pci_device);
|
||||
device_add(&keyboard_ps2_tg_ami_pci_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ machine_at_hawk_init(const machine_t *model)
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&keyboard_ps2_tg_ami_pci_device);
|
||||
device_add(&i430fx_device);
|
||||
device_add(&piix_device);
|
||||
device_add(&fdc37c665_device);
|
||||
|
||||
@@ -7036,7 +7036,7 @@ const machine_t machines[] = {
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_PCI,
|
||||
.bus_flags = MACHINE_PS2_PCI,
|
||||
.flags = MACHINE_IDE_DUAL | MACHINE_APM,
|
||||
.ram = {
|
||||
.min = 1024,
|
||||
|
||||
@@ -2530,11 +2530,12 @@ void
|
||||
mem_a20_init(void)
|
||||
{
|
||||
if (is286) {
|
||||
rammask = cpu_16bitbus ? 0xefffff : 0xffefffff;
|
||||
mem_a20_key = mem_a20_alt = mem_a20_state = 0;
|
||||
rammask = cpu_16bitbus ? 0xffffff : 0xffffffff;
|
||||
if (is6117)
|
||||
rammask |= 0x03000000;
|
||||
flushmmucache();
|
||||
mem_a20_state = mem_a20_key | mem_a20_alt;
|
||||
// mem_a20_state = mem_a20_key | mem_a20_alt;
|
||||
} else {
|
||||
rammask = 0xfffff;
|
||||
flushmmucache();
|
||||
|
||||
@@ -284,6 +284,12 @@ pic_set_shadow(int sh)
|
||||
shadow = sh;
|
||||
}
|
||||
|
||||
int
|
||||
pic_get_pci_flag(void)
|
||||
{
|
||||
return pic_pci;
|
||||
}
|
||||
|
||||
void
|
||||
pic_set_pci_flag(int pci)
|
||||
{
|
||||
|
||||
@@ -365,7 +365,7 @@ endif()
|
||||
if (UNIX AND NOT APPLE AND NOT HAIKU)
|
||||
find_package(X11 REQUIRED)
|
||||
target_link_libraries(ui PRIVATE X11::X11 X11::Xi)
|
||||
target_sources(ui PRIVATE xinput2_mouse.cpp)
|
||||
target_sources(ui PRIVATE evdev_keyboard.cpp xinput2_mouse.cpp)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(LIBEVDEV IMPORTED_TARGET libevdev)
|
||||
if (LIBEVDEV_FOUND)
|
||||
@@ -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)
|
||||
@@ -387,6 +402,9 @@ if (UNIX AND NOT APPLE AND NOT HAIKU)
|
||||
ecm_add_wayland_client_protocol(WL_SOURCE_VAR PROTOCOL ${CMAKE_SOURCE_DIR}/wl_protocols/pointer-constraints-unstable-v1.xml BASENAME pointer-constraints-unstable-v1)
|
||||
target_include_directories(ui PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${Qt${QT_MAJOR}Gui_PRIVATE_INCLUDE_DIRS})
|
||||
target_sources(ui PRIVATE ${WL_SOURCE_VAR} wl_mouse.cpp)
|
||||
if (XKBCOMMON_FOUND)
|
||||
target_sources(ui PRIVATE xkbcommon_wl_keyboard.cpp)
|
||||
endif()
|
||||
target_compile_definitions(ui PRIVATE WAYLAND)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
112
src/qt/be_keyboard.hpp
Normal file
112
src/qt/be_keyboard.hpp
Normal file
@@ -0,0 +1,112 @@
|
||||
static std::unordered_map<uint8_t, uint16_t> be_keycodes = {
|
||||
{B_F1_KEY, 0x3b},
|
||||
{B_F2_KEY, 0x3c},
|
||||
{B_F3_KEY, 0x3d},
|
||||
{B_F4_KEY, 0x3e},
|
||||
{B_F5_KEY, 0x3f},
|
||||
{B_F6_KEY, 0x40},
|
||||
{B_F7_KEY, 0x41},
|
||||
{B_F8_KEY, 0x42},
|
||||
{B_F9_KEY, 0x43},
|
||||
{B_F10_KEY, 0x44},
|
||||
{B_F11_KEY, 0x57},
|
||||
{B_F12_KEY, 0x58},
|
||||
{B_PRINT_KEY, 0x137},
|
||||
{B_SCROLL_KEY, 0x46},
|
||||
{B_PAUSE_KEY, 0x145},
|
||||
{B_KATAKANA_HIRAGANA, 0x70},
|
||||
{B_HANKAKU_ZENKAKU, 0x76},
|
||||
|
||||
{0x01, 0x01}, /* Escape */
|
||||
{0x11, 0x29},
|
||||
{0x12, 0x02},
|
||||
{0x13, 0x03},
|
||||
{0x14, 0x04},
|
||||
{0x15, 0x05},
|
||||
{0x16, 0x06},
|
||||
{0x17, 0x07},
|
||||
{0x18, 0x08},
|
||||
{0x19, 0x09},
|
||||
{0x1a, 0x0a},
|
||||
{0x1b, 0x0b},
|
||||
{0x1c, 0x0c},
|
||||
{0x1d, 0x0d},
|
||||
{0x1e, 0x0e}, /* Backspace */
|
||||
{0x1f, 0x152}, /* Insert */
|
||||
{0x20, 0x147}, /* Home */
|
||||
{0x21, 0x149}, /* Page Up */
|
||||
{0x22, 0x45},
|
||||
{0x23, 0x135},
|
||||
{0x24, 0x37},
|
||||
{0x25, 0x4a},
|
||||
{0x26, 0x0f}, /* Tab */
|
||||
{0x27, 0x10},
|
||||
{0x28, 0x11},
|
||||
{0x29, 0x12},
|
||||
{0x2a, 0x13},
|
||||
{0x2b, 0x14},
|
||||
{0x2c, 0x15},
|
||||
{0x2d, 0x16},
|
||||
{0x2e, 0x17},
|
||||
{0x2f, 0x18},
|
||||
{0x30, 0x19},
|
||||
{0x31, 0x1a},
|
||||
{0x32, 0x1b},
|
||||
{0x33, 0x2b},
|
||||
{0x34, 0x153}, /* Delete */
|
||||
{0x35, 0x14f}, /* End */
|
||||
{0x36, 0x151}, /* Page Down */
|
||||
{0x37, 0x47},
|
||||
{0x38, 0x48},
|
||||
{0x39, 0x49},
|
||||
{0x3a, 0x4e},
|
||||
{0x3b, 0x3a},
|
||||
{0x3c, 0x1e},
|
||||
{0x3d, 0x1f},
|
||||
{0x3e, 0x20},
|
||||
{0x3f, 0x21},
|
||||
{0x40, 0x22},
|
||||
{0x41, 0x23},
|
||||
{0x42, 0x24},
|
||||
{0x43, 0x25},
|
||||
{0x44, 0x26},
|
||||
{0x45, 0x27},
|
||||
{0x46, 0x28},
|
||||
{0x47, 0x1c}, /* Enter */
|
||||
{0x48, 0x4b},
|
||||
{0x49, 0x4c},
|
||||
{0x4a, 0x4d},
|
||||
{0x4b, 0x2a},
|
||||
{0x4c, 0x2c},
|
||||
{0x4d, 0x2d},
|
||||
{0x4e, 0x2e},
|
||||
{0x4f, 0x2f},
|
||||
{0x50, 0x30},
|
||||
{0x51, 0x31},
|
||||
{0x52, 0x32},
|
||||
{0x53, 0x33},
|
||||
{0x54, 0x34},
|
||||
{0x55, 0x35},
|
||||
{0x56, 0x36},
|
||||
{0x57, 0x148}, /* up arrow */
|
||||
{0x58, 0x51},
|
||||
{0x59, 0x50},
|
||||
{0x5a, 0x4f},
|
||||
{0x5b, 0x11c},
|
||||
{0x5c, 0x1d},
|
||||
{0x5d, 0x38},
|
||||
{0x5e, 0x39}, /* space bar */
|
||||
{0x5f, 0x138},
|
||||
{0x60, 0x11d},
|
||||
{0x61, 0x14b}, /* left arrow */
|
||||
{0x62, 0x150}, /* down arrow */
|
||||
{0x63, 0x14d}, /* right arrow */
|
||||
{0x64, 0x52},
|
||||
{0x65, 0x53},
|
||||
{0x66, 0x15b},
|
||||
{0x67, 0x15c},
|
||||
{0x68, 0x15d},
|
||||
{0x69, 0x56},
|
||||
{0x7e, 0x137}, /* System Request */
|
||||
{0x7f, 0x145}, /* Break */
|
||||
};
|
||||
129
src/qt/cocoa_keyboard.hpp
Normal file
129
src/qt/cocoa_keyboard.hpp
Normal file
@@ -0,0 +1,129 @@
|
||||
static std::array<uint32_t, 127> cocoa_keycodes = { /* key names in parentheses are not declared by Apple headers */
|
||||
0x1e, /* ANSI_A */
|
||||
0x1f, /* ANSI_S */
|
||||
0x20, /* ANSI_D */
|
||||
0x21, /* ANSI_F */
|
||||
0x23, /* ANSI_H */
|
||||
0x22, /* ANSI_G */
|
||||
0x2c, /* ANSI_Z */
|
||||
0x2d, /* ANSI_X */
|
||||
0x2e, /* ANSI_C */
|
||||
0x2f, /* ANSI_V */
|
||||
0x56, /* ISO_Section */
|
||||
0x30, /* ANSI_B */
|
||||
0x10, /* ANSI_Q */
|
||||
0x11, /* ANSI_W */
|
||||
0x12, /* ANSI_E */
|
||||
0x13, /* ANSI_R */
|
||||
0x15, /* ANSI_Y */
|
||||
0x14, /* ANSI_T */
|
||||
0x02, /* ANSI_1 */
|
||||
0x03, /* ANSI_2 */
|
||||
0x04, /* ANSI_3 */
|
||||
0x05, /* ANSI_4 */
|
||||
0x07, /* ANSI_6 */
|
||||
0x06, /* ANSI_5 */
|
||||
0x0d, /* ANSI_Equal */
|
||||
0x0a, /* ANSI_9 */
|
||||
0x08, /* ANSI_7 */
|
||||
0x0c, /* ANSI_Minus */
|
||||
0x09, /* ANSI_8 */
|
||||
0x0b, /* ANSI_0 */
|
||||
0x1b, /* ANSI_RightBracket */
|
||||
0x18, /* ANSI_O */
|
||||
0x16, /* ANSI_U */
|
||||
0x1a, /* ANSI_LeftBracket */
|
||||
0x17, /* ANSI_I */
|
||||
0x19, /* ANSI_P */
|
||||
0x1c, /* Return */
|
||||
0x26, /* ANSI_L */
|
||||
0x24, /* ANSI_J */
|
||||
0x28, /* ANSI_Quote */
|
||||
0x25, /* ANSI_K */
|
||||
0x27, /* ANSI_Semicolon */
|
||||
0x2b, /* ANSI_Backslash */
|
||||
0x33, /* ANSI_Comma */
|
||||
0x35, /* ANSI_Slash */
|
||||
0x31, /* ANSI_N */
|
||||
0x32, /* ANSI_M */
|
||||
0x34, /* ANSI_Period */
|
||||
0x0f, /* Tab */
|
||||
0x39, /* Space */
|
||||
0x29, /* ANSI_Grave */
|
||||
0x0e, /* Delete => Backspace */
|
||||
0x11c, /* (ANSI_KeypadEnter) */
|
||||
0x01, /* Escape */
|
||||
0x15c, /* (RightCommand) => Right Windows */
|
||||
0x15b, /* (Left)Command => Left Windows */
|
||||
0x2a, /* Shift */
|
||||
0x3a, /* CapsLock */
|
||||
0x38, /* Option */
|
||||
0x1d, /* Control */
|
||||
0x36, /* RightShift */
|
||||
0x138, /* RightOption */
|
||||
0x11d, /* RightControl */
|
||||
0x15c, /* Function */
|
||||
0x5e, /* F17 => F14 */
|
||||
0x53, /* ANSI_KeypadDecimal */
|
||||
0,
|
||||
0x37, /* ANSI_KeypadMultiply */
|
||||
0,
|
||||
0x4e, /* ANSI_KeypadPlus */
|
||||
0,
|
||||
0x45, /* ANSI_KeypadClear => Num Lock (location equivalent) */
|
||||
0x130, /* VolumeUp */
|
||||
0x12e, /* VolumeDown */
|
||||
0x120, /* Mute */
|
||||
0x135, /* ANSI_KeypadDivide */
|
||||
0x11c, /* ANSI_KeypadEnter */
|
||||
0,
|
||||
0x4a, /* ANSI_KeypadMinus */
|
||||
0x5f, /* F18 => F15 */
|
||||
0, /* F19 */
|
||||
0x59, /* ANSI_KeypadEquals */
|
||||
0x52, /* ANSI_Keypad0 */
|
||||
0x4f, /* ANSI_Keypad1 */
|
||||
0x50, /* ANSI_Keypad2 */
|
||||
0x51, /* ANSI_Keypad3 */
|
||||
0x4b, /* ANSI_Keypad4 */
|
||||
0x4c, /* ANSI_Keypad5 */
|
||||
0x4d, /* ANSI_Keypad6 */
|
||||
0x47, /* ANSI_Keypad7 */
|
||||
0, /* F20 */
|
||||
0x48, /* ANSI_Keypad8 */
|
||||
0x49, /* ANSI_Keypad9 */
|
||||
0x7d, /* JIS_Yen */
|
||||
0x73, /* JIS_Underscore */
|
||||
0x5c, /* JIS_KeypadComma */
|
||||
0x3f, /* F5 */
|
||||
0x40, /* F6 */
|
||||
0x41, /* F7 */
|
||||
0x3d, /* F3 */
|
||||
0x42, /* F8 */
|
||||
0x43, /* F9 */
|
||||
0x7b, /* JIS_Eisu => muhenkan (location equivalent) */
|
||||
0x57, /* F11 */
|
||||
0x79, /* JIS_Kana => henkan (location equivalent) */
|
||||
0x137, /* F13 => SysRq (location equivalent) */
|
||||
0x5d, /* F16 => F13 */
|
||||
0x46, /* F14 => Scroll Lock (location equivalent) */
|
||||
0,
|
||||
0x44, /* F10 */
|
||||
0x15d, /* (Menu) */
|
||||
0x58, /* F12 */
|
||||
0,
|
||||
0x145, /* F15 => Pause (location equivalent) */
|
||||
0x152, /* Help => Insert (location equivalent) */
|
||||
0x147, /* Home */
|
||||
0x149, /* PageUp */
|
||||
0x153, /* ForwardDelete */
|
||||
0x3e, /* F4 */
|
||||
0x14f, /* End */
|
||||
0x3c, /* F2 */
|
||||
0x151, /* PageDown */
|
||||
0x3b, /* F1 */
|
||||
0x14b, /* LeftArrow */
|
||||
0x14d, /* RightArrow */
|
||||
0x150, /* DownArrow */
|
||||
0x148, /* UpArrow */
|
||||
};
|
||||
163
src/qt/evdev_keyboard.cpp
Normal file
163
src/qt/evdev_keyboard.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* evdev keyboard input module.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2023 RichardG.
|
||||
*/
|
||||
#include <unordered_map>
|
||||
#include <QtDebug>
|
||||
|
||||
static std::unordered_map<uint32_t, uint16_t> evdev_keycodes = {
|
||||
{184, 0x46}, /* F14 => Scroll Lock (for Apple keyboards) */
|
||||
{86, 0x56}, /* 102ND */
|
||||
{87, 0x57}, /* F11 */
|
||||
{88, 0x58}, /* F12 */
|
||||
{186, 0x5d}, /* F16 => F13 */
|
||||
{187, 0x5e}, /* F17 => F14 */
|
||||
{188, 0x5f}, /* F18 => F15 */
|
||||
|
||||
/* Japanese keys. */
|
||||
{95, 0x5c}, /* KPJPCOMMA */
|
||||
{93, 0x70}, /* KATAKANAHIRAGANA */
|
||||
{89, 0x73}, /* RO */
|
||||
{85, 0x76}, /* ZENKAKUHANKAKU */
|
||||
{91, 0x77}, /* HIRAGANA */
|
||||
{90, 0x78}, /* KATAKANA */
|
||||
{92, 0x79}, /* HENKAN */
|
||||
{94, 0x7b}, /* MUHENKAN */
|
||||
{124, 0x7d}, /* YEN */
|
||||
{121, 0x7e}, /* KPCOMMA */
|
||||
|
||||
/* Korean keys. */
|
||||
{123, 0xf1}, /* HANJA */
|
||||
{122, 0xf2}, /* HANGUL */
|
||||
|
||||
{96, 0x11c}, /* KPENTER */
|
||||
{97, 0x11d}, /* RIGHTCTRL */
|
||||
{98, 0x135}, /* KPSLASH */
|
||||
{99, 0x137}, /* SYSRQ */
|
||||
{183, 0x137}, /* F13 => SysRq (for Apple keyboards) */
|
||||
{100, 0x138}, /* RIGHTALT */
|
||||
{119, 0x145}, /* PAUSE */
|
||||
{411, 0x145}, /* BREAK */
|
||||
{185, 0x145}, /* F15 => Pause (for Apple keyboards) */
|
||||
{102, 0x147}, /* HOME */
|
||||
{103, 0x148}, /* UP */
|
||||
{104, 0x149}, /* PAGEUP */
|
||||
{105, 0x14b}, /* LEFT */
|
||||
{106, 0x14d}, /* RIGHT */
|
||||
{107, 0x14f}, /* END */
|
||||
{108, 0x150}, /* DOWN */
|
||||
{109, 0x151}, /* PAGEDOWN */
|
||||
{110, 0x152}, /* INSERT */
|
||||
{111, 0x153}, /* DELETE */
|
||||
|
||||
{125, 0x15b}, /* LEFTMETA */
|
||||
{126, 0x15c}, /* RIGHTMETA */
|
||||
{127, 0x15d}, /* COMPOSE => Menu */
|
||||
|
||||
/* Multimedia keys. Guideline is to try and follow the Microsoft standard, then
|
||||
fill in remaining scancodes with OEM-specific keys for redundancy sake. Keys
|
||||
marked with # are not translated into evdev codes by the standard atkbd driver. */
|
||||
{634, 0x54}, /* SELECTIVE_SCREENSHOT# => Alt+SysRq */
|
||||
{117, 0x59}, /* KPEQUAL */
|
||||
{418, 0x6a}, /* ZOOMIN# => Logitech */
|
||||
{420, 0x6b}, /* ZOOMRESET# => Logitech */
|
||||
{223, 0x6d}, /* CANCEL# => Logitech */
|
||||
{132, 0x101}, /* # Logitech Task Select */
|
||||
{148, 0x102}, /* PROG1# => Samsung */
|
||||
{149, 0x103}, /* PROG2# => Samsung */
|
||||
{419, 0x104}, /* ZOOMOUT# => Logitech */
|
||||
{144, 0x105}, /* FILE# => Messenger/Files */
|
||||
{216, 0x105}, /* CHAT# => Messenger/Files */
|
||||
{430, 0x105}, /* MESSENGER# */
|
||||
{182, 0x107}, /* REDO# */
|
||||
{131, 0x108}, /* UNDO# */
|
||||
{135, 0x10a}, /* PASTE# */
|
||||
{177, 0x10b}, /* SCROLLUP# => normal speed */
|
||||
{165, 0x110}, /* PREVIOUSSONG */
|
||||
{136, 0x112}, /* FIND# => Logitech */
|
||||
{421, 0x113}, /* WORDPROCESSOR# => Word */
|
||||
{423, 0x114}, /* SPREADSHEET# => Excel */
|
||||
{397, 0x115}, /* CALENDAR# */
|
||||
{433, 0x116}, /* LOGOFF# */
|
||||
{137, 0x117}, /* CUT# */
|
||||
{133, 0x118}, /* COPY# */
|
||||
{163, 0x119}, /* NEXTSONG */
|
||||
{154, 0x11e}, /* CYCLEWINDOWS => Application Right (no left counterpart) */
|
||||
{113, 0x120}, /* MUTE */
|
||||
{140, 0x121}, /* CALC */
|
||||
{164, 0x122}, /* PLAYPAUSE */
|
||||
{432, 0x123}, /* SPELLCHECK# */
|
||||
{166, 0x124}, /* STOPCD */
|
||||
{139, 0x126}, /* MENU# => Shortcut/Menu/Help for a few OEMs */
|
||||
{114, 0x12e}, /* VOL- */
|
||||
{160, 0x12f}, /* CLOSECD# => Logitech Eject */
|
||||
{161, 0x12f}, /* EJECTCD# => Logitech */
|
||||
{162, 0x12f}, /* EJECTCLOSECD# => Logitech */
|
||||
{115, 0x130}, /* VOL+ */
|
||||
{150, 0x132}, /* WWW# */
|
||||
{172, 0x132}, /* HOMEPAGE */
|
||||
{138, 0x13b}, /* HELP# */
|
||||
{213, 0x13c}, /* SOUND# => My Music/Office Home */
|
||||
{360, 0x13c}, /* VENDOR# => My Music/Office Home */
|
||||
{204, 0x13d}, /* DASHBOARD# => Task Pane */
|
||||
{181, 0x13e}, /* NEW# */
|
||||
{134, 0x13f}, /* OPEN# */
|
||||
{206, 0x140}, /* CLOSE# */
|
||||
{232, 0x141}, /* REPLY# */
|
||||
{233, 0x142}, /* FORWARDMAIL# */
|
||||
{231, 0x143}, /* SEND# */
|
||||
{151, 0x144}, /* MSDOS# */
|
||||
{112, 0x14c}, /* MACRO */
|
||||
{179, 0x14c}, /* KPLEFTPAREN# */
|
||||
{118, 0x14e}, /* KPPLUSMINUS */
|
||||
{235, 0x155}, /* DOCUMENTS# => Logitech */
|
||||
{234, 0x157}, /* SAVE# */
|
||||
{210, 0x158}, /* PRINT# */
|
||||
{116, 0x15e}, /* POWER */
|
||||
{142, 0x15f}, /* SLEEP */
|
||||
{143, 0x163}, /* WAKEUP */
|
||||
{180, 0x164}, /* KPRIGHTPAREN# */
|
||||
{212, 0x164}, /* CAMERA# => My Pictures */
|
||||
{217, 0x165}, /* SEARCH */
|
||||
{156, 0x166}, /* BOOKMARKS => Favorites */
|
||||
{364, 0x166}, /* FAVORITES# */
|
||||
{173, 0x167}, /* REFRESH */
|
||||
{128, 0x168}, /* STOP */
|
||||
{159, 0x169}, /* FORWARD */
|
||||
{158, 0x16a}, /* BACK */
|
||||
{157, 0x16b}, /* COMPUTER */
|
||||
{155, 0x16c}, /* MAIL */
|
||||
{215, 0x16c}, /* EMAIL# */
|
||||
{226, 0x16d}, /* MEDIA */
|
||||
{167, 0x178}, /* RECORD# => Logitech */
|
||||
{152, 0x17a}, /* COFFEE/SCREENLOCK# */
|
||||
{178, 0x18b}, /* SCROLLDOWN# => normal speed */
|
||||
};
|
||||
|
||||
uint16_t
|
||||
evdev_translate(uint32_t keycode)
|
||||
{
|
||||
/* "for 1-83 (0x01-0x53) scancode equals keycode" */
|
||||
auto ret = (keycode <= 0x53) ? keycode : evdev_keycodes[keycode];
|
||||
|
||||
if (!ret)
|
||||
qWarning() << "Evdev Keyboard: Unknown key" << keycode;
|
||||
#if 0
|
||||
else
|
||||
qInfo() << "Evdev Keyboard: Key" << keycode << "scancode" << Qt::hex << ret;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
20
src/qt/evdev_keyboard.hpp
Normal file
20
src/qt/evdev_keyboard.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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 evdev keyboard input module.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2023 RichardG.
|
||||
*/
|
||||
#ifndef EVDEV_KEYBOARD_HPP
|
||||
#define EVDEV_KEYBOARD_HPP
|
||||
uint16_t evdev_translate(uint32_t keycode);
|
||||
#endif
|
||||
@@ -96,8 +96,17 @@ extern int qt_nvr_save(void);
|
||||
#include "qt_util.hpp"
|
||||
|
||||
#if defined __unix__ && !defined __HAIKU__
|
||||
# ifdef WAYLAND
|
||||
# include "wl_mouse.hpp"
|
||||
# ifndef Q_OS_MACOS
|
||||
# include "evdev_keyboard.hpp"
|
||||
# endif
|
||||
# ifdef XKBCOMMON
|
||||
# include "xkbcommon_keyboard.hpp"
|
||||
# ifdef XKBCOMMON_X11
|
||||
# include "xkbcommon_x11_keyboard.hpp"
|
||||
# endif
|
||||
# ifdef WAYLAND
|
||||
# include "xkbcommon_wl_keyboard.hpp"
|
||||
# endif
|
||||
# endif
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/keysym.h>
|
||||
@@ -106,6 +115,7 @@ extern int qt_nvr_save(void);
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
# include "cocoa_keyboard.hpp"
|
||||
// The namespace is required to avoid clashing typedefs; we only use this
|
||||
// header for its #defines anyway.
|
||||
namespace IOKit {
|
||||
@@ -116,6 +126,7 @@ namespace IOKit {
|
||||
#ifdef __HAIKU__
|
||||
# include <os/AppKit.h>
|
||||
# include <os/InterfaceKit.h>
|
||||
# include "be_keyboard.hpp"
|
||||
|
||||
extern MainWindow *main_window;
|
||||
|
||||
@@ -648,6 +659,20 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
} else {
|
||||
ui->actionCursor_Puck->setChecked(true);
|
||||
}
|
||||
|
||||
#ifdef XKBCOMMON
|
||||
# ifdef XKBCOMMON_X11
|
||||
if (QApplication::platformName().contains("xcb"))
|
||||
xkbcommon_x11_init();
|
||||
else
|
||||
# endif
|
||||
# ifdef WAYLAND
|
||||
if (QApplication::platformName().contains("wayland"))
|
||||
xkbcommon_wl_init();
|
||||
else
|
||||
# endif
|
||||
{}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -882,652 +907,67 @@ MainWindow::on_actionSettings_triggered()
|
||||
plat_pause(currentPause);
|
||||
}
|
||||
|
||||
#if defined(__unix__) && !defined(__HAIKU__)
|
||||
std::array<uint32_t, 256> x11_to_xt_base {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x01,
|
||||
0x02,
|
||||
0x03,
|
||||
0x04,
|
||||
0x05,
|
||||
0x06,
|
||||
0x07,
|
||||
0x08,
|
||||
0x09,
|
||||
0x0A,
|
||||
0x0B,
|
||||
0x0C,
|
||||
0x0D,
|
||||
0x0E,
|
||||
0x0F,
|
||||
0x10,
|
||||
0x11,
|
||||
0x12,
|
||||
0x13,
|
||||
0x14,
|
||||
0x15,
|
||||
0x16,
|
||||
0x17,
|
||||
0x18,
|
||||
0x19,
|
||||
0x1A,
|
||||
0x1B,
|
||||
0x1C,
|
||||
0x1D,
|
||||
0x1E,
|
||||
0x1F,
|
||||
0x20,
|
||||
0x21,
|
||||
0x22,
|
||||
0x23,
|
||||
0x24,
|
||||
0x25,
|
||||
0x26,
|
||||
0x27,
|
||||
0x28,
|
||||
0x29,
|
||||
0x2A,
|
||||
0x2B,
|
||||
0x2C,
|
||||
0x2D,
|
||||
0x2E,
|
||||
0x2F,
|
||||
0x30,
|
||||
0x31,
|
||||
0x32,
|
||||
0x33,
|
||||
0x34,
|
||||
0x35,
|
||||
0x36,
|
||||
0x37,
|
||||
0x38,
|
||||
0x39,
|
||||
0x3A,
|
||||
0x3B,
|
||||
0x3C,
|
||||
0x3D,
|
||||
0x3E,
|
||||
0x3F,
|
||||
0x40,
|
||||
0x41,
|
||||
0x42,
|
||||
0x43,
|
||||
0x44,
|
||||
0x45,
|
||||
0x46,
|
||||
0x47,
|
||||
0x48,
|
||||
0x49,
|
||||
0x4A,
|
||||
0x4B,
|
||||
0x4C,
|
||||
0x4D,
|
||||
0x4E,
|
||||
0x4F,
|
||||
0x50,
|
||||
0x51,
|
||||
0x52,
|
||||
0x53,
|
||||
0x54,
|
||||
0x55,
|
||||
0x56,
|
||||
0x57,
|
||||
0x58,
|
||||
0x147,
|
||||
0x148,
|
||||
0x149,
|
||||
0,
|
||||
0x14B,
|
||||
0,
|
||||
0x14D,
|
||||
0x14F,
|
||||
0x150,
|
||||
0x151,
|
||||
0x152,
|
||||
0x153,
|
||||
0x11C,
|
||||
0x11D,
|
||||
0, // Pause/Break key.
|
||||
0x137,
|
||||
0x135,
|
||||
0x138,
|
||||
0, // Ditto as above comment.
|
||||
0x15B,
|
||||
0x15C,
|
||||
0x15D,
|
||||
};
|
||||
|
||||
std::array<uint32_t, 256> x11_to_xt_2 {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x01,
|
||||
0x02,
|
||||
0x03,
|
||||
0x04,
|
||||
0x05,
|
||||
0x06,
|
||||
0x07,
|
||||
0x08,
|
||||
0x09,
|
||||
0x0A,
|
||||
0x0B,
|
||||
0x0C,
|
||||
0x0D,
|
||||
0x0E,
|
||||
0x0F,
|
||||
0x10,
|
||||
0x11,
|
||||
0x12,
|
||||
0x13,
|
||||
0x14,
|
||||
0x15,
|
||||
0x16,
|
||||
0x17,
|
||||
0x18,
|
||||
0x19,
|
||||
0x1A,
|
||||
0x1B,
|
||||
0x1C,
|
||||
0x1D,
|
||||
0x1E,
|
||||
0x1F,
|
||||
0x20,
|
||||
0x21,
|
||||
0x22,
|
||||
0x23,
|
||||
0x24,
|
||||
0x25,
|
||||
0x26,
|
||||
0x27,
|
||||
0x28,
|
||||
0x29,
|
||||
0x2A,
|
||||
0x2B,
|
||||
0x2C,
|
||||
0x2D,
|
||||
0x2E,
|
||||
0x2F,
|
||||
0x30,
|
||||
0x31,
|
||||
0x32,
|
||||
0x33,
|
||||
0x34,
|
||||
0x35,
|
||||
0x36,
|
||||
0x37,
|
||||
0x38,
|
||||
0x39,
|
||||
0x3A,
|
||||
0x3B,
|
||||
0x3C,
|
||||
0x3D,
|
||||
0x3E,
|
||||
0x3F,
|
||||
0x40,
|
||||
0x41,
|
||||
0x42,
|
||||
0x43,
|
||||
0x44,
|
||||
0x45,
|
||||
0x46,
|
||||
0x47,
|
||||
0x48,
|
||||
0x49,
|
||||
0x4A,
|
||||
0x4B,
|
||||
0x4C,
|
||||
0x4D,
|
||||
0x4E,
|
||||
0x4F,
|
||||
0x50,
|
||||
0x51,
|
||||
0x52,
|
||||
0x53,
|
||||
0x138,
|
||||
0x55,
|
||||
0x56,
|
||||
0x57,
|
||||
0x58,
|
||||
0x56,
|
||||
0x70,
|
||||
0x7B,
|
||||
0x7D,
|
||||
0x2B,
|
||||
0x7E,
|
||||
0,
|
||||
0x11C,
|
||||
0x11D,
|
||||
0x135,
|
||||
0x137,
|
||||
0x138,
|
||||
0,
|
||||
0x147,
|
||||
0x148,
|
||||
0x149,
|
||||
0x14B,
|
||||
0x14D,
|
||||
0x14F,
|
||||
0x150,
|
||||
0x151,
|
||||
0x152,
|
||||
0x153,
|
||||
0,
|
||||
0, /* Mute */
|
||||
0, /* Volume Down */
|
||||
0, /* Volume Up */
|
||||
0, /* Power Off */
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x70,
|
||||
0x7B,
|
||||
0x73,
|
||||
0x15B,
|
||||
0x15C,
|
||||
0x15D
|
||||
};
|
||||
|
||||
std::array<uint32_t, 256> x11_to_xt_vnc {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x1D,
|
||||
0x11D,
|
||||
0x2A,
|
||||
0x36,
|
||||
0,
|
||||
0,
|
||||
0x38,
|
||||
0x138,
|
||||
0x39,
|
||||
0x0B,
|
||||
0x02,
|
||||
0x03,
|
||||
0x04,
|
||||
0x05,
|
||||
0x06,
|
||||
0x07,
|
||||
0x08,
|
||||
0x09,
|
||||
0x0A,
|
||||
0x0C,
|
||||
0x0D,
|
||||
0x1A,
|
||||
0x1B,
|
||||
0x27,
|
||||
0x28,
|
||||
0x29,
|
||||
0x33,
|
||||
0x34,
|
||||
0x35,
|
||||
0x2B,
|
||||
0x1E,
|
||||
0x30,
|
||||
0x2E,
|
||||
0x20,
|
||||
0x12,
|
||||
0x21,
|
||||
0x22,
|
||||
0x23,
|
||||
0x17,
|
||||
0x24,
|
||||
0x25,
|
||||
0x26,
|
||||
0x32,
|
||||
0x31,
|
||||
0x18,
|
||||
0x19,
|
||||
0x10,
|
||||
0x13,
|
||||
0x1F,
|
||||
0x14,
|
||||
0x16,
|
||||
0x2F,
|
||||
0x11,
|
||||
0x2D,
|
||||
0x15,
|
||||
0x2C,
|
||||
0x0E,
|
||||
0x1C,
|
||||
0x0F,
|
||||
0x01,
|
||||
0x153,
|
||||
0x147,
|
||||
0x14F,
|
||||
0x149,
|
||||
0x151,
|
||||
0x148,
|
||||
0x150,
|
||||
0x14B,
|
||||
0x14D,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
std::array<uint32_t, 256> darwin_to_xt {
|
||||
0x1E,
|
||||
0x1F,
|
||||
0x20,
|
||||
0x21,
|
||||
0x23,
|
||||
0x22,
|
||||
0x2C,
|
||||
0x2D,
|
||||
0x2E,
|
||||
0x2F,
|
||||
0x2B,
|
||||
0x30,
|
||||
0x10,
|
||||
0x11,
|
||||
0x12,
|
||||
0x13,
|
||||
0x15,
|
||||
0x14,
|
||||
0x02,
|
||||
0x03,
|
||||
0x04,
|
||||
0x05,
|
||||
0x07,
|
||||
0x06,
|
||||
0x0D,
|
||||
0x0A,
|
||||
0x08,
|
||||
0x0C,
|
||||
0x09,
|
||||
0x0B,
|
||||
0x1B,
|
||||
0x18,
|
||||
0x16,
|
||||
0x1A,
|
||||
0x17,
|
||||
0x19,
|
||||
0x1C,
|
||||
0x26,
|
||||
0x24,
|
||||
0x28,
|
||||
0x25,
|
||||
0x27,
|
||||
0x2B,
|
||||
0x33,
|
||||
0x35,
|
||||
0x31,
|
||||
0x32,
|
||||
0x34,
|
||||
0x0F,
|
||||
0x39,
|
||||
0x29,
|
||||
0x0E,
|
||||
0x11C,
|
||||
0x01,
|
||||
0x15C,
|
||||
0x15B,
|
||||
0x2A,
|
||||
0x3A,
|
||||
0x38,
|
||||
0x1D,
|
||||
0x36,
|
||||
0x138,
|
||||
0x11D,
|
||||
0x15C,
|
||||
0,
|
||||
0x53,
|
||||
0,
|
||||
0x37,
|
||||
0,
|
||||
0x4E,
|
||||
0,
|
||||
0x45,
|
||||
0x130,
|
||||
0x12E,
|
||||
0x120,
|
||||
0x135,
|
||||
0x11C,
|
||||
0,
|
||||
0x4A,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x52,
|
||||
0x4F,
|
||||
0x50,
|
||||
0x51,
|
||||
0x4B,
|
||||
0x4C,
|
||||
0x4D,
|
||||
0x47,
|
||||
0,
|
||||
0x48,
|
||||
0x49,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x3F,
|
||||
0x40,
|
||||
0x41,
|
||||
0x3D,
|
||||
0x42,
|
||||
0x43,
|
||||
0,
|
||||
0x57,
|
||||
0,
|
||||
0x137,
|
||||
0,
|
||||
0x46,
|
||||
0,
|
||||
0x44,
|
||||
0x15D,
|
||||
0x58,
|
||||
0,
|
||||
0, // Pause/Break key.
|
||||
0x152,
|
||||
0x147,
|
||||
0x149,
|
||||
0x153,
|
||||
0x3E,
|
||||
0x14F,
|
||||
0x3C,
|
||||
0x151,
|
||||
0x3B,
|
||||
0x14B,
|
||||
0x14D,
|
||||
0x150,
|
||||
0x148,
|
||||
0,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(__unix__) && !defined(__HAIKU__)
|
||||
static std::unordered_map<uint32_t, uint16_t> evdev_to_xt = {
|
||||
{96, 0x11C},
|
||||
{ 97, 0x11D},
|
||||
{ 98, 0x135},
|
||||
{ 99, 0x71 },
|
||||
{ 100, 0x138},
|
||||
{ 101, 0x1C },
|
||||
{ 102, 0x147},
|
||||
{ 103, 0x148},
|
||||
{ 104, 0x149},
|
||||
{ 105, 0x14B},
|
||||
{ 106, 0x14D},
|
||||
{ 107, 0x14F},
|
||||
{ 108, 0x150},
|
||||
{ 109, 0x151},
|
||||
{ 110, 0x152},
|
||||
{ 111, 0x153}
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __HAIKU__
|
||||
static std::unordered_map<uint8_t, uint16_t> be_to_xt = {
|
||||
{0x01, 0x01 },
|
||||
{ B_F1_KEY, 0x3B },
|
||||
{ B_F2_KEY, 0x3C },
|
||||
{ B_F3_KEY, 0x3D },
|
||||
{ B_F4_KEY, 0x3E },
|
||||
{ B_F5_KEY, 0x3F },
|
||||
{ B_F6_KEY, 0x40 },
|
||||
{ B_F7_KEY, 0x41 },
|
||||
{ B_F8_KEY, 0x42 },
|
||||
{ B_F9_KEY, 0x43 },
|
||||
{ B_F10_KEY, 0x44 },
|
||||
{ B_F11_KEY, 0x57 },
|
||||
{ B_F12_KEY, 0x58 },
|
||||
{ 0x11, 0x29 },
|
||||
{ 0x12, 0x02 },
|
||||
{ 0x13, 0x03 },
|
||||
{ 0x14, 0x04 },
|
||||
{ 0x15, 0x05 },
|
||||
{ 0x16, 0x06 },
|
||||
{ 0x17, 0x07 },
|
||||
{ 0x18, 0x08 },
|
||||
{ 0x19, 0x09 },
|
||||
{ 0x1A, 0x0A },
|
||||
{ 0x1B, 0x0B },
|
||||
{ 0x1C, 0x0C },
|
||||
{ 0x1D, 0x0D },
|
||||
{ 0x1E, 0x0E },
|
||||
{ 0x1F, 0x152},
|
||||
{ 0x20, 0x147},
|
||||
{ 0x21, 0x149},
|
||||
{ 0x22, 0x45 },
|
||||
{ 0x23, 0x135},
|
||||
{ 0x24, 0x37 },
|
||||
{ 0x25, 0x4A },
|
||||
{ 0x26, 0x0F },
|
||||
{ 0x27, 0x10 },
|
||||
{ 0x28, 0x11 },
|
||||
{ 0x29, 0x12 },
|
||||
{ 0x2A, 0x13 },
|
||||
{ 0x2B, 0x14 },
|
||||
{ 0x2C, 0x15 },
|
||||
{ 0x2D, 0x16 },
|
||||
{ 0x2E, 0x17 },
|
||||
{ 0x2F, 0x18 },
|
||||
{ 0x30, 0x19 },
|
||||
{ 0x31, 0x1A },
|
||||
{ 0x32, 0x1B },
|
||||
{ 0x33, 0x2B },
|
||||
{ 0x34, 0x153},
|
||||
{ 0x35, 0x14F},
|
||||
{ 0x36, 0x151},
|
||||
{ 0x37, 0x47 },
|
||||
{ 0x38, 0x48 },
|
||||
{ 0x39, 0x49 },
|
||||
{ 0x3A, 0x4E },
|
||||
{ 0x3B, 0x3A },
|
||||
{ 0x3C, 0x1E },
|
||||
{ 0x3D, 0x1F },
|
||||
{ 0x3E, 0x20 },
|
||||
{ 0x3F, 0x21 },
|
||||
{ 0x40, 0x22 },
|
||||
{ 0x41, 0x23 },
|
||||
{ 0x42, 0x24 },
|
||||
{ 0x43, 0x25 },
|
||||
{ 0x44, 0x26 },
|
||||
{ 0x45, 0x27 },
|
||||
{ 0x46, 0x28 },
|
||||
{ 0x47, 0x1C },
|
||||
{ 0x48, 0x4B },
|
||||
{ 0x49, 0x4C },
|
||||
{ 0x4A, 0x4D },
|
||||
{ 0x4B, 0x2A },
|
||||
{ 0x4C, 0x2C },
|
||||
{ 0x4D, 0x2D },
|
||||
{ 0x4E, 0x2E },
|
||||
{ 0x4F, 0x2F },
|
||||
{ 0x50, 0x30 },
|
||||
{ 0x51, 0x31 },
|
||||
{ 0x52, 0x32 },
|
||||
{ 0x53, 0x33 },
|
||||
{ 0x54, 0x34 },
|
||||
{ 0x55, 0x35 },
|
||||
{ 0x56, 0x36 },
|
||||
{ 0x57, 0x148},
|
||||
{ 0x58, 0x51 },
|
||||
{ 0x59, 0x50 },
|
||||
{ 0x5A, 0x4F },
|
||||
{ 0x5B, 0x11C},
|
||||
{ 0x5C, 0x1D },
|
||||
{ 0x5D, 0x38 },
|
||||
{ 0x5E, 0x39 },
|
||||
{ 0x5F, 0x138},
|
||||
{ 0x60, 0x11D},
|
||||
{ 0x61, 0x14B},
|
||||
{ 0x62, 0x150},
|
||||
{ 0x63, 0x14D},
|
||||
{ 0x64, 0x52 },
|
||||
{ 0x65, 0x53 },
|
||||
|
||||
{ 0x0e, 0x137},
|
||||
{ 0x0f, 0x46 },
|
||||
{ 0x66, 0x15B},
|
||||
{ 0x67, 0x15C},
|
||||
{ 0x68, 0x15D},
|
||||
{ 0x69, 0x56 }
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(__unix__) && !defined(__HAIKU__)
|
||||
static std::array<uint32_t, 256> &selected_keycode = x11_to_xt_base;
|
||||
#endif
|
||||
|
||||
uint16_t
|
||||
x11_keycode_to_keysym(uint32_t keycode)
|
||||
void
|
||||
MainWindow::processKeyboardInput(bool down, uint32_t keycode)
|
||||
{
|
||||
uint16_t finalkeycode = 0;
|
||||
#if defined(Q_OS_WINDOWS)
|
||||
finalkeycode = (keycode & 0xFFFF);
|
||||
#if defined(Q_OS_WINDOWS) /* non-raw input */
|
||||
keycode &= 0xffff;
|
||||
#elif defined(Q_OS_MACOS)
|
||||
finalkeycode = darwin_to_xt[keycode];
|
||||
keycode = (keycode < 127) ? cocoa_keycodes[keycode] : 0;
|
||||
#elif defined(__HAIKU__)
|
||||
finalkeycode = be_to_xt[keycode];
|
||||
keycode = be_keycodes[keycode];
|
||||
#else
|
||||
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];
|
||||
}
|
||||
# ifdef XKBCOMMON
|
||||
if (xkbcommon_keymap)
|
||||
keycode = xkbcommon_translate(keycode);
|
||||
else
|
||||
# endif
|
||||
# ifdef EVDEV_KEYBOARD_HPP
|
||||
keycode = evdev_translate(keycode - 8);
|
||||
# else
|
||||
keycode = 0;
|
||||
# endif
|
||||
#endif
|
||||
if (rctrl_is_lalt && finalkeycode == 0x11D)
|
||||
finalkeycode = 0x38;
|
||||
return finalkeycode;
|
||||
|
||||
/* Apply special cases. */
|
||||
switch (keycode) {
|
||||
case 0x54: /* Alt + Print Screen (special case, i.e. evdev SELECTIVE_SCREENSHOT) */
|
||||
/* Send Alt as well. */
|
||||
if (down) {
|
||||
keyboard_input(down, 0x38);
|
||||
} else {
|
||||
keyboard_input(down, keycode);
|
||||
keycode = 0x38;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x11d: /* Right Ctrl */
|
||||
if (rctrl_is_lalt)
|
||||
keycode = 0x38; /* map to Left Alt */
|
||||
break;
|
||||
|
||||
case 0x137: /* Print Screen */
|
||||
if (keyboard_recv(0x38) || keyboard_recv(0x138)) { /* Alt+ */
|
||||
keycode = 0x54;
|
||||
} else if (down) {
|
||||
keyboard_input(down, 0x12a);
|
||||
} else {
|
||||
keyboard_input(down, keycode);
|
||||
keycode = 0x12a;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x145: /* Pause */
|
||||
if (keyboard_recv(0x1d) || keyboard_recv(0x11d)) { /* Ctrl+ */
|
||||
keycode = 0x146;
|
||||
} else {
|
||||
keyboard_input(down, 0xe11d);
|
||||
keycode &= 0x00ff;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
keyboard_input(down, keycode);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
@@ -1545,6 +985,7 @@ static std::unordered_map<uint32_t, uint16_t> mac_modifiers_to_xt = {
|
||||
{ NX_DEVICE_ALPHASHIFT_STATELESS_MASK, 0x3A },
|
||||
{ NX_DEVICERCTLKEYMASK, 0x11D},
|
||||
};
|
||||
static bool mac_iso_swap = false;
|
||||
|
||||
void
|
||||
MainWindow::processMacKeyboardInput(bool down, const QKeyEvent *event)
|
||||
@@ -1585,11 +1026,62 @@ MainWindow::processMacKeyboardInput(bool down, const QKeyEvent *event)
|
||||
// It's possible that other lock keys get delivered in this way, but
|
||||
// standard Apple keyboards don't have them, so this is untested.
|
||||
if (event->key() == Qt::Key_CapsLock) {
|
||||
keyboard_input(1, 0x3A);
|
||||
keyboard_input(0, 0x3A);
|
||||
keyboard_input(1, 0x3a);
|
||||
keyboard_input(0, 0x3a);
|
||||
}
|
||||
} else {
|
||||
keyboard_input(down, x11_keycode_to_keysym(event->nativeVirtualKey()));
|
||||
/* Apple ISO keyboards are notorious for swapping ISO_Section and ANSI_Grave
|
||||
on *some* layouts and/or models. While macOS can sort this mess out at
|
||||
keymap level, it still provides applications with unfiltered, ambiguous
|
||||
keycodes, so we have to disambiguate them by making some bold assumptions
|
||||
about the user's keyboard layout based on the OS-provided key mappings. */
|
||||
auto nvk = event->nativeVirtualKey();
|
||||
if ((nvk == 0x0a) || (nvk == 0x32)) {
|
||||
/* Flaws:
|
||||
- Layouts with `~ on ISO_Section are partially detected due to a conflict with ANSI
|
||||
- Czech and Slovak are not detected as they have <> ANSI_Grave and \| ISO_Section (differing from PC actually)
|
||||
- Italian is partially detected due to \| conflicting with Brazilian
|
||||
- Romanian third level ANSI_Grave is unknown
|
||||
- Russian clusters <>, plusminus and paragraph into a four-level ANSI_Grave, with the aforementioned `~ on ISO_Section */
|
||||
auto key = event->key();
|
||||
if ((nvk == 0x32) && ( /* system reports ANSI_Grave for ISO_Section keys: */
|
||||
(key == Qt::Key_Less) || (key == Qt::Key_Greater) || /* Croatian, French, German, Icelandic, Italian, Norwegian, Portuguese, Spanish, Spanish Latin America, Turkish Q */
|
||||
(key == Qt::Key_Ugrave) || /* French Canadian */
|
||||
(key == Qt::Key_Icircumflex) || /* Romanian */
|
||||
(key == Qt::Key_Iacute) || /* Hungarian */
|
||||
(key == Qt::Key_BracketLeft) || (key == Qt::Key_BracketRight) || /* Russian upper two levels */
|
||||
(key == Qt::Key_W) /* Turkish F */
|
||||
))
|
||||
mac_iso_swap = true;
|
||||
else if ((nvk == 0x0a) && ( /* system reports ISO_Section for ANSI_Grave keys: */
|
||||
(key == Qt::Key_paragraph) || (key == Qt::Key_plusminus) || /* Arabic, British, Bulgarian, Danish shifted, Dutch, Greek, Hebrew, Hungarian shifted, International English, Norwegian shifted, Portuguese, Russian lower two levels, Swiss unshifted, Swedish unshifted, Turkish F */
|
||||
(key == Qt::Key_At) || (key == Qt::Key_NumberSign) || /* Belgian, French */
|
||||
(key == Qt::Key_Apostrophe) || /* Brazilian unshifted */
|
||||
(key == Qt::Key_QuoteDbl) || /* Brazilian shifted, Turkish Q unshifted */
|
||||
(key == Qt::Key_QuoteLeft) || /* Croatian (right quote unknown) */
|
||||
(key == Qt::Key_Dollar) || /* Danish unshifted */
|
||||
(key == Qt::Key_AsciiCircum) || (key == 0x1ffffff) || /* German unshifted (0x1ffffff according to one tester), Polish unshifted */
|
||||
(key == Qt::Key_degree) || /* German shifted, Icelandic unshifted, Spanish Latin America shifted, Swiss shifted, Swedish shifted */
|
||||
(key == Qt::Key_0) || /* Hungarian unshifted */
|
||||
(key == Qt::Key_diaeresis) || /* Icelandic shifted */
|
||||
(key == Qt::Key_acute) || /* Norwegian unshifted */
|
||||
(key == Qt::Key_Asterisk) || /* Polish shifted */
|
||||
(key == Qt::Key_masculine) || (key == Qt::Key_ordfeminine) || /* Spanish (masculine unconfirmed) */
|
||||
(key == Qt::Key_Eacute) || /* Turkish Q shifted */
|
||||
(key == Qt::Key_Slash) /* French Canadian unshifted, Ukrainian shifted */
|
||||
))
|
||||
mac_iso_swap = true;
|
||||
#if 0
|
||||
if (down) {
|
||||
QMessageBox questionbox(QMessageBox::Icon::Information, QString("Mac key swap test"), QString("nativeVirtualKey 0x%1\nnativeScanCode 0x%2\nkey 0x%3\nmac_iso_swap %4").arg(nvk, 0, 16).arg(event->nativeScanCode(), 0, 16).arg(key, 0, 16).arg(mac_iso_swap ? "yes" : "no"), QMessageBox::Ok, this);
|
||||
questionbox.exec();
|
||||
}
|
||||
#endif
|
||||
if (mac_iso_swap)
|
||||
nvk = (nvk == 0x0a) ? 0x32 : 0x0a;
|
||||
}
|
||||
|
||||
processKeyboardInput(down, nvk);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1733,23 +1225,10 @@ void
|
||||
MainWindow::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if (send_keyboard_input && !(kbd_req_capture && !mouse_capture)) {
|
||||
// Windows keys in Qt have one-to-one mapping.
|
||||
if (event->key() == Qt::Key_Pause && !keyboard_recv(0x38) && !keyboard_recv(0x138)) {
|
||||
if ((keyboard_recv(0x1D) || keyboard_recv(0x11D))) {
|
||||
keyboard_input(1, 0x46);
|
||||
} else {
|
||||
keyboard_input(0, 0xE1);
|
||||
keyboard_input(0, 0x1D);
|
||||
keyboard_input(0, 0x45);
|
||||
keyboard_input(0, 0xE1);
|
||||
keyboard_input(1, 0x1D);
|
||||
keyboard_input(1, 0x45);
|
||||
}
|
||||
} else
|
||||
#ifdef Q_OS_MACOS
|
||||
processMacKeyboardInput(true, event);
|
||||
processMacKeyboardInput(true, event);
|
||||
#else
|
||||
keyboard_input(1, x11_keycode_to_keysym(event->nativeScanCode()));
|
||||
processKeyboardInput(true, event->nativeScanCode());
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1797,7 +1276,7 @@ MainWindow::keyReleaseEvent(QKeyEvent *event)
|
||||
#ifdef Q_OS_MACOS
|
||||
processMacKeyboardInput(false, event);
|
||||
#else
|
||||
keyboard_input(0, x11_keycode_to_keysym(event->nativeScanCode()));
|
||||
processKeyboardInput(false, event->nativeScanCode());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -155,6 +155,7 @@ private:
|
||||
std::unique_ptr<MachineStatus> status;
|
||||
std::shared_ptr<MediaMenu> mm;
|
||||
|
||||
void processKeyboardInput(bool down, uint32_t keycode);
|
||||
#ifdef Q_OS_MACOS
|
||||
uint32_t last_modifiers = 0;
|
||||
void processMacKeyboardInput(bool down, const QKeyEvent *event);
|
||||
|
||||
234
src/qt/xkbcommon_keyboard.cpp
Normal file
234
src/qt/xkbcommon_keyboard.cpp
Normal file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* 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>
|
||||
#include "evdev_keyboard.hpp"
|
||||
|
||||
#define IS_DEC_DIGIT(c) (((c) >= '0') && ((c) <= '9'))
|
||||
#define IS_HEX_DIGIT(c) (IS_DEC_DIGIT(c) || (((c) >= 'A') && ((c) <= 'F')) || (((c) >= 'a') && ((c) <= 'f')))
|
||||
|
||||
static 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},
|
||||
{"LNFD", 0x1c}, /* linefeed => Enter */
|
||||
|
||||
{"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 => Scroll Lock (for Apple keyboards) */
|
||||
{"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},
|
||||
{"FK16", 0x5d}, /* F16 => F13 */
|
||||
{"FK17", 0x5e}, /* F17 => F14 */
|
||||
{"FK18", 0x5f}, /* F18 => F15 */
|
||||
|
||||
/* Japanese keys. */
|
||||
{"JPCM", 0x5c}, /* Num, */
|
||||
{"KPDC", 0x5c},
|
||||
{"HKTG", 0x70}, /* hiragana-katakana toggle */
|
||||
{"AB11", 0x73}, /* \_ and Brazilian /? */
|
||||
{"HZTG", 0x76}, /* hankaku-zenkaku toggle */
|
||||
{"HIRA", 0x77},
|
||||
{"KATA", 0x78},
|
||||
{"HENK", 0x79},
|
||||
{"KANA", 0x79}, /* kana => henkan (for Apple keyboards) */
|
||||
{"MUHE", 0x7b},
|
||||
{"EISU", 0x7b}, /* eisu => muhenkan (for Apple keyboards) */
|
||||
{"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 => SysRq (for Apple keyboards) */
|
||||
{"RALT", 0x138},
|
||||
{"ALGR", 0x138},
|
||||
{"LVL3", 0x138}, /* observed on TigerVNC with AltGr-enabled layout */
|
||||
{"PAUS", 0x145},
|
||||
{"FK15", 0x145}, /* F15 => Pause (for Apple keyboards) */
|
||||
{"BRK", 0x145},
|
||||
{"HOME", 0x147},
|
||||
{"UP", 0x148},
|
||||
{"PGUP", 0x149},
|
||||
{"LEFT", 0x14b},
|
||||
{"RGHT", 0x14d},
|
||||
{"END", 0x14f},
|
||||
{"DOWN", 0x150},
|
||||
{"PGDN", 0x151},
|
||||
{"INS", 0x152},
|
||||
{"DELE", 0x153},
|
||||
|
||||
{"LWIN", 0x15b},
|
||||
{"LMTA", 0x15b},
|
||||
{"RWIN", 0x15c},
|
||||
{"RMTA", 0x15c},
|
||||
{"MENU", 0x15d},
|
||||
{"COMP", 0x15d}, /* Compose as Menu */
|
||||
|
||||
/* Multimedia keys. Same notes as evdev_keyboard apply here. */
|
||||
{"KPEQ", 0x59}, /* Num= */
|
||||
{"FRNT", 0x101}, /* # Logitech Task Select */
|
||||
{"UNDO", 0x108}, /* # */
|
||||
{"PAST", 0x10a}, /* # Paste */
|
||||
{"FIND", 0x112}, /* # Logitech */
|
||||
{"CUT", 0x117}, /* # */
|
||||
{"COPY", 0x118}, /* # */
|
||||
{"MUTE", 0x120},
|
||||
{"VOL-", 0x12e},
|
||||
{"VOL+", 0x130},
|
||||
{"HELP", 0x13b},
|
||||
{"OPEN", 0x13f},
|
||||
{"POWR", 0x15e},
|
||||
{"STOP", 0x168},
|
||||
};
|
||||
struct xkb_keymap *xkbcommon_keymap = nullptr;
|
||||
|
||||
void
|
||||
xkbcommon_init(struct xkb_keymap *keymap)
|
||||
{
|
||||
if (keymap)
|
||||
xkbcommon_keymap = keymap;
|
||||
}
|
||||
|
||||
void
|
||||
xkbcommon_close()
|
||||
{
|
||||
xkbcommon_keymap = nullptr;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
xkbcommon_translate(uint32_t keycode)
|
||||
{
|
||||
const char *key_name = xkb_keymap_key_get_name(xkbcommon_keymap, keycode);
|
||||
|
||||
/* If XKB doesn't know the key name for this keycode, assume an unnamed Ixxx key.
|
||||
This is useful for older XKB versions with an incomplete evdev keycode map. */
|
||||
auto key_name_s = key_name ? std::string(key_name) : QString("I%1").arg(keycode).toStdString();
|
||||
auto ret = xkb_keycodes[key_name_s];
|
||||
|
||||
/* Observed with multimedia keys on Windows VcXsrv. */
|
||||
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);
|
||||
|
||||
/* Translate unnamed evdev-specific keycodes. */
|
||||
if (!ret && (key_name_s.length() >= 2) && (key_name_s[0] == 'I') && IS_DEC_DIGIT(key_name_s[1]))
|
||||
ret = evdev_translate(stoi(key_name_s.substr(1)) - 8);
|
||||
|
||||
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;
|
||||
}
|
||||
20
src/qt/xkbcommon_keyboard.hpp
Normal file
20
src/qt/xkbcommon_keyboard.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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);
|
||||
void xkbcommon_close();
|
||||
uint16_t xkbcommon_translate(uint32_t keycode);
|
||||
241
src/qt/xkbcommon_wl_keyboard.cpp
Normal file
241
src/qt/xkbcommon_wl_keyboard.cpp
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 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 Wayland keyboard input module.
|
||||
*
|
||||
* Heavily inspired by libxkbcommon interactive-wayland.c
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2023 RichardG.
|
||||
*/
|
||||
extern "C" {
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <86box/86box.h>
|
||||
};
|
||||
#include "xkbcommon_keyboard.hpp"
|
||||
#include <wayland-client.h>
|
||||
#include <wayland-util.h>
|
||||
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#include <QtDebug>
|
||||
#include <QGuiApplication>
|
||||
|
||||
typedef struct {
|
||||
struct wl_seat *wl_seat;
|
||||
struct wl_keyboard *wl_kbd;
|
||||
uint32_t version;
|
||||
|
||||
struct xkb_keymap *keymap;
|
||||
|
||||
struct wl_list link;
|
||||
} seat_t;
|
||||
|
||||
static bool wl_init_ok = false;
|
||||
static struct wl_list seats;
|
||||
static struct xkb_context *ctx;
|
||||
|
||||
static void
|
||||
xkbcommon_wl_set_keymap()
|
||||
{
|
||||
/* Grab keymap from the first seat with one. */
|
||||
seat_t *seat, *tmp;
|
||||
wl_list_for_each_safe(seat, tmp, &seats, link) {
|
||||
if (seat->keymap) {
|
||||
xkbcommon_init(seat->keymap);
|
||||
return;
|
||||
}
|
||||
}
|
||||
xkbcommon_close(); /* none found */
|
||||
}
|
||||
|
||||
static void
|
||||
kbd_keymap(void *data, struct wl_keyboard *wl_kbd, uint32_t format,
|
||||
int fd, uint32_t size)
|
||||
{
|
||||
seat_t *seat = (seat_t *) data;
|
||||
|
||||
char *buf = (char *) mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (!buf) {
|
||||
qWarning() << "XKB Keyboard: Failed to mmap keymap with error" << errno;
|
||||
return;
|
||||
}
|
||||
|
||||
if (seat->keymap) {
|
||||
static struct xkb_keymap *keymap = seat->keymap;
|
||||
seat->keymap = NULL;
|
||||
xkbcommon_wl_set_keymap();
|
||||
xkb_keymap_unref(keymap);
|
||||
}
|
||||
|
||||
seat->keymap = xkb_keymap_new_from_buffer(ctx, buf, size - 1,
|
||||
XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
munmap(buf, size);
|
||||
close(fd);
|
||||
if (!seat->keymap)
|
||||
qWarning() << "XKB Keyboard: Keymap compilation failed";
|
||||
|
||||
xkbcommon_wl_set_keymap();
|
||||
}
|
||||
|
||||
static void
|
||||
kbd_enter(void *data, struct wl_keyboard *wl_kbd, uint32_t serial,
|
||||
struct wl_surface *surf, struct wl_array *keys)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
kbd_leave(void *data, struct wl_keyboard *wl_kbd, uint32_t serial,
|
||||
struct wl_surface *surf)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
kbd_key(void *data, struct wl_keyboard *wl_kbd, uint32_t serial, uint32_t time,
|
||||
uint32_t key, uint32_t state)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
kbd_modifiers(void *data, struct wl_keyboard *wl_kbd, uint32_t serial,
|
||||
uint32_t mods_depressed, uint32_t mods_latched,
|
||||
uint32_t mods_locked, uint32_t group)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
kbd_repeat_info(void *data, struct wl_keyboard *wl_kbd, int32_t rate,
|
||||
int32_t delay)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_keyboard_listener kbd_listener = {
|
||||
kbd_keymap,
|
||||
kbd_enter,
|
||||
kbd_leave,
|
||||
kbd_key,
|
||||
kbd_modifiers,
|
||||
kbd_repeat_info
|
||||
};
|
||||
|
||||
static void
|
||||
seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t caps)
|
||||
{
|
||||
seat_t *seat = (seat_t *) data;
|
||||
|
||||
if (!seat->wl_kbd && (caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
|
||||
seat->wl_kbd = wl_seat_get_keyboard(seat->wl_seat);
|
||||
wl_keyboard_add_listener(seat->wl_kbd, &kbd_listener, seat);
|
||||
} else if (seat->wl_kbd && !(caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
|
||||
if (seat->version >= WL_SEAT_RELEASE_SINCE_VERSION)
|
||||
wl_keyboard_release(seat->wl_kbd);
|
||||
else
|
||||
wl_keyboard_destroy(seat->wl_kbd);
|
||||
|
||||
static struct xkb_keymap *keymap = seat->keymap;
|
||||
seat->keymap = NULL;
|
||||
xkbcommon_wl_set_keymap();
|
||||
xkb_keymap_unref(keymap);
|
||||
|
||||
seat->wl_kbd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
seat_name(void *data, struct wl_seat *wl_seat, const char *name)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_seat_listener seat_listener = {
|
||||
seat_capabilities,
|
||||
seat_name
|
||||
};
|
||||
|
||||
static void
|
||||
display_handle_global(void *data, struct wl_registry *wl_registry, uint32_t id,
|
||||
const char *interface, uint32_t version)
|
||||
{
|
||||
if (!strcmp(interface, "wl_seat")) {
|
||||
seat_t *seat = (seat_t *) malloc(sizeof(seat_t));
|
||||
memset(seat, 0, sizeof(seat_t));
|
||||
|
||||
seat->wl_seat = (wl_seat *) wl_registry_bind(wl_registry, id, &wl_seat_interface, MIN(version, 5));
|
||||
wl_seat_add_listener(seat->wl_seat, &seat_listener, seat);
|
||||
wl_list_insert(&seats, &seat->link);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
display_global_remove(void *data, struct wl_registry *wl_registry, uint32_t id)
|
||||
{
|
||||
xkbcommon_close();
|
||||
|
||||
seat_t *seat, *tmp;
|
||||
wl_list_for_each_safe(seat, tmp, &seats, link) {
|
||||
if (seat->wl_kbd) {
|
||||
if (seat->version >= WL_SEAT_RELEASE_SINCE_VERSION)
|
||||
wl_keyboard_release(seat->wl_kbd);
|
||||
else
|
||||
wl_keyboard_destroy(seat->wl_kbd);
|
||||
|
||||
xkb_keymap_unref(seat->keymap);
|
||||
}
|
||||
|
||||
if (seat->version >= WL_SEAT_RELEASE_SINCE_VERSION)
|
||||
wl_seat_release(seat->wl_seat);
|
||||
else
|
||||
wl_seat_destroy(seat->wl_seat);
|
||||
|
||||
wl_list_remove(&seat->link);
|
||||
free(seat);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
display_handle_global,
|
||||
display_global_remove
|
||||
};
|
||||
|
||||
void
|
||||
xkbcommon_wl_init()
|
||||
{
|
||||
if (wl_init_ok)
|
||||
return;
|
||||
|
||||
wl_list_init(&seats);
|
||||
|
||||
ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if (!ctx) {
|
||||
qWarning() << "XKB Keyboard: XKB context creation failed";
|
||||
return;
|
||||
}
|
||||
|
||||
wl_display *display = (wl_display *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_display");
|
||||
if (display) {
|
||||
auto registry = wl_display_get_registry(display);
|
||||
if (registry) {
|
||||
wl_registry_add_listener(registry, ®istry_listener, nullptr);
|
||||
wl_display_roundtrip(display);
|
||||
wl_display_roundtrip(display);
|
||||
} else {
|
||||
goto err_ctx;
|
||||
}
|
||||
} else {
|
||||
goto err_ctx;
|
||||
}
|
||||
wl_init_ok = true;
|
||||
return;
|
||||
|
||||
err_ctx:
|
||||
xkb_context_unref(ctx);
|
||||
}
|
||||
17
src/qt/xkbcommon_wl_keyboard.hpp
Normal file
17
src/qt/xkbcommon_wl_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 Wayland keyboard input module.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2023 RichardG.
|
||||
*/
|
||||
void xkbcommon_wl_init();
|
||||
86
src/qt/xkbcommon_x11_keyboard.cpp
Normal file
86
src/qt/xkbcommon_x11_keyboard.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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 <qpa/qplatformnativeinterface.h>
|
||||
#include <QtDebug>
|
||||
#include <QGuiApplication>
|
||||
|
||||
void
|
||||
xkbcommon_x11_init()
|
||||
{
|
||||
xcb_connection_t *conn;
|
||||
struct xkb_context *ctx;
|
||||
int32_t core_kbd_device_id;
|
||||
struct xkb_keymap *keymap;
|
||||
|
||||
conn = (xcb_connection_t *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("connection");
|
||||
if (!conn) {
|
||||
qWarning() << "XKB Keyboard: X server connection failed";
|
||||
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";
|
||||
return;
|
||||
}
|
||||
|
||||
ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if (!ctx) {
|
||||
qWarning() << "XKB Keyboard: XKB context creation failed";
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
return;
|
||||
|
||||
err_ctx:
|
||||
xkb_context_unref(ctx);
|
||||
}
|
||||
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