From: Seunghun Lee Date: Wed, 29 Jun 2022 07:19:52 +0000 (+0900) Subject: seat: Add ds_seat_set_keyboard() X-Git-Tag: accepted/tizen/unified/20220718.140337~13 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F07%2F278107%2F1;p=platform%2Fcore%2Fuifw%2Flibds.git seat: Add ds_seat_set_keyboard() The ds_seat_set_keyboard() enables a seat to refer to a ds_keyboard, so that the seat reads keymap and repeat info from ds_keyboard and then sends them to the wayland clients. Change-Id: Ic20fa041f391d0f8c73c8a6818505525701e3929 --- diff --git a/include/libds/seat.h b/include/libds/seat.h index e55fc4c..928861d 100644 --- a/include/libds/seat.h +++ b/include/libds/seat.h @@ -95,6 +95,8 @@ void ds_seat_set_capabilities(struct ds_seat *seat, void ds_seat_set_name(struct ds_seat *seat, const char *name); +void ds_seat_set_keyboard(struct ds_seat *seat, struct ds_input_device *device); + void ds_seat_add_destroy_listener(struct ds_seat *seat, struct wl_listener *listener); diff --git a/src/keyboard.c b/src/keyboard.c index d122e81..72467ee 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -246,6 +246,10 @@ ds_keyboard_init(struct ds_keyboard *keyboard, keyboard->iface = iface; keyboard->keymap_fd = -1; + // Sane defaults + keyboard->repeat_info.rate = 25; + keyboard->repeat_info.delay = 600; + wl_signal_init(&keyboard->events.destroy); wl_signal_init(&keyboard->events.key); wl_signal_init(&keyboard->events.modifiers); @@ -262,6 +266,33 @@ ds_keyboard_destroy(struct ds_keyboard *keyboard) free(keyboard); } +bool +ds_keyboard_get_keymap_fd(struct ds_keyboard *keyboard, int *keymap_fd, + size_t *keymap_size) +{ + if (keyboard->keymap_fd < 0) + return false; + + if (keymap_fd) + *keymap_fd = keyboard->keymap_fd; + + if (keymap_size) + *keymap_size = keyboard->keymap_size; + + return true; +} + +void +ds_keyboard_get_repeat_info(struct ds_keyboard *keyboard, int32_t *rate, + int32_t *delay) +{ + if (rate) + *rate = keyboard->repeat_info.rate; + + if (delay) + *delay = keyboard->repeat_info.delay; +} + static bool keyboard_modifier_update(struct ds_keyboard *keyboard) { diff --git a/src/keyboard.h b/src/keyboard.h new file mode 100644 index 0000000..193501d --- /dev/null +++ b/src/keyboard.h @@ -0,0 +1,12 @@ +#ifndef DS_KEYBOARD_H +#define DS_KEYBOARD_H + +#include "libds/keyboard.h" + +bool ds_keyboard_get_keymap_fd(struct ds_keyboard *keyboard, int *keymap_fd, + size_t *keymap_size); + +void ds_keyboard_get_repeat_info(struct ds_keyboard *keyboard, int32_t *rate, + int32_t *delay); + +#endif diff --git a/src/seat/seat_keyboard.c b/src/seat/seat_keyboard.c index b022163..4846711 100644 --- a/src/seat/seat_keyboard.c +++ b/src/seat/seat_keyboard.c @@ -4,6 +4,7 @@ #include #include "libds/log.h" +#include "keyboard.h" #include "seat_private.h" static const struct ds_keyboard_grab_interface default_keyboard_grab_iface; @@ -12,10 +13,47 @@ static const struct wl_keyboard_interface keyboard_impl; static void seat_client_send_keyboard_leave_raw(struct ds_seat_client *seat_client, struct ds_surface *surface); -static void -seat_keyboard_handle_surface_destroy(struct wl_listener *listener, +static void seat_client_send_keymap(struct ds_seat_client *seat_client, + struct ds_keyboard *ds_keyboard); +static void seat_client_send_repeat_info(struct ds_seat_client *seat_client, + struct ds_keyboard *ds_keyboard); +static void seat_keyboard_handle_surface_destroy(struct wl_listener *listener, void *data); static void keyboard_handle_resource_destroy(struct wl_resource *resource); +static void seat_keyboard_set_keyboard(struct ds_seat_keyboard *keyboard, + struct ds_input_device *device); +static void seat_keyboard_unset_keyboard(struct ds_seat_keyboard *keyboard); +static void seat_keyboard_handle_keyboard_destroy(struct wl_listener *listener, + void *data); +static void seat_keyboard_handle_keymap(struct wl_listener *listener, + void *data); +static void seat_keyboard_handle_repeat_info(struct wl_listener *listener, + void *data); + +WL_EXPORT void +ds_seat_set_keyboard(struct ds_seat *seat, struct ds_input_device *device) +{ + struct ds_seat_keyboard *keyboard = &seat->keyboard; + struct ds_keyboard *ds_keyboard = NULL; + + if (device) { + if (ds_input_device_get_type(device) != DS_INPUT_DEVICE_KEYBOARD) { + ds_err("Given device is not a keyboard"); + return; + } + + ds_keyboard = ds_input_device_get_keyboard(device); + } + + if (keyboard->ds_keyboard == ds_keyboard) + return; + + if (keyboard->ds_keyboard) + seat_keyboard_unset_keyboard(keyboard); + + if (ds_keyboard) + seat_keyboard_set_keyboard(keyboard, device); +} WL_EXPORT void ds_seat_keyboard_notify_enter(struct ds_seat *seat, @@ -293,6 +331,7 @@ seat_client_add_keyboard_resource(struct ds_seat_client *seat_client, uint32_t version, uint32_t id) { struct wl_resource *resource; + struct ds_keyboard *ds_keyboard; resource = wl_resource_create(seat_client->wl_client, &wl_keyboard_interface, version, id); @@ -310,6 +349,13 @@ seat_client_add_keyboard_resource(struct ds_seat_client *seat_client, wl_resource_set_user_data(resource, NULL); return; } + + ds_keyboard = seat_client->seat->keyboard.ds_keyboard; + if (!ds_keyboard) + return; + + seat_client_send_keymap(seat_client, ds_keyboard); + seat_client_send_repeat_info(seat_client, ds_keyboard); } void @@ -401,6 +447,43 @@ seat_client_send_keyboard_leave_raw(struct ds_seat_client *seat_client, } static void +seat_client_send_keymap(struct ds_seat_client *seat_client, + struct ds_keyboard *ds_keyboard) +{ + struct wl_resource *resource; + int fd; + size_t size; + + if (!ds_keyboard_get_keymap_fd(ds_keyboard, &fd, &size)) { + ds_err("Failed to get keymap fd from ds_keyboard(%p)", ds_keyboard); + return; + } + + wl_resource_for_each(resource, &seat_client->keyboards) { + wl_keyboard_send_keymap(resource, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, + fd, size); + } +} + +static void +seat_client_send_repeat_info(struct ds_seat_client *seat_client, + struct ds_keyboard *ds_keyboard) +{ + struct wl_resource *resource; + int32_t rate, delay; + + ds_keyboard_get_repeat_info(ds_keyboard, &rate, &delay); + + wl_resource_for_each(resource, &seat_client->keyboards) { + if (wl_resource_get_version(resource) < + WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) + continue; + + wl_keyboard_send_repeat_info(resource, rate, delay); + } +} + +static void seat_keyboard_handle_surface_destroy(struct wl_listener *listener, void *data) { @@ -412,3 +495,72 @@ seat_keyboard_handle_surface_destroy(struct wl_listener *listener, wl_list_init(&keyboard->surface_destroy.link); ds_seat_keyboard_clear_focus(keyboard->seat); } + +static void +seat_keyboard_set_keyboard(struct ds_seat_keyboard *keyboard, + struct ds_input_device *device) +{ + struct ds_seat_client *seat_client; + + keyboard->ds_keyboard = ds_input_device_get_keyboard(device); + + keyboard->keyboard_destroy.notify = seat_keyboard_handle_keyboard_destroy; + ds_input_device_add_destroy_listener(device, &keyboard->keyboard_destroy); + + keyboard->keymap.notify = seat_keyboard_handle_keymap; + ds_keyboard_add_keymap_listener(keyboard->ds_keyboard, &keyboard->keymap); + + keyboard->repeat_info.notify = seat_keyboard_handle_repeat_info; + ds_keyboard_add_repeat_info_listener(keyboard->ds_keyboard, + &keyboard->repeat_info); + + wl_list_for_each(seat_client, &keyboard->seat->clients, link) { + seat_client_send_keymap(seat_client, keyboard->ds_keyboard); + seat_client_send_repeat_info(seat_client, keyboard->ds_keyboard); + } +} + +static void +seat_keyboard_unset_keyboard(struct ds_seat_keyboard *keyboard) +{ + wl_list_remove(&keyboard->keyboard_destroy.link); + wl_list_remove(&keyboard->keymap.link); + wl_list_remove(&keyboard->repeat_info.link); + + keyboard->ds_keyboard = NULL; +} + +static void +seat_keyboard_handle_keyboard_destroy(struct wl_listener *listener, void *data) +{ + struct ds_seat_keyboard *keyboard; + + keyboard = wl_container_of(listener, keyboard, keyboard_destroy); + + seat_keyboard_unset_keyboard(keyboard); +} + +static void +seat_keyboard_handle_keymap(struct wl_listener *listener, void *data) +{ + struct ds_seat_keyboard *keyboard; + struct ds_seat_client *seat_client; + + keyboard = wl_container_of(listener, keyboard, keymap); + + wl_list_for_each(seat_client, &keyboard->seat->clients, link) + seat_client_send_keymap(seat_client, keyboard->ds_keyboard); +} + +static void +seat_keyboard_handle_repeat_info(struct wl_listener *listener, + void *data) +{ + struct ds_seat_keyboard *keyboard; + struct ds_seat_client *seat_client; + + keyboard = wl_container_of(listener, keyboard, repeat_info); + + wl_list_for_each(seat_client, &keyboard->seat->clients, link) + seat_client_send_repeat_info(seat_client, keyboard->ds_keyboard); +} diff --git a/src/seat/seat_private.h b/src/seat/seat_private.h index 7a566bb..eeaa6ba 100644 --- a/src/seat/seat_private.h +++ b/src/seat/seat_private.h @@ -57,11 +57,15 @@ struct ds_seat_pointer struct ds_seat_keyboard { struct ds_seat *seat; + struct ds_keyboard *ds_keyboard; struct ds_seat_client *focused_client; struct ds_surface *focused_surface; struct wl_listener surface_destroy; + struct wl_listener keyboard_destroy; + struct wl_listener keymap; + struct wl_listener repeat_info; struct ds_seat_keyboard_grab *grab; struct ds_seat_keyboard_grab *default_grab;