backend/wayland: give wlr_keyboard ownership to wlr_wl_seat

This commit is contained in:
Simon Zeni 2022-03-03 13:23:08 -05:00 committed by Kirill Primak
parent 64fe6ab300
commit f9b6aa3079
3 changed files with 62 additions and 75 deletions

View file

@ -413,8 +413,8 @@ static bool backend_start(struct wlr_backend *backend) {
struct wlr_wl_seat *seat;
wl_list_for_each(seat, &wl->seats, link) {
if (seat->keyboard) {
create_wl_keyboard(seat);
if (seat->wl_keyboard) {
init_seat_keyboard(seat);
}
if (wl->tablet_manager) {

View file

@ -26,9 +26,6 @@
#include "util/time.h"
static const struct wlr_pointer_impl pointer_impl;
static const struct wlr_keyboard_impl keyboard_impl = {
.name = "wl-keyboard",
};
static const struct wlr_touch_impl touch_impl;
static struct wlr_wl_pointer *output_get_pointer(
@ -223,31 +220,27 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard,
static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard,
uint32_t serial, struct wl_surface *surface, struct wl_array *keys) {
struct wlr_input_device *dev = data;
uint32_t time = get_current_time_msec();
struct wlr_keyboard *keyboard = data;
uint32_t *keycode_ptr;
wl_array_for_each(keycode_ptr, keys) {
struct wlr_event_keyboard_key event = {
.keycode = *keycode_ptr,
.state = WL_KEYBOARD_KEY_STATE_PRESSED,
.time_msec = time,
.time_msec = get_current_time_msec(),
.update_state = false,
};
wlr_keyboard_notify_key(dev->keyboard, &event);
wlr_keyboard_notify_key(keyboard, &event);
}
}
static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard,
uint32_t serial, struct wl_surface *surface) {
struct wlr_input_device *dev = data;
struct wlr_keyboard *keyboard = data;
uint32_t time = get_current_time_msec();
size_t num_keycodes = dev->keyboard->num_keycodes;
size_t num_keycodes = keyboard->num_keycodes;
uint32_t pressed[num_keycodes + 1];
memcpy(pressed, dev->keyboard->keycodes,
memcpy(pressed, keyboard->keycodes,
num_keycodes * sizeof(uint32_t));
for (size_t i = 0; i < num_keycodes; ++i) {
@ -256,17 +249,16 @@ static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard,
struct wlr_event_keyboard_key event = {
.keycode = keycode,
.state = WL_KEYBOARD_KEY_STATE_RELEASED,
.time_msec = time,
.time_msec = get_current_time_msec(),
.update_state = false,
};
wlr_keyboard_notify_key(dev->keyboard, &event);
wlr_keyboard_notify_key(keyboard, &event);
}
}
static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,
uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
struct wlr_input_device *dev = data;
assert(dev && dev->keyboard);
struct wlr_keyboard *keyboard = data;
struct wlr_event_keyboard_key wlr_event = {
.keycode = key,
@ -274,15 +266,14 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,
.time_msec = time,
.update_state = false,
};
wlr_keyboard_notify_key(dev->keyboard, &wlr_event);
wlr_keyboard_notify_key(keyboard, &wlr_event);
}
static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard,
uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched,
uint32_t mods_locked, uint32_t group) {
struct wlr_input_device *dev = data;
assert(dev && dev->keyboard);
wlr_keyboard_notify_modifiers(dev->keyboard, mods_depressed, mods_latched,
struct wlr_keyboard *keyboard = data;
wlr_keyboard_notify_modifiers(keyboard, mods_depressed, mods_latched,
mods_locked, group);
}
@ -300,6 +291,24 @@ static const struct wl_keyboard_listener keyboard_listener = {
.repeat_info = keyboard_handle_repeat_info
};
static const struct wlr_keyboard_impl keyboard_impl = {
.name = "wl-keyboard",
};
void init_seat_keyboard(struct wlr_wl_seat *seat) {
assert(seat->wl_keyboard);
char name[128] = {0};
snprintf(name, sizeof(name), "wayland-keyboard-%s", seat->name);
wlr_keyboard_init(&seat->wlr_keyboard, &keyboard_impl, name);
wl_keyboard_add_listener(seat->wl_keyboard, &keyboard_listener,
&seat->wlr_keyboard);
wlr_signal_emit_safe(&seat->backend->backend.events.new_input,
&seat->wlr_keyboard.base);
}
static void touch_coordinates_to_absolute(struct wlr_wl_input_device *device,
wl_fixed_t x, wl_fixed_t y, double *sx, double *sy) {
// TODO: each output needs its own touch
@ -420,10 +429,11 @@ void destroy_wl_seats(struct wlr_wl_backend *wl) {
if (seat->pointer) {
wl_pointer_destroy(seat->pointer);
}
if (seat->keyboard && !wl->started) {
// early termination will not be handled by input_device_destroy
wl_keyboard_destroy(seat->keyboard);
if (seat->wl_keyboard) {
wl_keyboard_release(seat->wl_keyboard);
wlr_keyboard_finish(&seat->wlr_keyboard);
}
free(seat->name);
assert(seat->wl_seat);
wl_seat_destroy(seat->wl_seat);
@ -474,8 +484,9 @@ struct wlr_wl_input_device *create_wl_input_device(
switch (type) {
case WLR_INPUT_DEVICE_KEYBOARD:
type_name = "keyboard";
break;
wlr_log(WLR_ERROR, "can't create keyboard wlr_wl_input_device");
free(dev);
return NULL;
case WLR_INPUT_DEVICE_POINTER:
type_name = "pointer";
break;
@ -550,8 +561,7 @@ void destroy_wl_input_device(struct wlr_wl_input_device *dev) {
struct wlr_input_device *wlr_dev = &dev->wlr_input_device;
switch (wlr_dev->type) {
case WLR_INPUT_DEVICE_KEYBOARD:
wlr_keyboard_finish(wlr_dev->keyboard);
free(wlr_dev->keyboard);
wlr_log(WLR_ERROR, "wlr_wl_input_device has no keyboard");
break;
case WLR_INPUT_DEVICE_POINTER:
/* Owned by wlr_wl_pointer */
@ -814,29 +824,6 @@ void create_wl_pointer(struct wlr_wl_seat *seat, struct wlr_wl_output *output) {
wlr_signal_emit_safe(&backend->backend.events.new_input, wlr_dev);
}
void create_wl_keyboard(struct wlr_wl_seat *seat) {
assert(seat->keyboard);
struct wl_keyboard *wl_keyboard = seat->keyboard;
struct wlr_wl_input_device *dev =
create_wl_input_device(seat, WLR_INPUT_DEVICE_KEYBOARD);
if (!dev) {
return;
}
struct wlr_input_device *wlr_dev = &dev->wlr_input_device;
wlr_dev->keyboard = calloc(1, sizeof(*wlr_dev->keyboard));
if (!wlr_dev->keyboard) {
wlr_log_errno(WLR_ERROR, "Allocation failed");
destroy_wl_input_device(dev);
return;
}
wlr_keyboard_init(wlr_dev->keyboard, &keyboard_impl, wlr_dev->name);
wl_keyboard_add_listener(wl_keyboard, &keyboard_listener, wlr_dev);
wlr_signal_emit_safe(&seat->backend->backend.events.new_input, wlr_dev);
}
void create_wl_touch(struct wlr_wl_seat *seat) {
assert(seat->touch);
struct wl_touch *wl_touch = seat->touch;
@ -903,31 +890,23 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
seat->pointer = NULL;
}
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && seat->keyboard == NULL) {
wlr_log(WLR_DEBUG, "seat %p offered keyboard", (void *)wl_seat);
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && seat->wl_keyboard == NULL) {
wlr_log(WLR_DEBUG, "seat '%s' offering keyboard", seat->name);
struct wl_keyboard *wl_keyboard = wl_seat_get_keyboard(wl_seat);
seat->keyboard = wl_keyboard;
seat->wl_keyboard = wl_keyboard;
if (backend->started) {
create_wl_keyboard(seat);
init_seat_keyboard(seat);
}
}
if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && seat->keyboard != NULL) {
wlr_log(WLR_DEBUG, "seat %p dropped keyboard", (void *)wl_seat);
if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && seat->wl_keyboard != NULL) {
wlr_log(WLR_DEBUG, "seat '%s' dropping keyboard", seat->name);
struct wlr_wl_input_device *device, *tmp;
wl_list_for_each_safe(device, tmp, &backend->devices, link) {
if (device->wlr_input_device.type != WLR_INPUT_DEVICE_KEYBOARD) {
continue;
}
wl_keyboard_release(seat->wl_keyboard);
wlr_keyboard_finish(&seat->wlr_keyboard);
if (device->seat != seat) {
continue;
}
destroy_wl_input_device(device);
}
assert(seat->keyboard == NULL); // free'ed by input_device_destroy
seat->wl_keyboard = NULL;
}
if ((caps & WL_SEAT_CAPABILITY_TOUCH) && seat->touch == NULL) {

View file

@ -8,6 +8,7 @@
#include <wlr/backend/wayland.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_pointer.h>
#include <wlr/render/drm_format_set.h>
@ -112,23 +113,29 @@ struct wlr_wl_pointer {
};
struct wlr_wl_seat {
char *name;
struct wl_seat *wl_seat;
struct wl_list link; // wlr_wl_backend.seats
char *name;
struct wlr_wl_backend *backend;
struct wl_keyboard *wl_keyboard;
struct wlr_keyboard wlr_keyboard;
struct wl_touch *touch;
struct wl_pointer *pointer;
struct wl_keyboard *keyboard;
struct wlr_wl_backend *backend;
struct wlr_wl_pointer *active_pointer;
struct wl_list link; // wlr_wl_backend.seats
};
struct wlr_wl_backend *get_wl_backend_from_backend(struct wlr_backend *backend);
void update_wl_output_cursor(struct wlr_wl_output *output);
struct wlr_wl_pointer *pointer_get_wl(struct wlr_pointer *wlr_pointer);
void init_seat_keyboard(struct wlr_wl_seat *seat);
void create_wl_pointer(struct wlr_wl_seat *seat, struct wlr_wl_output *output);
void create_wl_keyboard(struct wlr_wl_seat *seat);
void create_wl_touch(struct wlr_wl_seat *seat);
struct wlr_wl_input_device *create_wl_input_device(
struct wlr_wl_seat *seat, enum wlr_input_device_type type);
@ -138,6 +145,7 @@ void destroy_wl_input_device(struct wlr_wl_input_device *dev);
void destroy_wl_buffer(struct wlr_wl_buffer *buffer);
extern const struct wl_seat_listener seat_listener;
extern const struct wlr_tablet_pad_impl tablet_pad_impl;
extern const struct wlr_tablet_impl tablet_impl;