summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2020-03-11 11:46:19 +0100
committerSimon Ser <contact@emersion.fr>2020-03-11 11:47:03 +0100
commit7ed9b05325c2755763c7394b9f3ffcbed3b69711 (patch)
treea499e68fe5351d5acf5ed534ac355682d525fc88
parentcf9e78a43f9a0dde33a86d965b0799662ecfa823 (diff)
Forward unhandled keys via virtual-keyboard
-rw-r--r--include/wlhangul.h4
-rw-r--r--main.c78
-rw-r--r--protocol/meson.build1
-rw-r--r--protocol/virtual-keyboard-unstable-v1.xml113
4 files changed, 179 insertions, 17 deletions
diff --git a/include/wlhangul.h b/include/wlhangul.h
index f92afcd..3b610f0 100644
--- a/include/wlhangul.h
+++ b/include/wlhangul.h
@@ -4,10 +4,12 @@
#include <hangul.h>
#include <stdbool.h>
#include <wayland-client-core.h>
+#include <xkbcommon/xkbcommon.h>
struct wlhangul_state {
struct wl_display *display;
struct zwp_input_method_manager_v2 *input_method_manager;
+ struct zwp_virtual_keyboard_manager_v1 *virtual_keyboard_manager;
bool running;
@@ -21,6 +23,7 @@ struct wlhangul_seat {
HangulInputContext *input_context;
struct zwp_input_method_v2 *input_method;
+ struct zwp_virtual_keyboard_v1 *virtual_keyboard;
struct xkb_context *xkb_context;
struct xkb_keymap *xkb_keymap;
@@ -30,6 +33,7 @@ struct wlhangul_seat {
uint32_t serial;
bool pending_activate, pending_deactivate;
struct zwp_input_method_keyboard_grab_v2 *keyboard_grab;
+ xkb_keycode_t pressed[64];
};
char *ucsstr_to_str(const ucschar *ucsstr);
diff --git a/main.c b/main.c
index 5b2f09c..7a0b153 100644
--- a/main.c
+++ b/main.c
@@ -4,24 +4,12 @@
#include <sys/mman.h>
#include <unistd.h>
#include <wayland-client.h>
-#include <xkbcommon/xkbcommon.h>
#include "wlhangul.h"
#include "input-method-unstable-v2-client-protocol.h"
+#include "virtual-keyboard-unstable-v1-client-protocol.h"
-static void handle_key(void *data,
- struct zwp_input_method_keyboard_grab_v2 *keyboard_grab,
- uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
- struct wlhangul_seat *seat = data;
- xkb_keycode_t xkb_key = key + 8;
-
- if (seat->xkb_state == NULL) {
- return;
- }
-
- if (state != WL_KEYBOARD_KEY_STATE_PRESSED) {
- return;
- }
-
+static bool handle_key_pressed(struct wlhangul_seat *seat,
+ xkb_keycode_t xkb_key) {
bool handled;
xkb_keysym_t sym = xkb_state_key_get_one_sym(seat->xkb_state, xkb_key);
switch (sym) {
@@ -56,9 +44,54 @@ static void handle_key(void *data,
zwp_input_method_v2_commit(seat->input_method, seat->serial);
+ if (handled) {
+ for (size_t i = 0; i < sizeof(seat->pressed) / sizeof(seat->pressed[0]); i++) {
+ if (seat->pressed[i] == 0) {
+ seat->pressed[i] = xkb_key;
+ break;
+ }
+ }
+ }
+
+ return handled;
+}
+
+static bool handle_key_released(struct wlhangul_seat *seat,
+ xkb_keycode_t xkb_key) {
+ bool handled = false;
+ for (size_t i = 0; i < sizeof(seat->pressed) / sizeof(seat->pressed[0]); i++) {
+ if (seat->pressed[i] == xkb_key) {
+ seat->pressed[i] = 0;
+ handled = true;
+ break;
+ }
+ }
+
+ return handled;
+}
+
+static void handle_key(void *data,
+ struct zwp_input_method_keyboard_grab_v2 *keyboard_grab,
+ uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
+ struct wlhangul_seat *seat = data;
+ xkb_keycode_t xkb_key = key + 8;
+
+ if (seat->xkb_state == NULL) {
+ return;
+ }
+
+ bool handled = false;
+ switch (state) {
+ case WL_KEYBOARD_KEY_STATE_PRESSED:
+ handled = handle_key_pressed(seat, xkb_key);
+ break;
+ case WL_KEYBOARD_KEY_STATE_RELEASED:
+ handled = handle_key_released(seat, xkb_key);
+ break;
+ }
+
if (!handled) {
- printf("key: %d\n", xkb_key);
- // TODO: forward key
+ zwp_virtual_keyboard_v1_key(seat->virtual_keyboard, time, key, state);
}
}
@@ -74,6 +107,8 @@ static void handle_modifiers(void *data,
xkb_state_update_mask(seat->xkb_state, mods_depressed,
mods_latched, mods_locked, 0, 0, group);
+ zwp_virtual_keyboard_v1_modifiers(seat->virtual_keyboard,
+ mods_depressed, mods_latched, mods_locked, group);
}
static void handle_keymap(void *data,
@@ -81,6 +116,8 @@ static void handle_keymap(void *data,
uint32_t format, int32_t fd, uint32_t size) {
struct wlhangul_seat *seat = data;
+ zwp_virtual_keyboard_v1_keymap(seat->virtual_keyboard, format, fd, size);
+
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
close(fd);
return;
@@ -168,6 +205,7 @@ static void handle_done(void *data, struct zwp_input_method_v2 *input_method) {
} else if (seat->pending_deactivate && seat->active) {
zwp_input_method_keyboard_grab_v2_release(seat->keyboard_grab);
hangul_ic_reset(seat->input_context);
+ memset(seat->pressed, 0, sizeof(seat->pressed));
seat->keyboard_grab = NULL;
seat->active = false;
}
@@ -209,6 +247,9 @@ static void registry_handle_global(void *data, struct wl_registry *registry,
} else if (strcmp(interface, zwp_input_method_manager_v2_interface.name) == 0) {
state->input_method_manager = wl_registry_bind(registry, name,
&zwp_input_method_manager_v2_interface, 1);
+ } else if (strcmp(interface, zwp_virtual_keyboard_manager_v1_interface.name) == 0) {
+ state->virtual_keyboard_manager = wl_registry_bind(registry, name,
+ &zwp_virtual_keyboard_manager_v1_interface, 1);
}
}
@@ -248,6 +289,9 @@ int main(int argc, char *argv[]) {
state.input_method_manager, seat->wl_seat);
zwp_input_method_v2_add_listener(seat->input_method,
&input_method_listener, seat);
+ seat->virtual_keyboard =
+ zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(
+ state.virtual_keyboard_manager, seat->wl_seat);
seat->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
}
diff --git a/protocol/meson.build b/protocol/meson.build
index 0a27675..e7e77bb 100644
--- a/protocol/meson.build
+++ b/protocol/meson.build
@@ -8,6 +8,7 @@ wayland_scanner_exe = find_program(
protocols = {
'input-method-unstable-v2': 'input-method-unstable-v2.xml',
+ 'virtual-keyboard-unstable-v1': 'virtual-keyboard-unstable-v1.xml',
}
foreach name, path : protocols
diff --git a/protocol/virtual-keyboard-unstable-v1.xml b/protocol/virtual-keyboard-unstable-v1.xml
new file mode 100644
index 0000000..5095c91
--- /dev/null
+++ b/protocol/virtual-keyboard-unstable-v1.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="virtual_keyboard_unstable_v1">
+ <copyright>
+ Copyright © 2008-2011 Kristian Høgsberg
+ Copyright © 2010-2013 Intel Corporation
+ Copyright © 2012-2013 Collabora, Ltd.
+ Copyright © 2018 Purism SPC
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice (including the next
+ paragraph) shall be included in all copies or substantial portions of the
+ Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ </copyright>
+
+ <interface name="zwp_virtual_keyboard_v1" version="1">
+ <description summary="virtual keyboard">
+ The virtual keyboard provides an application with requests which emulate
+ the behaviour of a physical keyboard.
+
+ This interface can be used by clients on its own to provide raw input
+ events, or it can accompany the input method protocol.
+ </description>
+
+ <request name="keymap">
+ <description summary="keyboard mapping">
+ Provide a file descriptor to the compositor which can be
+ memory-mapped to provide a keyboard mapping description.
+
+ Format carries a value from the keymap_format enumeration.
+ </description>
+ <arg name="format" type="uint" summary="keymap format"/>
+ <arg name="fd" type="fd" summary="keymap file descriptor"/>
+ <arg name="size" type="uint" summary="keymap size, in bytes"/>
+ </request>
+
+ <enum name="error">
+ <entry name="no_keymap" value="0" summary="No keymap was set"/>
+ </enum>
+
+ <request name="key">
+ <description summary="key event">
+ A key was pressed or released.
+ The time argument is a timestamp with millisecond granularity, with an
+ undefined base. All requests regarding a single object must share the
+ same clock.
+
+ Keymap must be set before issuing this request.
+
+ State carries a value from the key_state enumeration.
+ </description>
+ <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
+ <arg name="key" type="uint" summary="key that produced the event"/>
+ <arg name="state" type="uint" summary="physical state of the key"/>
+ </request>
+
+ <request name="modifiers">
+ <description summary="modifier and group state">
+ Notifies the compositor that the modifier and/or group state has
+ changed, and it should update state.
+
+ The client should use wl_keyboard.modifiers event to synchronize its
+ internal state with seat state.
+
+ Keymap must be set before issuing this request.
+ </description>
+ <arg name="mods_depressed" type="uint" summary="depressed modifiers"/>
+ <arg name="mods_latched" type="uint" summary="latched modifiers"/>
+ <arg name="mods_locked" type="uint" summary="locked modifiers"/>
+ <arg name="group" type="uint" summary="keyboard layout"/>
+ </request>
+
+ <request name="destroy" type="destructor" since="1">
+ <description summary="destroy the virtual keyboard keyboard object"/>
+ </request>
+ </interface>
+
+ <interface name="zwp_virtual_keyboard_manager_v1" version="1">
+ <description summary="virtual keyboard manager">
+ A virtual keyboard manager allows an application to provide keyboard
+ input events as if they came from a physical keyboard.
+ </description>
+
+ <enum name="error">
+ <entry name="unauthorized" value="0" summary="client not authorized to use the interface"/>
+ </enum>
+
+ <request name="create_virtual_keyboard">
+ <description summary="Create a new virtual keyboard">
+ Creates a new virtual keyboard associated to a seat.
+
+ If the compositor enables a keyboard to perform arbitrary actions, it
+ should present an error when an untrusted client requests a new
+ keyboard.
+ </description>
+ <arg name="seat" type="object" interface="wl_seat"/>
+ <arg name="id" type="new_id" interface="zwp_virtual_keyboard_v1"/>
+ </request>
+ </interface>
+</protocol>