diff options
Diffstat (limited to 'backend')
-rw-r--r-- | backend/CMakeLists.txt | 1 | ||||
-rw-r--r-- | backend/backend.c | 8 | ||||
-rw-r--r-- | backend/libinput/backend.c | 13 | ||||
-rw-r--r-- | backend/libinput/events.c | 100 |
4 files changed, 108 insertions, 14 deletions
diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt index c3e7ef54..e22032c3 100644 --- a/backend/CMakeLists.txt +++ b/backend/CMakeLists.txt @@ -15,6 +15,7 @@ add_library(wlr-backend drm/drm.c libinput/backend.c + libinput/events.c backend.c egl.c diff --git a/backend/backend.c b/backend/backend.c index 1a0c3295..83249a8c 100644 --- a/backend/backend.c +++ b/backend/backend.c @@ -19,14 +19,10 @@ struct wlr_backend *wlr_backend_create(const struct wlr_backend_impl *impl, } backend->state = state; backend->impl = impl; + wl_signal_init(&backend->events.input_add); + wl_signal_init(&backend->events.input_remove); wl_signal_init(&backend->events.output_add); wl_signal_init(&backend->events.output_remove); - wl_signal_init(&backend->events.keyboard_add); - wl_signal_init(&backend->events.keyboard_remove); - wl_signal_init(&backend->events.pointer_add); - wl_signal_init(&backend->events.pointer_remove); - wl_signal_init(&backend->events.touch_add); - wl_signal_init(&backend->events.touch_remove); return backend; } diff --git a/backend/libinput/backend.c b/backend/libinput/backend.c index f6dce58e..3af08875 100644 --- a/backend/libinput/backend.c +++ b/backend/libinput/backend.c @@ -23,7 +23,7 @@ static const struct libinput_interface libinput_impl = { .close_restricted = wlr_libinput_close_restricted }; -static int wlr_libinput_handle_event(int fd, uint32_t mask, void *_state) { +static int wlr_libinput_readable(int fd, uint32_t mask, void *_state) { struct wlr_backend_state *state = _state; if (libinput_dispatch(state->libinput) != 0) { wlr_log(L_ERROR, "Failed to dispatch libinput"); @@ -32,12 +32,7 @@ static int wlr_libinput_handle_event(int fd, uint32_t mask, void *_state) { } struct libinput_event *event; while ((event = libinput_get_event(state->libinput))) { - struct libinput *context = libinput_event_get_context(event); - struct libinput_device *device = libinput_event_get_device(event); - enum libinput_event_type event_type = libinput_event_get_type(event); - wlr_log(L_DEBUG, "libinput event: %d", event_type); - (void)device; (void)context; - // TODO: dispatch event + wlr_libinput_event(state, event); } return 0; } @@ -73,7 +68,7 @@ static bool wlr_libinput_backend_init(struct wlr_backend_state *state) { } state->input_event = wl_event_loop_add_fd(event_loop, libinput_get_fd(state->libinput), WL_EVENT_READABLE, - wlr_libinput_handle_event, state); + wlr_libinput_readable, state); if (!state->input_event) { wlr_log(L_ERROR, "Failed to create input event on event loop"); return false; @@ -112,5 +107,7 @@ struct wlr_backend *wlr_libinput_backend_create(struct wl_display *display, state->udev = udev; state->display = display; + state->keyboards = list_create(); + return backend; } diff --git a/backend/libinput/events.c b/backend/libinput/events.c new file mode 100644 index 00000000..b4816928 --- /dev/null +++ b/backend/libinput/events.c @@ -0,0 +1,100 @@ +#include <stdlib.h> +#include <assert.h> +#include <libinput.h> +#include <wlr/session.h> +#include <wlr/types.h> +#include <wlr/common/list.h> +#include "backend/libinput/backend.h" +#include "common/log.h" +#include "types.h" + +static void wlr_libinput_keyboard_destroy(struct wlr_keyboard_state *state) { + free(state); +} + +static struct wlr_keyboard_impl keyboard_impl = { + .destroy = wlr_libinput_keyboard_destroy +}; + +static struct wlr_keyboard *wlr_libinput_keyboard_create( + struct libinput_device *device) { + assert(device); + struct wlr_keyboard_state *kbstate = + calloc(1, sizeof(struct wlr_keyboard_state)); + kbstate->handle = device; + return wlr_keyboard_create(&keyboard_impl, kbstate); +} + +static void device_added(struct wlr_backend_state *state, + struct libinput_device *device) { + assert(state && device); + /* + * Note: the wlr API exposes only devices with a single capability, because + * that meshes better with how Wayland does things and is a bit simpler. + * However, libinput devices often have multiple capabilities - in such + * cases we have to create several devices. + */ + int vendor = libinput_device_get_id_vendor(device); + int product = libinput_device_get_id_product(device); + const char *name = libinput_device_get_name(device); + list_t *devices = list_create(); + wlr_log(L_DEBUG, "Added %s [%d:%d]", name, vendor, product); + + if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_KEYBOARD)) { + struct wlr_input_device *wlr_device = wlr_input_device_create( + WLR_INPUT_DEVICE_KEYBOARD, name, vendor, product); + wlr_device->keyboard = wlr_libinput_keyboard_create(device); + wl_signal_emit(&state->backend->events.input_add, wlr_device); + list_add(devices, wlr_device); + } + if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER)) { + // TODO + } + if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH)) { + // TODO + } + if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TABLET_TOOL)) { + // TODO + } + if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TABLET_PAD)) { + // TODO + } + if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_GESTURE)) { + // TODO + } + if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_SWITCH)) { + // TODO + } + + if (devices->length > 0) { + libinput_device_set_user_data(device, devices); + } else { + list_free(devices); + } +} + +static void device_removed(struct wlr_backend_state *state, + struct libinput_device *device) { + wlr_log(L_DEBUG, "libinput device removed"); + // TODO +} + +void wlr_libinput_event(struct wlr_backend_state *state, + struct libinput_event *event) { + assert(state && event); + struct libinput *context = libinput_event_get_context(event); + struct libinput_device *device = libinput_event_get_device(event); + enum libinput_event_type event_type = libinput_event_get_type(event); + (void)context; + switch (event_type) { + case LIBINPUT_EVENT_DEVICE_ADDED: + device_added(state, device); + break; + case LIBINPUT_EVENT_DEVICE_REMOVED: + device_removed(state, device); + break; + default: + wlr_log(L_DEBUG, "Unknown libinput event %d", event_type); + break; + } +} |