--- /dev/null
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <drm_fourcc.h>
+#include <libds/log.h>
+#include <libds/backend/wayland.h>
+#include <libds/input_device.h>
+#include <libds/pointer.h>
+#include <libds/keyboard.h>
+#include <libds/allocator/shm.h>
+#include <libds/swapchain.h>
+
+#include "pixman-helper.h"
+
+#define WIDTH 700
+#define HEIGHT 400
+
+struct pointer_device {
+ struct ds_pointer *ds_pointer;
+
+ struct wl_listener destroy;
+ struct wl_listener motion_absolute;
+ struct wl_listener button;
+ struct wl_listener frame;
+};
+
+struct server;
+
+struct keyboard_device {
+ struct server *server;
+ struct ds_keyboard *ds_keyboard;
+
+ struct wl_listener destroy;
+ struct wl_listener modifiers;
+ struct wl_listener key;
+};
+
+struct output
+{
+ struct server *server;
+
+ struct ds_output *ds_output;
+ struct ds_allocator *allocator;
+ struct ds_swapchain *swapchain;
+
+ struct ds_buffer *front_buffer;
+
+ struct wl_listener destroy;
+};
+
+struct server
+{
+ struct wl_display *display;
+
+ struct output output;
+
+ struct ds_backend *backend;
+
+ struct wl_listener backend_destroy;
+ struct wl_listener new_input;
+};
+
+struct server _server;
+
+static struct ds_backend *create_backend_auto(struct wl_display *display);
+static void handle_backend_destroy(struct wl_listener *listener, void *data);
+static void handle_new_input(struct wl_listener *listener, void *data);
+static void output_init(struct output *output, struct server *sever);
+static void output_draw(struct output *output);
+
+int
+main(void)
+{
+ struct server *server = &_server;
+
+ ds_log_init(DS_DBG, NULL);
+
+ server->display = wl_display_create();
+ assert(server->display);
+
+ server->backend = create_backend_auto(server->display);
+ assert(server->backend);
+
+ server->backend_destroy.notify = handle_backend_destroy;
+ ds_backend_add_destroy_listener(server->backend, &server->backend_destroy);
+
+ server->new_input.notify = handle_new_input;
+ ds_backend_add_new_input_listener(server->backend, &server->new_input);
+
+ output_init(&server->output, server);
+
+ ds_backend_start(server->backend);
+
+ output_draw(&server->output);
+
+ wl_display_run(server->display);
+
+ wl_display_destroy(server->display);
+
+ return 0;
+}
+
+static struct ds_backend *
+create_backend_auto(struct wl_display *display)
+{
+ struct ds_backend *backend = NULL;
+ char name[512];
+ int i;
+
+ for (i = 0; i < 5; i++) {
+ snprintf(name, sizeof name, "wayland-%d", i);
+ backend = ds_wl_backend_create(display, name);
+ if (backend)
+ break;
+ }
+
+ return backend;
+}
+
+static void
+handle_backend_destroy(struct wl_listener *listener, void *data)
+{
+ struct server *server;
+
+ server = wl_container_of(listener, server, backend_destroy);
+
+ wl_list_remove(&server->backend_destroy.link);
+ wl_list_remove(&server->new_input.link);
+}
+
+static char *
+device_type_to_string(enum ds_input_device_type type)
+{
+ switch (type) {
+ case DS_INPUT_DEVICE_POINTER:
+ return "pointer";
+ break;
+ case DS_INPUT_DEVICE_KEYBOARD:
+ return "keyboard";
+ break;
+ case DS_INPUT_DEVICE_TOUCH:
+ return "touch";
+ break;
+ default:
+ return "Unknown";
+ }
+}
+
+static void
+pointer_handle_device_destroy(struct wl_listener *listener, void *data)
+{
+ struct pointer_device *pointer;
+
+ pointer = wl_container_of(listener, pointer, destroy);
+
+ wl_list_remove(&pointer->destroy.link);
+ wl_list_remove(&pointer->motion_absolute.link);
+ wl_list_remove(&pointer->button.link);
+ wl_list_remove(&pointer->frame.link);
+
+ free(pointer);
+}
+
+static void
+pointer_handle_motion_absolute(struct wl_listener *listener, void *data)
+{
+ struct ds_event_pointer_motion_absolute *event = data;
+
+ ds_inf("Pointer device(%p): motion absolute (%f, %f) time(%d ms)",
+ event->device, event->x, event->y, event->time_msec);
+}
+
+static void
+pointer_handle_button(struct wl_listener *listener, void *data)
+{
+ struct ds_event_pointer_button *event = data;
+
+ ds_inf("Pointer Device(%p): button(%d) state(%d) time(%d ms)",
+ event->device, event->button, event->state, event->time_msec);
+}
+
+static void
+pointer_handle_frame(struct wl_listener *listener, void *data)
+{
+ ds_inf("Pointer device(%p): frame", data);
+}
+
+static void
+add_pointer(struct ds_input_device *dev)
+{
+ struct pointer_device *pointer;
+
+ pointer = calloc(1, sizeof *pointer);
+ if (!pointer)
+ return;
+
+ pointer->ds_pointer = ds_input_device_get_pointer(dev);
+
+ pointer->destroy.notify = pointer_handle_device_destroy;
+ ds_input_device_add_destroy_listener(dev, &pointer->destroy);
+
+ pointer->motion_absolute.notify = pointer_handle_motion_absolute;
+ ds_pointer_add_motion_absolute_listener(pointer->ds_pointer,
+ &pointer->motion_absolute);
+
+ pointer->button.notify = pointer_handle_button;
+ ds_pointer_add_button_listener(pointer->ds_pointer,
+ &pointer->button);
+
+ pointer->frame.notify = pointer_handle_frame;
+ ds_pointer_add_frame_listener(pointer->ds_pointer,
+ &pointer->frame);
+}
+
+static void
+keyboard_handle_device_destroy(struct wl_listener *listener, void *data)
+{
+ struct keyboard_device *keyboard;
+
+ keyboard = wl_container_of(listener, keyboard, destroy);
+
+ wl_list_remove(&keyboard->destroy.link);
+ wl_list_remove(&keyboard->modifiers.link);
+ wl_list_remove(&keyboard->key.link);
+
+ free(keyboard);
+}
+
+static void
+keyboard_handle_modifiers(struct wl_listener *listener, void *data)
+{
+ struct keyboard_device *keyboard;
+ struct ds_keyboard *ds_keyboard = data;
+
+ keyboard = wl_container_of(listener, keyboard, destroy);
+
+ ds_inf("Keyboard(%p) event modifiers", ds_keyboard);
+}
+
+static void
+keyboard_handle_key(struct wl_listener *listener, void *data)
+{
+ struct ds_event_keyboard_key *event = data;
+ struct keyboard_device *keyboard;
+ struct xkb_state *xkb_state;
+ const xkb_keysym_t *syms;
+ int nsyms = 0;
+
+ keyboard = wl_container_of(listener, keyboard, key);
+
+ ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), "
+ "update_state(%d)", keyboard->ds_keyboard,
+ event->keycode, event->state, event->time_msec,
+ event->update_state);
+
+ xkb_state = ds_keyboard_get_xkb_state(keyboard->ds_keyboard);
+ if (!xkb_state)
+ return;
+
+ nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8, &syms);
+
+ for (int i = 0; i < nsyms; i++) {
+ if (syms[i] == XKB_KEY_Escape)
+ wl_display_terminate(keyboard->server->display);
+ }
+}
+
+static void
+add_keyboard(struct server *server, struct ds_input_device *dev)
+{
+ struct keyboard_device *keyboard;
+
+ keyboard = calloc(1, sizeof *keyboard);
+ if (!keyboard)
+ return;
+
+ keyboard->server = server;
+ keyboard->ds_keyboard = ds_input_device_get_keyboard(dev);
+
+ ds_inf("Keyboard(%p) added", keyboard->ds_keyboard);
+
+ keyboard->destroy.notify = keyboard_handle_device_destroy;
+ ds_input_device_add_destroy_listener(dev, &keyboard->destroy);
+
+ keyboard->modifiers.notify = keyboard_handle_modifiers;
+ ds_keyboard_add_modifiers_listener(keyboard->ds_keyboard,
+ &keyboard->modifiers);
+
+ keyboard->key.notify = keyboard_handle_key;
+ ds_keyboard_add_key_listener(keyboard->ds_keyboard,
+ &keyboard->key);
+}
+
+static void
+handle_new_input(struct wl_listener *listener, void *data)
+{
+ struct server *server;
+ struct ds_input_device *dev = data;
+ enum ds_input_device_type type;
+
+ type = ds_input_device_get_type(dev);
+
+ ds_inf("New device(%p) type(%s)", dev, device_type_to_string(type));
+
+ if (type == DS_INPUT_DEVICE_POINTER)
+ add_pointer(dev);
+ else if (type == DS_INPUT_DEVICE_KEYBOARD) {
+ server = wl_container_of(listener, server, new_input);
+ add_keyboard(server, dev);
+ }
+}
+
+static void
+output_handle_destroy(struct wl_listener *listener, void *data)
+{
+ struct output *output;
+
+ output = wl_container_of(listener, output, destroy);
+
+ wl_list_remove(&output->destroy.link);
+
+ ds_swapchain_destroy(output->swapchain);
+ ds_allocator_destroy(output->allocator);
+}
+
+static void
+output_init(struct output *output, struct server *server)
+{
+ output->server = server;
+
+ output->ds_output = ds_wl_backend_create_output(server->backend);
+ assert(output->ds_output);
+
+ output->destroy.notify = output_handle_destroy;
+ ds_output_add_destroy_listener(output->ds_output, &output->destroy);
+
+ output->allocator = ds_shm_allocator_create();
+ assert(output->allocator);
+
+ output->swapchain = ds_swapchain_create(output->allocator,
+ WIDTH, HEIGHT, DRM_FORMAT_XRGB8888);
+ assert(output->swapchain);
+}
+
+static void
+output_draw(struct output *output)
+{
+ struct ds_buffer *buffer;
+ pixman_image_t *img;
+
+ ds_dbg("Redraw output");
+
+ buffer = ds_swapchain_acquire(output->swapchain, NULL);
+ assert(buffer);
+
+ img = pixman_image_from_buffer(buffer, DS_BUFFER_DATA_PTR_ACCESS_WRITE);
+ assert(img);
+
+ pixman_image_fill_color(img, 80, 80, 80);
+
+ pixman_image_unref(img);
+
+ ds_output_attach_buffer(output->ds_output, buffer);
+ ds_output_commit(output->ds_output);
+
+ if (output->front_buffer)
+ ds_buffer_unlock(output->front_buffer);
+
+ output->front_buffer = buffer;
+}
+++ /dev/null
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <drm_fourcc.h>
-#include <libds/log.h>
-#include <libds/backend/wayland.h>
-#include <libds/input_device.h>
-#include <libds/pointer.h>
-#include <libds/allocator/shm.h>
-#include <libds/swapchain.h>
-
-#include "pixman-helper.h"
-
-#define WIDTH 700
-#define HEIGHT 400
-
-struct pointer_device {
- struct ds_pointer *ds_pointer;
-
- struct wl_listener destroy;
- struct wl_listener motion_absolute;
- struct wl_listener button;
- struct wl_listener frame;
-};
-
-struct output
-{
- struct server *server;
-
- struct ds_output *ds_output;
- struct ds_allocator *allocator;
- struct ds_swapchain *swapchain;
-
- struct ds_buffer *front_buffer;
-
- struct wl_listener destroy;
-};
-
-struct server
-{
- struct wl_display *display;
-
- struct output output;
-
- struct ds_backend *backend;
-
- struct wl_listener backend_destroy;
- struct wl_listener new_input;
-};
-
-struct server _server;
-
-static struct ds_backend *create_backend_auto(struct wl_display *display);
-static void handle_backend_destroy(struct wl_listener *listener, void *data);
-static void handle_new_input(struct wl_listener *listener, void *data);
-static void output_init(struct output *output, struct server *sever);
-static void output_draw(struct output *output);
-
-int
-main(void)
-{
- struct server *server = &_server;
-
- ds_log_init(DS_DBG, NULL);
-
- server->display = wl_display_create();
- assert(server->display);
-
- server->backend = create_backend_auto(server->display);
- assert(server->backend);
-
- server->backend_destroy.notify = handle_backend_destroy;
- ds_backend_add_destroy_listener(server->backend, &server->backend_destroy);
-
- server->new_input.notify = handle_new_input;
- ds_backend_add_new_input_listener(server->backend, &server->new_input);
-
- output_init(&server->output, server);
-
- ds_backend_start(server->backend);
-
- output_draw(&server->output);
-
- wl_display_run(server->display);
-
- wl_display_destroy(server->display);
-
- return 0;
-}
-
-static struct ds_backend *
-create_backend_auto(struct wl_display *display)
-{
- struct ds_backend *backend = NULL;
- char name[512];
- int i;
-
- for (i = 0; i < 5; i++) {
- snprintf(name, sizeof name, "wayland-%d", i);
- backend = ds_wl_backend_create(display, name);
- if (backend)
- break;
- }
-
- return backend;
-}
-
-static void
-handle_backend_destroy(struct wl_listener *listener, void *data)
-{
- struct server *server;
-
- server = wl_container_of(listener, server, backend_destroy);
-
- wl_list_remove(&server->backend_destroy.link);
- wl_list_remove(&server->new_input.link);
-}
-
-static char *
-device_type_to_string(enum ds_input_device_type type)
-{
- switch (type) {
- case DS_INPUT_DEVICE_POINTER:
- return "pointer";
- break;
- case DS_INPUT_DEVICE_KEYBOARD:
- return "keyboard";
- break;
- case DS_INPUT_DEVICE_TOUCH:
- return "touch";
- break;
- default:
- return "Unknown";
- }
-}
-
-static void
-pointer_handle_device_destroy(struct wl_listener *listener, void *data)
-{
- struct pointer_device *pointer;
-
- pointer = wl_container_of(listener, pointer, destroy);
-
- wl_list_remove(&pointer->destroy.link);
- wl_list_remove(&pointer->motion_absolute.link);
- wl_list_remove(&pointer->button.link);
- wl_list_remove(&pointer->frame.link);
-
- free(pointer);
-}
-
-static void
-pointer_handle_motion_absolute(struct wl_listener *listener, void *data)
-{
- struct ds_event_pointer_motion_absolute *event = data;
-
- ds_inf("Pointer device(%p): motion absolute (%f, %f) time(%d ms)",
- event->device, event->x, event->y, event->time_msec);
-}
-
-static void
-pointer_handle_button(struct wl_listener *listener, void *data)
-{
- struct ds_event_pointer_button *event = data;
-
- ds_inf("Pointer Device(%p): button(%d) state(%d) time(%d ms)",
- event->device, event->button, event->state, event->time_msec);
-}
-
-static void
-pointer_handle_frame(struct wl_listener *listener, void *data)
-{
- ds_inf("Pointer device(%p): frame", data);
-}
-
-static void
-add_pointer(struct ds_input_device *dev)
-{
- struct pointer_device *pointer;
-
- pointer = calloc(1, sizeof *pointer);
- if (!pointer)
- return;
-
- pointer->ds_pointer = ds_input_device_get_pointer(dev);
-
- pointer->destroy.notify = pointer_handle_device_destroy;
- ds_input_device_add_destroy_listener(dev, &pointer->destroy);
-
- pointer->motion_absolute.notify = pointer_handle_motion_absolute;
- ds_pointer_add_motion_absolute_listener(pointer->ds_pointer,
- &pointer->motion_absolute);
-
- pointer->button.notify = pointer_handle_button;
- ds_pointer_add_button_listener(pointer->ds_pointer,
- &pointer->button);
-
- pointer->frame.notify = pointer_handle_frame;
- ds_pointer_add_frame_listener(pointer->ds_pointer,
- &pointer->frame);
-}
-
-static void
-handle_new_input(struct wl_listener *listener, void *data)
-{
- struct ds_input_device *dev = data;
- enum ds_input_device_type type;
-
- type = ds_input_device_get_type(dev);
-
- if (type != DS_INPUT_DEVICE_POINTER)
- return;
-
- ds_inf("New pointer device(%p) type(%s)", dev,
- device_type_to_string(type));
-
- add_pointer(dev);
-}
-
-static void
-output_handle_destroy(struct wl_listener *listener, void *data)
-{
- struct output *output;
-
- output = wl_container_of(listener, output, destroy);
-
- wl_list_remove(&output->destroy.link);
-
- ds_swapchain_destroy(output->swapchain);
- ds_allocator_destroy(output->allocator);
-}
-
-static void
-output_init(struct output *output, struct server *server)
-{
- output->server = server;
-
- output->ds_output = ds_wl_backend_create_output(server->backend);
- assert(output->ds_output);
-
- output->destroy.notify = output_handle_destroy;
- ds_output_add_destroy_listener(output->ds_output, &output->destroy);
-
- output->allocator = ds_shm_allocator_create();
- assert(output->allocator);
-
- output->swapchain = ds_swapchain_create(output->allocator,
- WIDTH, HEIGHT, DRM_FORMAT_XRGB8888);
- assert(output->swapchain);
-}
-
-static void
-output_draw(struct output *output)
-{
- struct ds_buffer *buffer;
- pixman_image_t *img;
-
- ds_dbg("Redraw output");
-
- buffer = ds_swapchain_acquire(output->swapchain, NULL);
- assert(buffer);
-
- img = pixman_image_from_buffer(buffer, DS_BUFFER_DATA_PTR_ACCESS_WRITE);
- assert(img);
-
- pixman_image_fill_color(img, 80, 80, 80);
-
- pixman_image_unref(img);
-
- ds_output_attach_buffer(output->ds_output, buffer);
- ds_output_commit(output->ds_output);
-
- if (output->front_buffer)
- ds_buffer_unlock(output->front_buffer);
-
- output->front_buffer = buffer;
-}