mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-14 21:17:54 +00:00
[client] wayland: add keyboard typing handling with xkbcommon
This commit is contained in:
parent
9414449408
commit
7045760490
3 changed files with 91 additions and 1 deletions
|
@ -5,6 +5,7 @@ find_package(PkgConfig)
|
||||||
pkg_check_modules(DISPLAYSERVER_Wayland REQUIRED IMPORTED_TARGET
|
pkg_check_modules(DISPLAYSERVER_Wayland REQUIRED IMPORTED_TARGET
|
||||||
wayland-client
|
wayland-client
|
||||||
wayland-cursor
|
wayland-cursor
|
||||||
|
xkbcommon
|
||||||
)
|
)
|
||||||
|
|
||||||
set(DISPLAYSERVER_Wayland_OPT_PKGCONFIG_LIBRARIES "")
|
set(DISPLAYSERVER_Wayland_OPT_PKGCONFIG_LIBRARIES "")
|
||||||
|
|
|
@ -20,11 +20,14 @@
|
||||||
|
|
||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
|
@ -159,6 +162,50 @@ static const struct zwp_relative_pointer_v1_listener relativePointerListener = {
|
||||||
static void keyboardKeymapHandler(void * data, struct wl_keyboard * keyboard,
|
static void keyboardKeymapHandler(void * data, struct wl_keyboard * keyboard,
|
||||||
uint32_t format, int fd, uint32_t size)
|
uint32_t format, int fd, uint32_t size)
|
||||||
{
|
{
|
||||||
|
if (!wlWm.xkb)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (wlWm.keymap)
|
||||||
|
{
|
||||||
|
xkb_keymap_unref(wlWm.keymap);
|
||||||
|
wlWm.keymap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wlWm.xkbState)
|
||||||
|
{
|
||||||
|
xkb_state_unref(wlWm.xkbState);
|
||||||
|
wlWm.xkbState = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
|
||||||
|
{
|
||||||
|
DEBUG_WARN("Unsupported keymap format, keyboard input will not work: %d", format);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||||
|
if (map == MAP_FAILED)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to mmap keymap: %s", strerror(errno));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlWm.keymap = xkb_keymap_new_from_string(wlWm.xkb, map,
|
||||||
|
XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
|
||||||
|
if (!wlWm.keymap)
|
||||||
|
DEBUG_WARN("Failed to load keymap, keyboard input will not work");
|
||||||
|
|
||||||
|
munmap(map, size);
|
||||||
|
|
||||||
|
if (wlWm.keymap)
|
||||||
|
{
|
||||||
|
wlWm.xkbState = xkb_state_new(wlWm.keymap);
|
||||||
|
if (!wlWm.xkbState)
|
||||||
|
DEBUG_WARN("Failed to create xkb_state");
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,13 +245,35 @@ static void keyboardKeyHandler(void * data, struct wl_keyboard * keyboard,
|
||||||
app_handleKeyPress(key);
|
app_handleKeyPress(key);
|
||||||
else
|
else
|
||||||
app_handleKeyRelease(key);
|
app_handleKeyRelease(key);
|
||||||
|
|
||||||
|
if (!wlWm.xkbState || !app_isOverlayMode() || state != WL_KEYBOARD_KEY_STATE_PRESSED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
key += 8; // xkb scancode is evdev scancode + 8
|
||||||
|
int size = xkb_state_key_get_utf8(wlWm.xkbState, key, NULL, 0);
|
||||||
|
|
||||||
|
if (size <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char buffer[size + 1];
|
||||||
|
xkb_state_key_get_utf8(wlWm.xkbState, key, buffer, size + 1);
|
||||||
|
app_handleKeyboardTyped(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keyboardModifiersHandler(void * data,
|
static void keyboardModifiersHandler(void * data,
|
||||||
struct wl_keyboard * keyboard, uint32_t serial, uint32_t modsDepressed,
|
struct wl_keyboard * keyboard, uint32_t serial, uint32_t modsDepressed,
|
||||||
uint32_t modsLatched, uint32_t modsLocked, uint32_t group)
|
uint32_t modsLatched, uint32_t modsLocked, uint32_t group)
|
||||||
{
|
{
|
||||||
// Do nothing.
|
if (!wlWm.xkbState)
|
||||||
|
return;
|
||||||
|
|
||||||
|
xkb_state_update_mask(wlWm.xkbState, modsDepressed, modsLatched, modsLocked, 0, 0, group);
|
||||||
|
app_handleKeyboardModifiers(
|
||||||
|
xkb_state_mod_name_is_active(wlWm.xkbState, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_EFFECTIVE) > 0,
|
||||||
|
xkb_state_mod_name_is_active(wlWm.xkbState, XKB_MOD_NAME_SHIFT, XKB_STATE_MODS_EFFECTIVE) > 0,
|
||||||
|
xkb_state_mod_name_is_active(wlWm.xkbState, XKB_MOD_NAME_ALT, XKB_STATE_MODS_EFFECTIVE) > 0,
|
||||||
|
xkb_state_mod_name_is_active(wlWm.xkbState, XKB_MOD_NAME_LOGO, XKB_STATE_MODS_EFFECTIVE) > 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_keyboard_listener keyboardListener = {
|
static const struct wl_keyboard_listener keyboardListener = {
|
||||||
|
@ -293,6 +362,10 @@ bool waylandInputInit(void)
|
||||||
DEBUG_WARN("zwp_keyboard_shortcuts_inhibit_manager_v1 not exported by "
|
DEBUG_WARN("zwp_keyboard_shortcuts_inhibit_manager_v1 not exported by "
|
||||||
"compositor, keyboard will not be grabbed");
|
"compositor, keyboard will not be grabbed");
|
||||||
|
|
||||||
|
wlWm.xkb = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
|
if (!wlWm.xkb)
|
||||||
|
DEBUG_WARN("Failed to initialize xkb, keyboard input will not work");
|
||||||
|
|
||||||
wl_seat_add_listener(wlWm.seat, &seatListener, NULL);
|
wl_seat_add_listener(wlWm.seat, &seatListener, NULL);
|
||||||
wl_display_roundtrip(wlWm.display);
|
wl_display_roundtrip(wlWm.display);
|
||||||
|
|
||||||
|
@ -317,6 +390,15 @@ void waylandInputFree(void)
|
||||||
wl_pointer_destroy(wlWm.pointer);
|
wl_pointer_destroy(wlWm.pointer);
|
||||||
wl_keyboard_destroy(wlWm.keyboard);
|
wl_keyboard_destroy(wlWm.keyboard);
|
||||||
wl_seat_destroy(wlWm.seat);
|
wl_seat_destroy(wlWm.seat);
|
||||||
|
|
||||||
|
if (wlWm.xkbState)
|
||||||
|
xkb_state_unref(wlWm.xkbState);
|
||||||
|
|
||||||
|
if (wlWm.keymap)
|
||||||
|
xkb_keymap_unref(wlWm.keymap);
|
||||||
|
|
||||||
|
if (wlWm.xkb)
|
||||||
|
xkb_context_unref(wlWm.xkb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void waylandGrabPointer(void)
|
void waylandGrabPointer(void)
|
||||||
|
|
|
@ -88,6 +88,10 @@ enum EGLSwapWithDamageState {
|
||||||
SWAP_WITH_DAMAGE_EXT,
|
SWAP_WITH_DAMAGE_EXT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct xkb_context;
|
||||||
|
struct xkb_keymap;
|
||||||
|
struct xkb_state;
|
||||||
|
|
||||||
struct WaylandDSState
|
struct WaylandDSState
|
||||||
{
|
{
|
||||||
bool pointerGrabbed;
|
bool pointerGrabbed;
|
||||||
|
@ -155,6 +159,9 @@ struct WaylandDSState
|
||||||
struct zwp_keyboard_shortcuts_inhibit_manager_v1 * keyboardInhibitManager;
|
struct zwp_keyboard_shortcuts_inhibit_manager_v1 * keyboardInhibitManager;
|
||||||
struct zwp_keyboard_shortcuts_inhibitor_v1 * keyboardInhibitor;
|
struct zwp_keyboard_shortcuts_inhibitor_v1 * keyboardInhibitor;
|
||||||
uint32_t keyboardEnterSerial;
|
uint32_t keyboardEnterSerial;
|
||||||
|
struct xkb_context * xkb;
|
||||||
|
struct xkb_state * xkbState;
|
||||||
|
struct xkb_keymap * keymap;
|
||||||
|
|
||||||
struct wl_pointer * pointer;
|
struct wl_pointer * pointer;
|
||||||
struct zwp_relative_pointer_manager_v1 * relativePointerManager;
|
struct zwp_relative_pointer_manager_v1 * relativePointerManager;
|
||||||
|
|
Loading…
Reference in a new issue