From bd5b20e1fab67d7fb548ecde0aade8455df4509c Mon Sep 17 00:00:00 2001 From: ChemicalXandco <32775248+ChemicalXandco@users.noreply.github.com> Date: Sat, 7 Jan 2023 14:28:40 +0000 Subject: [PATCH] add wlr_virtual_keyboard_manager_v1 and wlr_virtual_pointer_manager_v1 --- cage.c | 20 ++++++++++++++++ seat.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++-------- seat.h | 1 + server.h | 7 +++--- 4 files changed, 86 insertions(+), 14 deletions(-) diff --git a/cage.c b/cage.c index a08fafc..c5eda4d 100644 --- a/cage.c +++ b/cage.c @@ -35,6 +35,8 @@ #include #include #include +#include +#include #if CAGE_HAS_XWAYLAND #include #endif @@ -270,6 +272,8 @@ main(int argc, char *argv[]) struct wlr_single_pixel_buffer_manager_v1 *single_pixel_buffer = NULL; struct wlr_xdg_output_manager_v1 *output_manager = NULL; struct wlr_gamma_control_manager_v1 *gamma_control_manager = NULL; + struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard = NULL; + struct wlr_virtual_pointer_manager_v1 *virtual_pointer = NULL; struct wlr_viewporter *viewporter = NULL; struct wlr_presentation *presentation = NULL; struct wlr_xdg_shell *xdg_shell = NULL; @@ -482,6 +486,22 @@ main(int argc, char *argv[]) goto end; } + virtual_keyboard = wlr_virtual_keyboard_manager_v1_create(server.wl_display); + if (!virtual_keyboard) { + wlr_log(WLR_ERROR, "Unable to create the virtual keyboard manager"); + ret = 1; + goto end; + } + wl_signal_add(&virtual_keyboard->events.new_virtual_keyboard, &server.new_virtual_keyboard); + + virtual_pointer = wlr_virtual_pointer_manager_v1_create(server.wl_display); + if (!virtual_pointer) { + wlr_log(WLR_ERROR, "Unable to create the virtual pointer manager"); + ret = 1; + goto end; + } + wl_signal_add(&virtual_pointer->events.new_virtual_pointer, &server.new_virtual_pointer); + #if CAGE_HAS_XWAYLAND xwayland = wlr_xwayland_create(server.wl_display, compositor, true); if (!xwayland) { diff --git a/seat.c b/seat.c index 3b65c3d..5d80e33 100644 --- a/seat.c +++ b/seat.c @@ -6,11 +6,14 @@ * See the LICENSE file accompanying this file. */ +#define _POSIX_C_SOURCE 200809L + #include "config.h" #include #include #include +#include #include #include #include @@ -22,6 +25,8 @@ #include #include #include +#include +#include #include #include #if CAGE_HAS_XWAYLAND @@ -216,6 +221,27 @@ handle_new_pointer(struct cg_seat *seat, struct wlr_pointer *wlr_pointer) map_input_device_to_output(seat, &wlr_pointer->base, wlr_pointer->output_name); } +static void +handle_virtual_pointer(struct wl_listener *listener, void *data) +{ + struct cg_server *server = wl_container_of(listener, server, new_virtual_pointer); + struct cg_seat *seat = server->seat; + struct wlr_virtual_pointer_v1_new_pointer_event *event = data; + struct wlr_virtual_pointer_v1 *pointer = event->new_pointer; + struct wlr_pointer *wlr_pointer = &pointer->pointer; + + /* We'll want to map the device back to an output later, this is a bit + * sub-optimal (we could just keep the suggested_output), but just copy + * its name so we do like other devices + */ + if (event->suggested_output != NULL) { + wlr_pointer->output_name = strdup(event->suggested_output->name); + } + /* TODO: event->suggested_seat should be checked if we handle multiple seats */ + handle_new_pointer(seat, wlr_pointer); + update_capabilities(seat); +} + static void handle_modifier_event(struct wlr_keyboard *keyboard, struct cg_seat *seat) { @@ -295,14 +321,21 @@ handle_keyboard_group_modifiers(struct wl_listener *listener, void *data) } static void -cg_keyboard_group_add(struct wlr_keyboard *keyboard, struct cg_seat *seat) +cg_keyboard_group_add(struct wlr_keyboard *keyboard, struct cg_seat *seat, bool virtual) { - struct cg_keyboard_group *group; - wl_list_for_each (group, &seat->keyboard_groups, link) { - struct wlr_keyboard_group *wlr_group = group->wlr_group; - if (wlr_keyboard_group_add_keyboard(wlr_group, keyboard)) { - wlr_log(WLR_DEBUG, "Added new keyboard to existing group"); - return; + /* We apparently should not group virtual keyboards, + * so create a new group with it + */ + if (!virtual) { + struct cg_keyboard_group *group; + wl_list_for_each (group, &seat->keyboard_groups, link) { + if (group->is_virtual) + continue; + struct wlr_keyboard_group *wlr_group = group->wlr_group; + if (wlr_keyboard_group_add_keyboard(wlr_group, keyboard)) { + wlr_log(WLR_DEBUG, "Added new keyboard to existing group"); + return; + } } } @@ -314,6 +347,7 @@ cg_keyboard_group_add(struct wlr_keyboard *keyboard, struct cg_seat *seat) return; } cg_group->seat = seat; + cg_group->is_virtual = virtual; cg_group->wlr_group = wlr_keyboard_group_create(); if (cg_group->wlr_group == NULL) { wlr_log(WLR_ERROR, "Failed to create wlr keyboard group."); @@ -346,7 +380,7 @@ cleanup: } static void -handle_new_keyboard(struct cg_seat *seat, struct wlr_keyboard *keyboard) +handle_new_keyboard(struct cg_seat *seat, struct wlr_keyboard *keyboard, bool virtual) { struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (!context) { @@ -367,11 +401,26 @@ handle_new_keyboard(struct cg_seat *seat, struct wlr_keyboard *keyboard) xkb_context_unref(context); wlr_keyboard_set_repeat_info(keyboard, 25, 600); - cg_keyboard_group_add(keyboard, seat); + cg_keyboard_group_add(keyboard, seat, virtual); wlr_seat_set_keyboard(seat->seat, keyboard); } +static void +handle_virtual_keyboard(struct wl_listener *listener, void *data) +{ + struct cg_server *server = wl_container_of(listener, server, new_virtual_keyboard); + struct cg_seat *seat = server->seat; + struct wlr_virtual_keyboard_v1 *keyboard = data; + struct wlr_keyboard *wlr_keyboard = &keyboard->keyboard; + + /* TODO: If multiple seats are supported, check keyboard->seat + * to select the appropriate one */ + + handle_new_keyboard(seat, wlr_keyboard, true); + update_capabilities(seat); +} + static void handle_new_input(struct wl_listener *listener, void *data) { @@ -380,7 +429,7 @@ handle_new_input(struct wl_listener *listener, void *data) switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: - handle_new_keyboard(seat, wlr_keyboard_from_input_device(device)); + handle_new_keyboard(seat, wlr_keyboard_from_input_device(device), false); break; case WLR_INPUT_DEVICE_POINTER: handle_new_pointer(seat, wlr_pointer_from_input_device(device)); @@ -797,6 +846,9 @@ seat_create(struct cg_server *server, struct wlr_backend *backend) seat->new_input.notify = handle_new_input; wl_signal_add(&backend->events.new_input, &seat->new_input); + server->new_virtual_keyboard.notify = handle_virtual_keyboard; + server->new_virtual_pointer.notify = handle_virtual_pointer; + wl_list_init(&seat->drag_icons); seat->request_start_drag.notify = handle_request_start_drag; wl_signal_add(&seat->seat->events.request_start_drag, &seat->request_start_drag); diff --git a/seat.h b/seat.h index 7b5dabf..52cbee4 100644 --- a/seat.h +++ b/seat.h @@ -55,6 +55,7 @@ struct cg_keyboard_group { struct wl_listener key; struct wl_listener modifiers; struct wl_list link; // cg_seat::keyboard_groups + bool is_virtual; }; struct cg_pointer { diff --git a/server.h b/server.h index bb7f3c1..082a435 100644 --- a/server.h +++ b/server.h @@ -12,10 +12,6 @@ #include #endif -#include "output.h" -#include "seat.h" -#include "view.h" - enum cg_multi_output_mode { CAGE_MULTI_OUTPUT_MODE_EXTEND, CAGE_MULTI_OUTPUT_MODE_LAST, @@ -44,6 +40,9 @@ struct cg_server { struct wl_listener xdg_toplevel_decoration; struct wl_listener new_xdg_shell_surface; + + struct wl_listener new_virtual_keyboard; + struct wl_listener new_virtual_pointer; #if CAGE_HAS_XWAYLAND struct wl_listener new_xwayland_surface; #endif