#include <time.h>
#include "libds/log.h"
+#include "keyboard.h"
#include "seat_private.h"
static const struct ds_keyboard_grab_interface default_keyboard_grab_iface;
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,
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);
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
}
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)
{
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);
+}