#include <libds/swapchain.h>
#include <libds/compositor.h>
#include <libds/xdg_shell.h>
+#include <libds/input_device.h>
+#include <libds/keyboard.h>
#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;
struct wl_list views;
struct wl_list outputs;
+ struct wl_listener new_input;
struct wl_listener new_xdg_surface;
};
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);
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);
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;
+ }
+}