Merge branch 'master' of ssh://github.com/86Box/86Box

# Conflicts:
#	src/qt/qt_mainwindow.cpp
This commit is contained in:
RichardG867
2023-04-11 12:00:01 -03:00
29 changed files with 2144 additions and 1098 deletions

View File

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

View File

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

View File

@@ -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
View File

@@ -34,6 +34,8 @@ Makefile
*.tar.*
*.AppImage
/appimage-builder-cache
/appimage-build
/AppImageBuilder-generated.yml
# Visual Studio Code
/.vs

View File

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

View File

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

View File

@@ -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. */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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;
}

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

View 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, &registry_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);
}

View 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();

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

View 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();