From 3bc198b97377e0770b88f81b3e9b29d7f1ce1ef2 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 20 Apr 2022 11:29:17 +0900 Subject: [PATCH] examples/tinyds: Handle ds_keyboard tinyds now handles ds_keyboard, and it may be terminated by pressing Alt + Ctrl + Shift + BackSapce. Change-Id: I6333e2b239f3d7b28e62ca3997180e1428c9c4f7 --- src/examples/tinyds.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/src/examples/tinyds.c b/src/examples/tinyds.c index a4c1042..cfa55a6 100644 --- a/src/examples/tinyds.c +++ b/src/examples/tinyds.c @@ -17,12 +17,25 @@ #include #include #include +#include +#include #define TINYDS_UNUSED __attribute__((unused)) #define OUTPUT_WIDTH 1280 #define OUTPUT_HEIGHT 720 +struct tinyds_server; + +struct tinyds_keyboard +{ + struct ds_input_device *dev; + struct tinyds_server *server; + + struct wl_listener destroy; + struct wl_listener key; +}; + struct tinyds_output { struct tinyds_server *server; @@ -54,6 +67,7 @@ struct tinyds_server struct wl_list views; struct wl_list outputs; + struct wl_listener new_input; struct wl_listener new_xdg_surface; }; @@ -77,6 +91,7 @@ struct tinyds_server _tinyds; static bool init_server(struct tinyds_server *server, struct wl_display *display); static void fini_server(struct tinyds_server *server); +static void server_handle_new_input(struct wl_listener *listener, void *data); static bool init_output(struct tinyds_output *output, struct tinyds_server *server, int width, int height); static void fini_output(struct tinyds_output *output); @@ -240,6 +255,9 @@ init_server(struct tinyds_server *server, struct wl_display *display) if (!server->backend) return false; + server->new_input.notify = server_handle_new_input; + ds_backend_add_new_input_listener(server->backend, &server->new_input); + server->compositor = ds_compositor_create(display); if (!server->compositor) { ds_backend_destroy(server->backend); @@ -439,3 +457,103 @@ view_send_frame_done(struct tinyds_view *view) ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface), &now); } + +static void +keyboard_handle_device_destroy(struct wl_listener *listener, void *data) +{ + struct tinyds_keyboard *kbd; + + kbd = wl_container_of(listener, kbd, destroy); + + ds_inf("Keyboard(%p) destroyed", kbd); + + wl_list_remove(&kbd->destroy.link); + wl_list_remove(&kbd->key.link); + + free(kbd); +} + +static bool +server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym) +{ + switch (sym) { + case XKB_KEY_BackSpace: + wl_display_terminate(server->display); + break; + default: + return false; + } + + return true; +} + +static void +keyboard_handle_key(struct wl_listener *listener, void *data) +{ + struct tinyds_keyboard *kbd; + struct ds_event_keyboard_key *event = data; + struct ds_keyboard *ds_keyboard; + struct xkb_state *xkb_state; + const xkb_keysym_t *syms; + uint32_t modifiers; + int nsyms; + + kbd = wl_container_of(listener, kbd, key); + + ds_keyboard = ds_input_device_get_keyboard(kbd->dev); + + modifiers = ds_keyboard_get_modifiers(ds_keyboard); + if ((modifiers & DS_MODIFIER_CTRL) && + (modifiers & DS_MODIFIER_ALT) && + (modifiers & DS_MODIFIER_SHIFT) && + event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { + xkb_state = ds_keyboard_get_xkb_state(ds_keyboard); + if (xkb_state) { + nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8, + &syms); + for (int i = 0; i < nsyms; i++) { + server_handle_keybinding(kbd->server, syms[i]); + } + } + } +} + +static void +server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev) +{ + struct tinyds_keyboard *kbd; + + kbd = calloc(1, sizeof *kbd); + assert(kbd); + + kbd->dev = dev; + kbd->server = server; + + kbd->destroy.notify = keyboard_handle_device_destroy; + ds_input_device_add_destroy_listener(dev, &kbd->destroy); + + kbd->key.notify = keyboard_handle_key; + ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key); + + ds_inf("Keyboard(%p) added", kbd); +} + +static void +server_handle_new_input(struct wl_listener *listener, void *data) +{ + struct tinyds_server *server; + struct ds_input_device *dev = data; + enum ds_input_device_type dev_type; + + server = wl_container_of(listener, server, new_input); + + dev_type = ds_input_device_get_type(dev); + switch (dev_type) { + case DS_INPUT_DEVICE_KEYBOARD: + server_add_keyboard(server, dev); + break; + default: + ds_err("Unknown type(%d) of ds_input_device", dev_type); + break; + } +} -- 2.7.4