add struct ds_libinput_backend, ds_libinput_input_device, etc.
add an executable 'libinput-backend' to test libinput events
Change-Id: Ifbc5ab8e587fbbc0767a3070da6b7b548d990cac
--- /dev/null
+#ifndef LIBDS_BACKEND_LIBINPUT_H
+#define LIBDS_BACKEND_LIBINPUT_H
+
+#include <libds/backend.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ds_backend *
+ds_libinput_backend_create(struct wl_display *display);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
double x, y;
};
+struct ds_event_pointer_motion
+{
+ struct ds_input_device *device;
+ uint32_t time_msec;
+ double delta_x, delta_y;
+};
+
struct ds_event_pointer_button
{
struct ds_input_device *device;
BuildRequires: pkgconfig(pixman-1)
BuildRequires: pkgconfig(libdrm)
BuildRequires: pkgconfig(xkbcommon)
+BuildRequires: pkgconfig(libinput)
+BuildRequires: pkgconfig(libudev)
BuildRequires: pkgconfig(libtdm)
BuildRequires: pkgconfig(libtbm)
%{_bindir}/wl-backend
%{_bindir}/tinyds
%{_bindir}/input-device-test
+%{_bindir}/libinput-backend
%files tizen-devel
%manifest %{name}.manifest
--- /dev/null
+#include <assert.h>
+ #include <stdlib.h>
+
+#include <wayland-server.h>
+#include <libds/log.h>
+#include <libds/backend/libinput.h>
+#include <libds/input_device.h>
+#include <libds/pointer.h>
+#include <libds/keyboard.h>
+#include <libds/touch.h>
+
+#define UNUSED __attribute__((unused))
+
+struct keyboard_device
+{
+ struct server *server;
+ struct ds_keyboard *ds_keyboard;
+
+ struct wl_listener destroy;
+ struct wl_listener key;
+};
+
+struct pointer_device
+{
+ struct ds_pointer *ds_pointer;
+
+ struct wl_listener destroy;
+ struct wl_listener motion;
+ struct wl_listener button;
+};
+
+struct touch_device
+{
+ struct ds_touch *ds_touch;
+
+ struct wl_listener destroy;
+ struct wl_listener down;
+ struct wl_listener up;
+ struct wl_listener motion;
+};
+
+struct server
+{
+ struct wl_display *display;
+
+ 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);
+
+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);
+
+ ds_backend_start(server->backend);
+
+ 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;
+ backend = ds_libinput_backend_create(display);
+ if (!backend)
+ ds_err("Failed to create libinput backend");
+
+ 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
+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->key.link);
+
+ free(keyboard);
+}
+
+static void
+keyboard_handle_key(struct wl_listener *listener, void *data)
+{
+ struct ds_event_keyboard_key *event = data;
+ struct keyboard_device *keyboard;
+
+ 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);
+}
+
+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->key.notify = keyboard_handle_key;
+ ds_keyboard_add_key_listener(keyboard->ds_keyboard,
+ &keyboard->key);
+}
+
+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->button.link);
+ wl_list_remove(&pointer->motion.link);
+
+ free(pointer);
+}
+
+static void
+pointer_handle_motion(struct wl_listener *listener, void *data)
+{
+ struct ds_event_pointer_motion *event = data;
+ struct pointer_device *pointer;
+
+ pointer = wl_container_of(listener, pointer, motion);
+
+ ds_inf("Pointer Device(%p): motion delta_x,y(%f, %f) time(%d ms)",
+ pointer->ds_pointer, event->delta_x, event->delta_y,
+ event->time_msec);
+}
+
+static void
+pointer_handle_button(struct wl_listener *listener, void *data)
+{
+ struct ds_event_pointer_button *event = data;
+ struct pointer_device *pointer;
+
+ pointer = wl_container_of(listener, pointer, button);
+ ds_inf("Pointer Device(%p): button(%d) state(%d) time(%d ms)",
+ pointer->ds_pointer, event->button, event->state,
+ event->time_msec);
+}
+
+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);
+
+ ds_inf("Pointer(%p) added", pointer->ds_pointer);
+
+ pointer->destroy.notify = pointer_handle_device_destroy;
+ ds_input_device_add_destroy_listener(dev, &pointer->destroy);
+
+ pointer->motion.notify = pointer_handle_motion;
+ ds_pointer_add_motion_listener(pointer->ds_pointer,
+ &pointer->motion);
+
+ pointer->button.notify = pointer_handle_button;
+ ds_pointer_add_button_listener(pointer->ds_pointer,
+ &pointer->button);
+}
+
+static void
+touch_handle_device_destroy(struct wl_listener *listener, void *data)
+{
+ struct touch_device *touch;
+
+ touch = wl_container_of(listener, touch, destroy);
+
+ wl_list_remove(&touch->destroy.link);
+ wl_list_remove(&touch->down.link);
+ wl_list_remove(&touch->up.link);
+ wl_list_remove(&touch->motion.link);
+
+ free(touch);
+}
+
+static void
+touch_handle_down(struct wl_listener *listener, void *data)
+{
+ struct ds_event_touch_down *event = data;
+ struct touch_device *touch;
+
+ touch = wl_container_of(listener, touch, down);
+
+ ds_inf("Touch(%p) event down: id(%d) x(%f) y(%f) time_msec(%d)",
+ touch->ds_touch, event->id, event->x, event->y, event->time_msec);
+}
+
+static void
+touch_handle_up(struct wl_listener *listener, void *data)
+{
+ struct ds_event_touch_up *event = data;
+ struct touch_device *touch;
+
+ touch = wl_container_of(listener, touch, up);
+
+ ds_inf("Touch(%p) event up: id(%d) time_msec(%d)",
+ touch->ds_touch, event->id, event->time_msec);
+}
+
+static void
+touch_handle_motion(struct wl_listener *listener, void *data)
+{
+ struct ds_event_touch_motion *event = data;
+ struct touch_device *touch;
+
+ touch = wl_container_of(listener, touch, motion);
+
+ ds_inf("Touch(%p) event motion: id(%d) x(%f) y(%f) time_msec(%d)",
+ touch->ds_touch, event->id, event->x, event->y, event->time_msec);
+}
+
+static void
+add_touch(struct server *server, struct ds_input_device *dev)
+{
+ struct touch_device *touch;
+
+ touch = calloc(1, sizeof *touch);
+ if (!touch)
+ return;
+
+ touch->ds_touch = ds_input_device_get_touch(dev);
+
+ ds_inf("Touch(%p) added", touch->ds_touch);
+
+ touch->destroy.notify = touch_handle_device_destroy;
+ ds_input_device_add_destroy_listener(dev, &touch->destroy);
+
+ touch->down.notify = touch_handle_down;
+ ds_touch_add_down_listener(touch->ds_touch,
+ &touch->down);
+
+ touch->up.notify = touch_handle_up;
+ ds_touch_add_up_listener(touch->ds_touch,
+ &touch->up);
+
+ touch->motion.notify = touch_handle_motion;
+ ds_touch_add_motion_listener(touch->ds_touch,
+ &touch->motion);
+}
+
+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);
+ }
+ else if (type == DS_INPUT_DEVICE_TOUCH) {
+ server = wl_container_of(listener, server, new_input);
+ add_touch(server, dev);
+ }
+}
install_dir: libds_bindir,
install : true
)
+
+ executable('libinput-backend',
+ 'libinput-backend.c',
+ dependencies: common_deps,
+ install_dir: libds_bindir,
+ install : true
+ )
endif
--- /dev/null
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "libds/log.h"
+
+#include "backend.h"
+
+static const struct ds_backend_interface libinput_backend_interface;
+static void libinput_backend_handle_display_destroy(
+ struct wl_listener *listener, void *data);
+
+WL_EXPORT struct ds_backend *
+ds_libinput_backend_create(struct wl_display *display)
+{
+ struct ds_libinput_backend *libinput_backend;
+
+ libinput_backend = calloc(1, sizeof *libinput_backend);
+ if (!libinput_backend) {
+ ds_log_errno(DS_ERR, "Could not allocate memory");
+ return NULL;
+ }
+
+ ds_backend_init(&libinput_backend->base, &libinput_backend_interface);
+
+ libinput_backend->display = display;
+ wl_list_init(&libinput_backend->devices);
+
+ libinput_backend->display_destroy.notify =
+ libinput_backend_handle_display_destroy;
+ wl_display_add_destroy_listener(display,
+ &libinput_backend->display_destroy);
+
+ ds_inf("Libinput backend(%p) created",
+ libinput_backend);
+
+ return &libinput_backend->base;
+}
+
+WL_EXPORT struct ds_libinput_backend *
+libinput_backend_from_backend(struct ds_backend *backend)
+{
+ assert(backend->iface == &libinput_backend_interface);
+ return (struct ds_libinput_backend *)backend;
+}
+
+void
+destroy_libinput_input_device(struct ds_libinput_input_device *dev)
+{
+ ds_input_device_destroy(&dev->base);
+ libinput_device_unref(dev->handle);
+ wl_list_remove(&dev->link);
+ free(dev);
+}
+
+static void
+libinput_backend_destroy(struct ds_libinput_backend *backend)
+{
+ struct ds_libinput_input_device *dev, *tmp_dev;
+
+ wl_list_for_each_safe(dev, tmp_dev, &backend->devices, link)
+ destroy_libinput_input_device(dev);
+
+ ds_backend_finish(&backend->base);
+ wl_list_remove(&backend->display_destroy.link);
+ wl_event_source_remove(backend->server_event_source);
+ udev_unref(backend->udev);
+ libinput_unref(backend->libinput_context);
+
+ free(backend);
+}
+
+static int
+libinput_open_restricted(const char *path, int flags, void *_backend)
+{
+ int fd = -1;
+ struct stat s;
+
+ fd = open(path, flags | O_CLOEXEC);
+
+ if (fd < 0 || (fstat(fd, &s) == -1)) {
+ ds_log(DS_ERR, "Could not open device");
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+static void
+libinput_close_restricted(int fd, void *_backend)
+{
+ if (fd >= 0) close(fd);
+}
+
+static const struct libinput_interface libinput_impl = {
+ .open_restricted = libinput_open_restricted,
+ .close_restricted = libinput_close_restricted
+};
+
+static int
+handle_libinput_readable(int fd, uint32_t mask, void *_backend)
+{
+ struct ds_libinput_backend *backend = _backend;
+ struct libinput_event *event;
+ int ret;
+
+ ret = libinput_dispatch(backend->libinput_context);
+ if (ret != 0) {
+ ds_log(DS_ERR, "Failed to dispatch libinput: %s", strerror(-ret));
+ wl_display_terminate(backend->display);
+ return 0;
+ }
+
+ while ((event = libinput_get_event(backend->libinput_context))) {
+ handle_libinput_event(backend, event);
+ libinput_event_destroy(event);
+ }
+ return 0;
+}
+
+static void
+log_libinput(struct libinput *libinput_context,
+ enum libinput_log_priority priority, const char *fmt, va_list args)
+{
+ char buf[1024] = {0,};
+
+ vsnprintf(buf, 1024, fmt, args);
+ switch (priority) {
+ case LIBINPUT_LOG_PRIORITY_DEBUG:
+ ds_log(DS_DBG,"%s", buf);
+ break;
+ case LIBINPUT_LOG_PRIORITY_INFO:
+ ds_log(DS_INF, "%s", buf);
+ break;
+ case LIBINPUT_LOG_PRIORITY_ERROR:
+ ds_log(DS_ERR, "%s", buf);
+ break;
+ default:
+ break;
+ }
+}
+
+static bool
+libinput_backend_iface_start(struct ds_backend *ds_backend)
+{
+ struct ds_libinput_backend *backend;
+ struct wl_event_loop *event_loop;
+ int libinput_fd;
+
+ backend = libinput_backend_from_backend(ds_backend);
+ ds_log(DS_DBG, "Starting libinput backend");
+
+ backend->udev = udev_new();
+ backend->libinput_context = libinput_udev_create_context(&libinput_impl,
+ backend, backend->udev);
+ if (!backend->libinput_context) {
+ ds_log(DS_ERR, "Failed to create libinput context");
+ return false;
+ }
+
+ if (libinput_udev_assign_seat(backend->libinput_context, "seat0") != 0) {
+ ds_log(DS_ERR, "Failed to assign libinput seat");
+ return false;
+ }
+
+ libinput_log_set_handler(backend->libinput_context, log_libinput);
+ libinput_log_set_priority(backend->libinput_context,
+ LIBINPUT_LOG_PRIORITY_DEBUG);
+
+ libinput_fd = libinput_get_fd(backend->libinput_context);
+ if (wl_list_empty(&backend->devices)) {
+ handle_libinput_readable(libinput_fd, WL_EVENT_READABLE, backend);
+ if (wl_list_empty(&backend->devices)) {
+ ds_log(DS_ERR, "libinput initialization failed, no input devices");
+ return false;
+ }
+ }
+
+ event_loop = wl_display_get_event_loop(backend->display);
+ if (backend->server_event_source) {
+ wl_event_source_remove(backend->server_event_source);
+ }
+ backend->server_event_source =
+ wl_event_loop_add_fd(event_loop, libinput_fd, WL_EVENT_READABLE,
+ handle_libinput_readable, backend);
+ if (!backend->server_event_source) {
+ ds_log(DS_ERR, "Failed to create input event on event loop");
+ return false;
+ }
+ ds_log(DS_DBG, "libinput successfully initialized");
+
+ return true;
+}
+
+static void
+libinput_backend_iface_destroy(struct ds_backend *backend)
+{
+ struct ds_libinput_backend *libinput_backend;
+
+ if (!backend)
+ return;
+
+ libinput_backend = libinput_backend_from_backend(backend);
+ libinput_backend_destroy(libinput_backend);
+}
+
+static const struct ds_backend_interface libinput_backend_interface =
+{
+ .start = libinput_backend_iface_start,
+ .destroy = libinput_backend_iface_destroy,
+ .get_drm_fd = NULL,
+};
+
+static void
+libinput_backend_handle_display_destroy(struct wl_listener *listener,
+ void *data)
+{
+ struct ds_libinput_backend *libinput_backend;
+
+ libinput_backend =
+ wl_container_of(listener, libinput_backend, display_destroy);
+ libinput_backend_destroy(libinput_backend);
+}
--- /dev/null
+#ifndef DS_BACKEND_LIBINPUT_H
+#define DS_BACKEND_LIBINPUT_H
+
+#include <libinput.h>
+#include <libudev.h>
+
+#include "libds/interfaces/backend.h"
+#include "libds/interfaces/input_device.h"
+#include "libds/interfaces/pointer.h"
+#include "libds/interfaces/keyboard.h"
+#include "libds/interfaces/touch.h"
+
+struct ds_libinput_backend
+{
+ struct ds_backend base;
+
+ struct wl_display *display;
+ struct wl_listener display_destroy;
+
+ struct udev *udev;
+ struct libinput *libinput_context;
+ struct wl_list devices; // ds_libinput_input_device::link
+
+ struct wl_event_source *server_event_source;
+};
+
+struct ds_libinput_input_device
+{
+ struct ds_input_device base;
+
+ struct ds_libinput_backend *backend;
+ struct libinput_device *handle;
+
+ struct wl_list link; //ds_libinput_backend.devices
+};
+
+struct ds_libinput_backend *
+ libinput_backend_from_backend(struct ds_backend *backend);
+
+void handle_libinput_event(struct ds_libinput_backend *state,
+ struct libinput_event *event);
+
+void destroy_libinput_input_device(struct ds_libinput_input_device *dev);
+
+//keyboard
+void handle_keyboard_key(struct libinput_event *event,
+ struct ds_keyboard *kbd);
+
+//pointer
+void handle_pointer_motion(struct libinput_event *event,
+ struct ds_pointer *pointer);
+void handle_pointer_motion_abs(struct libinput_event *event,
+ struct ds_pointer *pointer);
+void handle_pointer_button(struct libinput_event *event,
+ struct ds_pointer *pointer);
+void handle_pointer_axis(struct libinput_event *event,
+ struct ds_pointer *pointer);
+
+//touch
+void handle_touch_down(struct libinput_event *event,
+ struct ds_touch *touch);
+void handle_touch_up(struct libinput_event *event,
+ struct ds_touch *touch);
+void handle_touch_motion(struct libinput_event *event,
+ struct ds_touch *touch);
+void handle_touch_cancel(struct libinput_event *event,
+ struct ds_touch *touch);
+void handle_touch_frame(struct libinput_event *event,
+ struct ds_touch *touch);
+
+#endif
--- /dev/null
+#include <assert.h>
+
+#include "libds/log.h"
+#include "backend.h"
+
+static const struct ds_input_device_interface input_device_iface;
+
+static bool
+ds_input_device_is_libinput(struct ds_input_device *ds_dev)
+{
+ return ds_dev->iface == &input_device_iface;
+}
+
+static struct ds_libinput_input_device *
+get_libinput_input_device_from_input_device(struct ds_input_device *ds_dev)
+{
+ assert(ds_input_device_is_libinput(ds_dev));
+ return (struct ds_libinput_input_device *)ds_dev;
+}
+
+static void
+input_device_iface_destroy(struct ds_input_device *ds_dev)
+{
+ struct ds_libinput_input_device *dev;
+
+ dev = get_libinput_input_device_from_input_device(ds_dev);
+
+ free(dev);
+}
+
+static const struct ds_input_device_interface input_device_iface =
+{
+ .destroy = input_device_iface_destroy,
+};
+
+static struct ds_keyboard *
+create_ds_keyboard()
+{
+ struct ds_keyboard *kbd;
+ kbd = calloc(1, sizeof *kbd);
+ if (!kbd) {
+ ds_err("Could not allocate memory");
+ return NULL;
+ }
+ ds_keyboard_init(kbd, NULL);
+
+ return kbd;
+}
+
+static struct ds_pointer *
+create_ds_pointer()
+{
+ struct ds_pointer *pointer;
+ pointer = calloc(1, sizeof *pointer);
+ if (!pointer) {
+ ds_err("Could not allocate memory");
+ return NULL;
+ }
+ ds_pointer_init(pointer, NULL);
+
+ return pointer;
+}
+
+static struct ds_touch *
+create_ds_touch()
+{
+ struct ds_touch *touch;
+ touch = calloc(1, sizeof *touch);
+ if (!touch) {
+ ds_err("Could not allocate memory");
+ return NULL;
+ }
+ ds_touch_init(touch, NULL);
+
+ return touch;
+}
+
+static void
+handle_device_added(struct ds_libinput_backend *backend,
+ struct libinput_device *libinput_dev)
+{
+ int vendor, product;
+ const char *name;
+ struct ds_libinput_input_device *dev;
+
+ vendor = libinput_device_get_id_vendor(libinput_dev);
+ product = libinput_device_get_id_product(libinput_dev);
+ name = libinput_device_get_name(libinput_dev);
+ ds_log(DS_DBG, "Adding %s [%d:%d]", name, vendor, product);
+
+ dev = calloc(1, sizeof(struct ds_libinput_input_device));
+ if (dev == NULL) {
+ ds_log(DS_ERR, "failed to allocate ds_libinput_input_device");
+ return;
+ }
+
+ dev->handle = libinput_dev;
+ dev->backend = backend;
+ libinput_device_ref(libinput_dev);
+ libinput_device_set_user_data(libinput_dev, dev);
+
+ wl_list_insert(&backend->devices, &dev->link);
+
+ if (libinput_device_has_capability(
+ libinput_dev, LIBINPUT_DEVICE_CAP_KEYBOARD)) {
+ ds_input_device_init(&dev->base, DS_INPUT_DEVICE_KEYBOARD,
+ &input_device_iface, name, vendor, product);
+ dev->base.keyboard = create_ds_keyboard();
+
+ wl_signal_emit(&backend->base.events.new_input,
+ &dev->base);
+ }
+
+ if (libinput_device_has_capability(
+ libinput_dev, LIBINPUT_DEVICE_CAP_POINTER)) {
+ ds_input_device_init(&dev->base, DS_INPUT_DEVICE_POINTER,
+ &input_device_iface, name, vendor, product);
+ dev->base.pointer = create_ds_pointer();
+
+ wl_signal_emit(&backend->base.events.new_input,
+ &dev->base);
+ }
+
+ if (libinput_device_has_capability(
+ libinput_dev, LIBINPUT_DEVICE_CAP_TOUCH)) {
+ ds_input_device_init(&dev->base, DS_INPUT_DEVICE_TOUCH,
+ &input_device_iface, name, vendor, product);
+ dev->base.touch = create_ds_touch();
+
+ wl_signal_emit(&backend->base.events.new_input,
+ &dev->base);
+ }
+}
+
+static void
+handle_device_removed(struct ds_libinput_backend *backend,
+ struct libinput_device *libinput_dev)
+{
+ int vendor, product;
+ const char *name;
+ struct ds_libinput_input_device *dev;
+
+ vendor = libinput_device_get_id_vendor(libinput_dev);
+ product = libinput_device_get_id_product(libinput_dev);
+ name = libinput_device_get_name(libinput_dev);
+ ds_log(DS_DBG, "Removing %s [%d:%d]", name, vendor, product);
+
+ dev = libinput_device_get_user_data(libinput_dev);
+ if (dev == NULL) {
+ ds_log(DS_ERR, "libinput_device has no ds_libinput_input_device");
+ return;
+ }
+
+ destroy_libinput_input_device(dev);
+}
+
+void
+handle_libinput_event(struct ds_libinput_backend *backend,
+ struct libinput_event *event)
+{
+ struct libinput_device *libinput_dev;
+ struct ds_libinput_input_device *dev;
+ enum libinput_event_type event_type;
+
+ libinput_dev = libinput_event_get_device(event);
+ event_type = libinput_event_get_type(event);
+ dev = libinput_device_get_user_data(libinput_dev);
+
+ switch (event_type) {
+ case LIBINPUT_EVENT_DEVICE_ADDED:
+ handle_device_added(backend, libinput_dev);
+ break;
+ case LIBINPUT_EVENT_DEVICE_REMOVED:
+ handle_device_removed(backend, libinput_dev);
+ break;
+ case LIBINPUT_EVENT_KEYBOARD_KEY:
+ handle_keyboard_key(event, dev->base.keyboard);
+ break;
+ case LIBINPUT_EVENT_POINTER_MOTION:
+ handle_pointer_motion(event, dev->base.pointer);
+ break;
+ case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
+ handle_pointer_motion_abs(event, dev->base.pointer);
+ break;
+ case LIBINPUT_EVENT_POINTER_BUTTON:
+ handle_pointer_button(event, dev->base.pointer);
+ break;
+ case LIBINPUT_EVENT_POINTER_AXIS:
+ handle_pointer_axis(event, dev->base.pointer);
+ break;
+ case LIBINPUT_EVENT_TOUCH_DOWN:
+ handle_touch_down(event, dev->base.touch);
+ break;
+ case LIBINPUT_EVENT_TOUCH_UP:
+ handle_touch_up(event, dev->base.touch);
+ break;
+ case LIBINPUT_EVENT_TOUCH_MOTION:
+ handle_touch_motion(event, dev->base.touch);
+ break;
+ case LIBINPUT_EVENT_TOUCH_CANCEL:
+ handle_touch_cancel(event, dev->base.touch);
+ break;
+ case LIBINPUT_EVENT_TOUCH_FRAME:
+ handle_touch_frame(event, dev->base.touch);
+ break;
+ default:
+ ds_log(DS_DBG, "Unknown libinput event %d", event_type);
+ break;
+ }
+}
--- /dev/null
+#include "libds/log.h"
+#include "backend.h"
+
+void
+handle_keyboard_key(struct libinput_event *event,
+ struct ds_keyboard *kbd)
+{
+ struct libinput_event_keyboard *kbevent;
+ uint32_t key;
+ enum libinput_key_state li_state;
+ enum wl_keyboard_key_state state = WL_KEYBOARD_KEY_STATE_PRESSED;
+
+ kbevent = libinput_event_get_keyboard_event(event);
+
+ key = libinput_event_keyboard_get_key(kbevent);
+ li_state = libinput_event_keyboard_get_key_state(kbevent);
+ if (li_state == LIBINPUT_KEY_STATE_PRESSED) {
+ state = WL_KEYBOARD_KEY_STATE_PRESSED;
+ }
+ else {
+ state = WL_KEYBOARD_KEY_STATE_RELEASED;
+ }
+
+ ds_log(DS_DBG, "Keyboard(%p) key event key:%d, state:%s", kbd, key,
+ (state == WL_KEYBOARD_KEY_STATE_PRESSED) ? "PRESSED":"RELEASED");
+
+ struct ds_event_keyboard_key ds_event = {
+ .keycode = key,
+ .state = state,
+ .time_msec = -1,
+ .update_state = false,
+ };
+
+ ds_keyboard_notify_key(kbd, &ds_event);
+}
--- /dev/null
+libds_files += files(
+ 'backend.c',
+ 'input.c',
+ 'keyboard.c',
+ 'pointer.c',
+ 'touch.c',
+)
+
+libinput = dependency('libinput', required: true)
+libudev = dependency('libudev', required: true)
+
+libds_deps += [
+ libinput,
+ libudev,
+]
--- /dev/null
+#include "libds/log.h"
+#include "backend.h"
+
+void
+handle_pointer_motion(struct libinput_event *event,
+ struct ds_pointer *pointer)
+{
+ struct libinput_event_pointer *pevent;
+ double delta_x, delta_y;
+ struct ds_event_pointer_motion ds_event = { 0 };
+
+ pevent = libinput_event_get_pointer_event(event);
+
+ delta_x = libinput_event_pointer_get_dx(pevent);
+ delta_y = libinput_event_pointer_get_dy(pevent);
+
+ ds_log(DS_DBG, "pointer motion event delta_x:%f, delta_y:%f", delta_x, delta_y);
+
+ ds_event.device = NULL;
+ ds_event.time_msec = -1;
+ ds_event.delta_x = delta_x;
+ ds_event.delta_y = delta_y;
+
+ wl_signal_emit(&pointer->events.motion, &ds_event);
+}
+
+void
+handle_pointer_motion_abs(struct libinput_event *event,
+ struct ds_pointer *pointer)
+{
+ struct libinput_event_pointer *pevent;
+ double x, y;
+ struct ds_event_pointer_motion_absolute ds_event = { 0 };
+
+ pevent = libinput_event_get_pointer_event(event);
+
+ x = libinput_event_pointer_get_absolute_x_transformed(pevent, 1);
+ y = libinput_event_pointer_get_absolute_y_transformed(pevent, 1);
+
+ ds_log(DS_DBG, "Pointer(%p) motion abs event x:%f, y:%f", pointer, x, y);
+
+ ds_event.device = NULL;
+ ds_event.time_msec = -1;
+ ds_event.x = x;
+ ds_event.y = y;
+
+ wl_signal_emit(&pointer->events.motion_absolute, &ds_event);
+}
+void
+handle_pointer_button(struct libinput_event *event,
+ struct ds_pointer *pointer)
+{
+ struct libinput_event_pointer *pevent;
+ uint32_t button;
+ enum libinput_button_state li_state = LIBINPUT_BUTTON_STATE_PRESSED;
+ enum ds_button_state state = DS_BUTTON_PRESSED;
+ struct ds_event_pointer_button ds_event = { 0 };
+
+ pevent = libinput_event_get_pointer_event(event);
+
+ button = libinput_event_pointer_get_button(pevent);
+ button = ((button & 0x00F) + 1);
+ if (button == 3) button = 2;
+ else if (button == 2) button = 3;
+
+ li_state = libinput_event_pointer_get_button_state(pevent);
+ if (li_state == LIBINPUT_BUTTON_STATE_PRESSED) {
+ state = DS_BUTTON_PRESSED;
+ }
+ else {
+ state = DS_BUTTON_RELEASED;
+ }
+ ds_log(DS_DBG, "Pointer(%p) button event button:%d state:%s",
+ pointer, button,
+ (state == DS_BUTTON_PRESSED) ? "PRESSED" : "RELEASED");
+
+ ds_event.device = NULL;
+ ds_event.time_msec = -1;
+ ds_event.button = button;
+ ds_event.state = state;
+
+ wl_signal_emit(&pointer->events.button, &ds_event);
+}
+
+void
+handle_pointer_axis(struct libinput_event *event,
+ struct ds_pointer *pointer)
+{
+ ds_log(DS_DBG, "pointer(%p) axis event", pointer);
+ /* TODO: wl_signal_emit() */
+}
--- /dev/null
+#include "libds/log.h"
+#include "backend.h"
+
+void
+handle_touch_down(struct libinput_event *event,
+ struct ds_touch *touch)
+{
+ struct libinput_event_touch *tevent;
+ uint32_t touch_id;
+ double x, y;
+ struct ds_event_touch_down ds_event = { 0 };
+
+ tevent = libinput_event_get_touch_event(event);
+
+ touch_id = libinput_event_touch_get_seat_slot(tevent);
+ x = libinput_event_touch_get_x_transformed(tevent, 1);
+ y = libinput_event_touch_get_y_transformed(tevent, 1);
+
+ ds_log(DS_DBG, "touch down event id:%d, x:%f, y:%f", touch_id, x, y);
+
+ ds_event.device = NULL;
+ ds_event.time_msec = -1;
+ ds_event.id = touch_id;
+ ds_event.x = x;
+ ds_event.y = y;
+
+ wl_signal_emit(&touch->events.down, &ds_event);
+}
+
+void
+handle_touch_up(struct libinput_event *event,
+ struct ds_touch *touch)
+{
+ struct libinput_event_touch *tevent;
+ uint32_t touch_id;
+ struct ds_event_touch_up ds_event = { 0 };
+
+ tevent = libinput_event_get_touch_event(event);
+
+ touch_id = libinput_event_touch_get_seat_slot(tevent);
+
+ ds_log(DS_DBG, "touch up event id:%d", touch_id);
+
+ ds_event.device = NULL;
+ ds_event.time_msec = -1;
+ ds_event.id = touch_id;
+
+ wl_signal_emit(&touch->events.up, &ds_event);
+}
+
+void
+handle_touch_motion(struct libinput_event *event,
+ struct ds_touch *touch)
+{
+ struct libinput_event_touch *tevent;
+ uint32_t touch_id;
+ double x, y;
+ struct ds_event_touch_motion ds_event = { 0 };
+
+ tevent = libinput_event_get_touch_event(event);
+
+ touch_id = libinput_event_touch_get_seat_slot(tevent);
+ x = libinput_event_touch_get_x_transformed(tevent, 1);
+ y = libinput_event_touch_get_y_transformed(tevent, 1);
+
+ ds_log(DS_DBG, "touch motion event id:%d, x:%f, y:%f", touch_id, x, y);
+
+ ds_event.device = NULL;
+ ds_event.time_msec = -1;
+ ds_event.id = touch_id;
+ ds_event.x = x;
+ ds_event.y = y;
+
+ wl_signal_emit(&touch->events.motion, &ds_event);
+}
+
+void
+handle_touch_cancel(struct libinput_event *event,
+ struct ds_touch *touch)
+{
+ struct libinput_event_touch *tevent;
+ uint32_t touch_id;
+
+ tevent = libinput_event_get_touch_event(event);
+
+ touch_id = libinput_event_touch_get_seat_slot(tevent);
+
+ ds_log(DS_DBG, "touch cancel event id:%d", touch_id);
+ /* TODO: wl_signal_emit() */
+}
+
+void
+handle_touch_frame(struct libinput_event *event,
+ struct ds_touch *touch)
+{
+ ds_log(DS_DBG, "touch frame event");
+ /* TODO: wl_signal_emit() */
+}
subdir('wayland')
+subdir('libinput')