diff options
Diffstat (limited to 'backend/libinput/tablet_pad.c')
-rw-r--r-- | backend/libinput/tablet_pad.c | 121 |
1 files changed, 71 insertions, 50 deletions
diff --git a/backend/libinput/tablet_pad.c b/backend/libinput/tablet_pad.c index 50b8ad6e..ba988557 100644 --- a/backend/libinput/tablet_pad.c +++ b/backend/libinput/tablet_pad.c @@ -1,17 +1,20 @@ -#ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200809L -#endif #include <assert.h> #include <string.h> #include <libinput.h> #include <stdlib.h> -#include <wlr/backend/session.h> #include <wlr/interfaces/wlr_tablet_pad.h> -#include <wlr/types/wlr_input_device.h> #include <wlr/util/log.h> #include "backend/libinput.h" #include "util/signal.h" +static void group_destroy(struct wlr_tablet_pad_group *group) { + free(group->buttons); + free(group->strips); + free(group->rings); + free(group); +} + // FIXME: Decide on how to alloc/count here static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad, struct libinput_device *device, unsigned int index) { @@ -20,6 +23,7 @@ static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad, struct wlr_tablet_pad_group *group = calloc(1, sizeof(struct wlr_tablet_pad_group)); if (!group) { + wlr_log_errno(WLR_ERROR, "failed to allocate wlr_tablet_pad_group"); return; } @@ -29,6 +33,10 @@ static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad, } } group->rings = calloc(sizeof(unsigned int), group->ring_count); + if (group->rings == NULL) { + goto group_fail; + } + size_t ring = 0; for (size_t i = 0; i < pad->ring_count; ++i) { if (libinput_tablet_pad_mode_group_has_ring(li_group, i)) { @@ -42,6 +50,9 @@ static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad, } } group->strips = calloc(sizeof(unsigned int), group->strip_count); + if (group->strips == NULL) { + goto group_fail; + } size_t strip = 0; for (size_t i = 0; i < pad->strip_count; ++i) { if (libinput_tablet_pad_mode_group_has_strip(li_group, i)) { @@ -55,6 +66,9 @@ static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad, } } group->buttons = calloc(sizeof(unsigned int), group->button_count); + if (group->buttons == NULL) { + goto group_fail; + } size_t button = 0; for (size_t i = 0; i < pad->button_count; ++i) { if (libinput_tablet_pad_mode_group_has_button(li_group, i)) { @@ -63,53 +77,74 @@ static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad, } group->mode_count = libinput_tablet_pad_mode_group_get_num_modes(li_group); + + libinput_tablet_pad_mode_group_ref(li_group); + wl_list_insert(&pad->groups, &group->link); + return; + +group_fail: + wlr_log(WLR_ERROR, "failed to configure wlr_tablet_pad_group"); + group_destroy(group); } -const struct wlr_tablet_pad_impl libinput_tablet_pad_impl; +static void tablet_pad_destroy(struct wlr_tablet_pad *wlr_tablet_pad) { + struct wlr_libinput_input_device *dev = + device_from_tablet_pad(wlr_tablet_pad); -struct wlr_tablet_pad *create_libinput_tablet_pad( - struct libinput_device *libinput_dev) { - assert(libinput_dev); - struct wlr_tablet_pad *wlr_tablet_pad = - calloc(1, sizeof(struct wlr_tablet_pad)); - if (!wlr_tablet_pad) { - wlr_log(WLR_ERROR, "Unable to allocate wlr_tablet_pad"); - return NULL; + struct wlr_tablet_pad_group *group, *tmp; + wl_list_for_each_safe(group, tmp, &wlr_tablet_pad->groups, link) { + group_destroy(group); + } + + int groups = libinput_device_tablet_pad_get_num_mode_groups(dev->handle); + for (int i = 0; i < groups; ++i) { + struct libinput_tablet_pad_mode_group *li_group = + libinput_device_tablet_pad_get_mode_group(dev->handle, i); + libinput_tablet_pad_mode_group_unref(li_group); } - const char *name = libinput_device_get_name(libinput_dev); +} + +const struct wlr_tablet_pad_impl libinput_tablet_pad_impl = { + .destroy = tablet_pad_destroy, +}; + +void init_device_tablet_pad(struct wlr_libinput_input_device *dev) { + struct libinput_device *handle = dev->handle; + const char *name = libinput_device_get_name(handle); + struct wlr_tablet_pad *wlr_tablet_pad = &dev->tablet_pad; wlr_tablet_pad_init(wlr_tablet_pad, &libinput_tablet_pad_impl, name); - wlr_tablet_pad->base.vendor = libinput_device_get_id_vendor(libinput_dev); - wlr_tablet_pad->base.product = libinput_device_get_id_product(libinput_dev); + wlr_tablet_pad->base.vendor = libinput_device_get_id_vendor(handle); + wlr_tablet_pad->base.product = libinput_device_get_id_product(handle); wlr_tablet_pad->button_count = - libinput_device_tablet_pad_get_num_buttons(libinput_dev); + libinput_device_tablet_pad_get_num_buttons(handle); wlr_tablet_pad->ring_count = - libinput_device_tablet_pad_get_num_rings(libinput_dev); + libinput_device_tablet_pad_get_num_rings(handle); wlr_tablet_pad->strip_count = - libinput_device_tablet_pad_get_num_strips(libinput_dev); + libinput_device_tablet_pad_get_num_strips(handle); - struct udev_device *udev = libinput_device_get_udev_device(libinput_dev); + struct udev_device *udev = libinput_device_get_udev_device(handle); char **dst = wl_array_add(&wlr_tablet_pad->paths, sizeof(char *)); *dst = strdup(udev_device_get_syspath(udev)); - int groups = libinput_device_tablet_pad_get_num_mode_groups(libinput_dev); + int groups = libinput_device_tablet_pad_get_num_mode_groups(handle); for (int i = 0; i < groups; ++i) { - add_pad_group_from_libinput(wlr_tablet_pad, libinput_dev, i); + add_pad_group_from_libinput(wlr_tablet_pad, handle, i); } +} + +struct wlr_libinput_input_device *device_from_tablet_pad( + struct wlr_tablet_pad *wlr_tablet_pad) { + assert(wlr_tablet_pad->impl == &libinput_tablet_pad_impl); - return wlr_tablet_pad; + struct wlr_libinput_input_device *dev = + wl_container_of(wlr_tablet_pad, dev, tablet_pad); + return dev; } void handle_tablet_pad_button(struct libinput_event *event, - struct libinput_device *libinput_dev) { - struct wlr_input_device *wlr_dev = - get_appropriate_device(WLR_INPUT_DEVICE_TABLET_PAD, libinput_dev); - if (!wlr_dev) { - wlr_log(WLR_DEBUG, - "Got a tablet pad event for a device with no tablet pad?"); - return; - } + struct wlr_tablet_pad *tablet_pad) { struct libinput_event_tablet_pad *pevent = libinput_event_get_tablet_pad_event(event); struct wlr_event_tablet_pad_button wlr_event = { 0 }; @@ -127,18 +162,11 @@ void handle_tablet_pad_button(struct libinput_event *event, wlr_event.state = WLR_BUTTON_RELEASED; break; } - wlr_signal_emit_safe(&wlr_dev->tablet_pad->events.button, &wlr_event); + wlr_signal_emit_safe(&tablet_pad->events.button, &wlr_event); } void handle_tablet_pad_ring(struct libinput_event *event, - struct libinput_device *libinput_dev) { - struct wlr_input_device *wlr_dev = - get_appropriate_device(WLR_INPUT_DEVICE_TABLET_PAD, libinput_dev); - if (!wlr_dev) { - wlr_log(WLR_DEBUG, - "Got a tablet pad event for a device with no tablet pad?"); - return; - } + struct wlr_tablet_pad *tablet_pad) { struct libinput_event_tablet_pad *pevent = libinput_event_get_tablet_pad_event(event); struct wlr_event_tablet_pad_ring wlr_event = { 0 }; @@ -155,18 +183,11 @@ void handle_tablet_pad_ring(struct libinput_event *event, wlr_event.source = WLR_TABLET_PAD_RING_SOURCE_FINGER; break; } - wlr_signal_emit_safe(&wlr_dev->tablet_pad->events.ring, &wlr_event); + wlr_signal_emit_safe(&tablet_pad->events.ring, &wlr_event); } void handle_tablet_pad_strip(struct libinput_event *event, - struct libinput_device *libinput_dev) { - struct wlr_input_device *wlr_dev = - get_appropriate_device(WLR_INPUT_DEVICE_TABLET_PAD, libinput_dev); - if (!wlr_dev) { - wlr_log(WLR_DEBUG, - "Got a tablet pad event for a device with no tablet pad?"); - return; - } + struct wlr_tablet_pad *tablet_pad) { struct libinput_event_tablet_pad *pevent = libinput_event_get_tablet_pad_event(event); struct wlr_event_tablet_pad_strip wlr_event = { 0 }; @@ -183,5 +204,5 @@ void handle_tablet_pad_strip(struct libinput_event *event, wlr_event.source = WLR_TABLET_PAD_STRIP_SOURCE_FINGER; break; } - wlr_signal_emit_safe(&wlr_dev->tablet_pad->events.strip, &wlr_event); + wlr_signal_emit_safe(&tablet_pad->events.strip, &wlr_event); } |