X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Flibinput.c;h=5780a92d7aca126cf3df182c11550a6a21b09e01;hb=HEAD;hp=550ca942d5c0ca0358d79b189ca67a4e8ac2f4f7;hpb=ded615c64f5a73f0d3264dcecdcc93165817c024;p=platform%2Fupstream%2Flibinput.git diff --git a/src/libinput.c b/src/libinput.c index 550ca94..5780a92 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -33,13 +33,7 @@ #include "libinput.h" #include "libinput-private.h" #include "evdev.h" -#include "udev-seat.h" - -enum libinput_event_class { - LIBINPUT_EVENT_CLASS_BASE, - LIBINPUT_EVENT_CLASS_SEAT, - LIBINPUT_EVENT_CLASS_DEVICE, -}; +#include "timer.h" struct libinput_source { libinput_source_dispatch_t dispatch; @@ -50,82 +44,102 @@ struct libinput_source { struct libinput_event { enum libinput_event_type type; - union libinput_event_target target; -}; - -struct libinput_event_added_seat { - struct libinput_event base; - struct libinput_seat *seat; -}; - -struct libinput_event_removed_seat { - struct libinput_event base; - struct libinput_seat *seat; -}; - -struct libinput_event_added_device { - struct libinput_event base; - struct libinput_device *device; -}; - -struct libinput_event_removed_device { - struct libinput_event base; struct libinput_device *device; }; -struct libinput_event_device_register_capability { +struct libinput_event_device_notify { struct libinput_event base; - enum libinput_device_capability capability; }; -struct libinput_event_device_unregister_capability { - struct libinput_event base; - enum libinput_device_capability capability; -}; - -struct libinput_event_keyboard_key { +struct libinput_event_keyboard { struct libinput_event base; uint32_t time; uint32_t key; - enum libinput_keyboard_key_state state; + uint32_t seat_key_count; + enum libinput_key_state state; }; -struct libinput_event_pointer_motion { +struct libinput_event_pointer { struct libinput_event base; uint32_t time; - li_fixed_t dx; - li_fixed_t dy; + double x; + double y; + uint32_t button; + uint32_t seat_button_count; + enum libinput_button_state state; + enum libinput_pointer_axis axis; + double value; }; -struct libinput_event_pointer_motion_absolute { +struct libinput_event_touch { struct libinput_event base; uint32_t time; - li_fixed_t x; - li_fixed_t y; + int32_t slot; + int32_t seat_slot; + double x; + double y; }; -struct libinput_event_pointer_button { - struct libinput_event base; - uint32_t time; - uint32_t button; - enum libinput_pointer_button_state state; -}; +static void +libinput_default_log_func(struct libinput *libinput, + enum libinput_log_priority priority, + const char *format, va_list args) +{ + const char *prefix; -struct libinput_event_pointer_axis { - struct libinput_event base; - uint32_t time; - enum libinput_pointer_axis axis; - li_fixed_t value; -}; + switch(priority) { + case LIBINPUT_LOG_PRIORITY_DEBUG: prefix = "debug"; break; + case LIBINPUT_LOG_PRIORITY_INFO: prefix = "info"; break; + case LIBINPUT_LOG_PRIORITY_ERROR: prefix = "error"; break; + default: prefix=""; break; + } -struct libinput_event_touch_touch { - struct libinput_event base; - uint32_t time; - uint32_t slot; - li_fixed_t x; - li_fixed_t y; - enum libinput_touch_type touch_type; -}; + fprintf(stderr, "libinput %s: ", prefix); + vfprintf(stderr, format, args); +} + +void +log_msg_va(struct libinput *libinput, + enum libinput_log_priority priority, + const char *format, + va_list args) +{ + if (libinput->log_handler && + libinput->log_priority <= priority) + libinput->log_handler(libinput, priority, format, args); +} + +void +log_msg(struct libinput *libinput, + enum libinput_log_priority priority, + const char *format, ...) +{ + va_list args; + + va_start(args, format); + log_msg_va(libinput, priority, format, args); + va_end(args); +} + +LIBINPUT_EXPORT void +libinput_log_set_priority(struct libinput *libinput, + enum libinput_log_priority priority) +{ + libinput->log_priority = priority; +} + +LIBINPUT_EXPORT enum libinput_log_priority +libinput_log_get_priority(const struct libinput *libinput) +{ + return libinput->log_priority; +} + +LIBINPUT_EXPORT void +libinput_log_set_handler(struct libinput *libinput, + libinput_log_handler log_handler) +{ + libinput->log_handler = log_handler; +} static void libinput_post_event(struct libinput *libinput, @@ -137,190 +151,288 @@ libinput_event_get_type(struct libinput_event *event) return event->type; } -LIBINPUT_EXPORT union libinput_event_target -libinput_event_get_target(struct libinput_event *event) +LIBINPUT_EXPORT struct libinput * +libinput_event_get_context(struct libinput_event *event) { - return event->target; + return event->device->seat->libinput; } -LIBINPUT_EXPORT struct libinput_seat * -libinput_event_added_seat_get_seat(struct libinput_event_added_seat *event) +LIBINPUT_EXPORT struct libinput_device * +libinput_event_get_device(struct libinput_event *event) { - return event->seat; + return event->device; } -LIBINPUT_EXPORT struct libinput_seat * -libinput_event_removed_seat_get_seat(struct libinput_event_removed_seat *event) +LIBINPUT_EXPORT struct libinput_event_pointer * +libinput_event_get_pointer_event(struct libinput_event *event) { - return event->seat; -} + switch (event->type) { + case LIBINPUT_EVENT_NONE: + abort(); /* not used as actual event type */ + case LIBINPUT_EVENT_DEVICE_ADDED: + case LIBINPUT_EVENT_DEVICE_REMOVED: + case LIBINPUT_EVENT_KEYBOARD_KEY: + break; + case LIBINPUT_EVENT_POINTER_MOTION: + case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: + case LIBINPUT_EVENT_POINTER_BUTTON: + case LIBINPUT_EVENT_POINTER_AXIS: + return (struct libinput_event_pointer *) event; + case LIBINPUT_EVENT_TOUCH_DOWN: + case LIBINPUT_EVENT_TOUCH_UP: + case LIBINPUT_EVENT_TOUCH_MOTION: + case LIBINPUT_EVENT_TOUCH_CANCEL: + case LIBINPUT_EVENT_TOUCH_FRAME: + break; + } -LIBINPUT_EXPORT struct libinput_device * -libinput_event_added_device_get_device( - struct libinput_event_added_device *event) -{ - return event->device; + return NULL; } -LIBINPUT_EXPORT struct libinput_device * -libinput_event_removed_device_get_device( - struct libinput_event_removed_device *event) +LIBINPUT_EXPORT struct libinput_event_keyboard * +libinput_event_get_keyboard_event(struct libinput_event *event) { - return event->device; + switch (event->type) { + case LIBINPUT_EVENT_NONE: + abort(); /* not used as actual event type */ + case LIBINPUT_EVENT_DEVICE_ADDED: + case LIBINPUT_EVENT_DEVICE_REMOVED: + break; + case LIBINPUT_EVENT_KEYBOARD_KEY: + return (struct libinput_event_keyboard *) event; + case LIBINPUT_EVENT_POINTER_MOTION: + case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: + case LIBINPUT_EVENT_POINTER_BUTTON: + case LIBINPUT_EVENT_POINTER_AXIS: + case LIBINPUT_EVENT_TOUCH_DOWN: + case LIBINPUT_EVENT_TOUCH_UP: + case LIBINPUT_EVENT_TOUCH_MOTION: + case LIBINPUT_EVENT_TOUCH_CANCEL: + case LIBINPUT_EVENT_TOUCH_FRAME: + break; + } + + return NULL; } -LIBINPUT_EXPORT enum libinput_device_capability -libinput_event_device_register_capability_get_capability( - struct libinput_event_device_register_capability *event) +LIBINPUT_EXPORT struct libinput_event_touch * +libinput_event_get_touch_event(struct libinput_event *event) { - return event->capability; + switch (event->type) { + case LIBINPUT_EVENT_NONE: + abort(); /* not used as actual event type */ + case LIBINPUT_EVENT_DEVICE_ADDED: + case LIBINPUT_EVENT_DEVICE_REMOVED: + case LIBINPUT_EVENT_KEYBOARD_KEY: + case LIBINPUT_EVENT_POINTER_MOTION: + case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: + case LIBINPUT_EVENT_POINTER_BUTTON: + case LIBINPUT_EVENT_POINTER_AXIS: + break; + case LIBINPUT_EVENT_TOUCH_DOWN: + case LIBINPUT_EVENT_TOUCH_UP: + case LIBINPUT_EVENT_TOUCH_MOTION: + case LIBINPUT_EVENT_TOUCH_CANCEL: + case LIBINPUT_EVENT_TOUCH_FRAME: + return (struct libinput_event_touch *) event; + } + + return NULL; } -LIBINPUT_EXPORT enum libinput_device_capability -libinput_event_device_unregister_capability_get_capability( - struct libinput_event_device_unregister_capability *event) +LIBINPUT_EXPORT struct libinput_event_device_notify * +libinput_event_get_device_notify_event(struct libinput_event *event) { - return event->capability; + switch (event->type) { + case LIBINPUT_EVENT_NONE: + abort(); /* not used as actual event type */ + case LIBINPUT_EVENT_DEVICE_ADDED: + case LIBINPUT_EVENT_DEVICE_REMOVED: + return (struct libinput_event_device_notify *) event; + case LIBINPUT_EVENT_KEYBOARD_KEY: + case LIBINPUT_EVENT_POINTER_MOTION: + case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: + case LIBINPUT_EVENT_POINTER_BUTTON: + case LIBINPUT_EVENT_POINTER_AXIS: + case LIBINPUT_EVENT_TOUCH_DOWN: + case LIBINPUT_EVENT_TOUCH_UP: + case LIBINPUT_EVENT_TOUCH_MOTION: + case LIBINPUT_EVENT_TOUCH_CANCEL: + case LIBINPUT_EVENT_TOUCH_FRAME: + break; + } + + return NULL; } LIBINPUT_EXPORT uint32_t -libinput_event_keyboard_key_get_time( - struct libinput_event_keyboard_key *event) +libinput_event_keyboard_get_time(struct libinput_event_keyboard *event) { return event->time; } LIBINPUT_EXPORT uint32_t -libinput_event_keyboard_key_get_key( - struct libinput_event_keyboard_key *event) +libinput_event_keyboard_get_key(struct libinput_event_keyboard *event) { return event->key; } -LIBINPUT_EXPORT enum libinput_keyboard_key_state -libinput_event_keyboard_key_get_state( - struct libinput_event_keyboard_key *event) +LIBINPUT_EXPORT enum libinput_key_state +libinput_event_keyboard_get_key_state(struct libinput_event_keyboard *event) { return event->state; } LIBINPUT_EXPORT uint32_t -libinput_event_pointer_motion_get_time( - struct libinput_event_pointer_motion *event) +libinput_event_keyboard_get_seat_key_count( + struct libinput_event_keyboard *event) +{ + return event->seat_key_count; +} + +LIBINPUT_EXPORT uint32_t +libinput_event_pointer_get_time(struct libinput_event_pointer *event) { return event->time; } -LIBINPUT_EXPORT li_fixed_t -libinput_event_pointer_motion_get_dx( - struct libinput_event_pointer_motion *event) +LIBINPUT_EXPORT double +libinput_event_pointer_get_dx(struct libinput_event_pointer *event) { - return event->dx; + return event->x; } -LIBINPUT_EXPORT li_fixed_t -libinput_event_pointer_motion_get_dy( - struct libinput_event_pointer_motion *event) +LIBINPUT_EXPORT double +libinput_event_pointer_get_dy(struct libinput_event_pointer *event) { - return event->dy; + return event->y; } -LIBINPUT_EXPORT uint32_t -libinput_event_pointer_motion_absolute_get_time( - struct libinput_event_pointer_motion_absolute *event) +LIBINPUT_EXPORT double +libinput_event_pointer_get_absolute_x(struct libinput_event_pointer *event) { - return event->time; + struct evdev_device *device = + (struct evdev_device *) event->base.device; + + return evdev_convert_to_mm(device->abs.absinfo_x, event->x); } -LIBINPUT_EXPORT li_fixed_t -libinput_event_pointer_motion_absolute_get_x( - struct libinput_event_pointer_motion_absolute *event) +LIBINPUT_EXPORT double +libinput_event_pointer_get_absolute_y(struct libinput_event_pointer *event) { - return event->x; + struct evdev_device *device = + (struct evdev_device *) event->base.device; + + return evdev_convert_to_mm(device->abs.absinfo_y, event->y); } -LIBINPUT_EXPORT li_fixed_t -libinput_event_pointer_motion_absolute_get_y( - struct libinput_event_pointer_motion_absolute *event) +LIBINPUT_EXPORT double +libinput_event_pointer_get_absolute_x_transformed( + struct libinput_event_pointer *event, + uint32_t width) { - return event->y; + struct evdev_device *device = + (struct evdev_device *) event->base.device; + + return evdev_device_transform_x(device, event->x, width); } -LIBINPUT_EXPORT uint32_t -libinput_event_pointer_button_get_time( - struct libinput_event_pointer_button *event) +LIBINPUT_EXPORT double +libinput_event_pointer_get_absolute_y_transformed( + struct libinput_event_pointer *event, + uint32_t height) { - return event->time; + struct evdev_device *device = + (struct evdev_device *) event->base.device; + + return evdev_device_transform_y(device, event->y, height); } LIBINPUT_EXPORT uint32_t -libinput_event_pointer_button_get_button( - struct libinput_event_pointer_button *event) +libinput_event_pointer_get_button(struct libinput_event_pointer *event) { return event->button; } -LIBINPUT_EXPORT enum libinput_pointer_button_state -libinput_event_pointer_button_get_state( - struct libinput_event_pointer_button *event) +LIBINPUT_EXPORT enum libinput_button_state +libinput_event_pointer_get_button_state(struct libinput_event_pointer *event) { return event->state; } LIBINPUT_EXPORT uint32_t -libinput_event_pointer_axis_get_time( - struct libinput_event_pointer_axis *event) +libinput_event_pointer_get_seat_button_count( + struct libinput_event_pointer *event) { - return event->time; + return event->seat_button_count; } LIBINPUT_EXPORT enum libinput_pointer_axis -libinput_event_pointer_axis_get_axis( - struct libinput_event_pointer_axis *event) +libinput_event_pointer_get_axis(struct libinput_event_pointer *event) { return event->axis; } -LIBINPUT_EXPORT li_fixed_t -libinput_event_pointer_axis_get_value( - struct libinput_event_pointer_axis *event) +LIBINPUT_EXPORT double +libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event) { return event->value; } LIBINPUT_EXPORT uint32_t -libinput_event_touch_touch_get_time( - struct libinput_event_touch_touch *event) +libinput_event_touch_get_time(struct libinput_event_touch *event) { return event->time; } -LIBINPUT_EXPORT uint32_t -libinput_event_touch_touch_get_slot( - struct libinput_event_touch_touch *event) +LIBINPUT_EXPORT int32_t +libinput_event_touch_get_slot(struct libinput_event_touch *event) { return event->slot; } -LIBINPUT_EXPORT li_fixed_t -libinput_event_touch_touch_get_x( - struct libinput_event_touch_touch *event) +LIBINPUT_EXPORT int32_t +libinput_event_touch_get_seat_slot(struct libinput_event_touch *event) { - return event->x; + return event->seat_slot; } -LIBINPUT_EXPORT li_fixed_t -libinput_event_touch_touch_get_y( - struct libinput_event_touch_touch *event) +LIBINPUT_EXPORT double +libinput_event_touch_get_x(struct libinput_event_touch *event) { - return event->y; + struct evdev_device *device = + (struct evdev_device *) event->base.device; + + return evdev_convert_to_mm(device->abs.absinfo_x, event->x); } -LIBINPUT_EXPORT enum libinput_touch_type -libinput_event_touch_touch_get_touch_type( - struct libinput_event_touch_touch *event) +LIBINPUT_EXPORT double +libinput_event_touch_get_x_transformed(struct libinput_event_touch *event, + uint32_t width) { - return event->touch_type; + struct evdev_device *device = + (struct evdev_device *) event->base.device; + + return evdev_device_transform_x(device, event->x, width); +} + +LIBINPUT_EXPORT double +libinput_event_touch_get_y_transformed(struct libinput_event_touch *event, + uint32_t height) +{ + struct evdev_device *device = + (struct evdev_device *) event->base.device; + + return evdev_device_transform_y(device, event->y, height); +} + +LIBINPUT_EXPORT double +libinput_event_touch_get_y(struct libinput_event_touch *event) +{ + struct evdev_device *device = + (struct evdev_device *) event->base.device; + + return evdev_convert_to_mm(device->abs.absinfo_y, event->y); } struct libinput_source * @@ -345,7 +457,6 @@ libinput_add_fd(struct libinput *libinput, ep.data.ptr = source; if (epoll_ctl(libinput->epoll_fd, EPOLL_CTL_ADD, fd, &ep) < 0) { - close(source->fd); free(source); return NULL; } @@ -358,7 +469,6 @@ libinput_remove_source(struct libinput *libinput, struct libinput_source *source) { epoll_ctl(libinput->epoll_fd, EPOLL_CTL_DEL, source->fd, NULL); - close(source->fd); source->fd = -1; list_insert(&libinput->source_destroy_list, &source->link); } @@ -366,6 +476,7 @@ libinput_remove_source(struct libinput *libinput, int libinput_init(struct libinput *libinput, const struct libinput_interface *interface, + const struct libinput_interface_backend *interface_backend, void *user_data) { libinput->epoll_fd = epoll_create1(EPOLL_CLOEXEC);; @@ -379,11 +490,21 @@ libinput_init(struct libinput *libinput, return -1; } + libinput->log_handler = libinput_default_log_func; + libinput->log_priority = LIBINPUT_LOG_PRIORITY_ERROR; libinput->interface = interface; + libinput->interface_backend = interface_backend; libinput->user_data = user_data; + libinput->refcount = 1; list_init(&libinput->source_destroy_list); list_init(&libinput->seat_list); + if (libinput_timer_subsys_init(libinput) != 0) { + free(libinput->events); + close(libinput->epoll_fd); + return -1; + } + return 0; } @@ -393,15 +514,45 @@ libinput_device_destroy(struct libinput_device *device); static void libinput_seat_destroy(struct libinput_seat *seat); -LIBINPUT_EXPORT void -libinput_destroy(struct libinput *libinput) +static void +libinput_drop_destroyed_sources(struct libinput *libinput) +{ + struct libinput_source *source, *next; + + list_for_each_safe(source, next, &libinput->source_destroy_list, link) + free(source); + list_init(&libinput->source_destroy_list); +} + +LIBINPUT_EXPORT struct libinput * +libinput_ref(struct libinput *libinput) +{ + libinput->refcount++; + return libinput; +} + +LIBINPUT_EXPORT struct libinput * +libinput_unref(struct libinput *libinput) { struct libinput_event *event; struct libinput_device *device, *next_device; struct libinput_seat *seat, *next_seat; + if (libinput == NULL) + return NULL; + + assert(libinput->refcount > 0); + libinput->refcount--; + if (libinput->refcount > 0) + return libinput; + + libinput_suspend(libinput); + + libinput->interface_backend->destroy(libinput); + while ((event = libinput_get_event(libinput))) libinput_event_destroy(event); + free(libinput->events); list_for_each_safe(seat, next_seat, &libinput->seat_list, link) { @@ -413,33 +564,12 @@ libinput_destroy(struct libinput *libinput) libinput_seat_destroy(seat); } + libinput_timer_subsys_destroy(libinput); + libinput_drop_destroyed_sources(libinput); close(libinput->epoll_fd); free(libinput); -} - -static enum libinput_event_class -libinput_event_get_class(struct libinput_event *event) -{ - switch (event->type) { - case LIBINPUT_EVENT_ADDED_SEAT: - case LIBINPUT_EVENT_REMOVED_SEAT: - case LIBINPUT_EVENT_ADDED_DEVICE: - case LIBINPUT_EVENT_REMOVED_DEVICE: - return LIBINPUT_EVENT_CLASS_BASE; - - case LIBINPUT_EVENT_DEVICE_REGISTER_CAPABILITY: - case LIBINPUT_EVENT_DEVICE_UNREGISTER_CAPABILITY: - case LIBINPUT_EVENT_KEYBOARD_KEY: - case LIBINPUT_EVENT_POINTER_MOTION: - case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: - case LIBINPUT_EVENT_POINTER_BUTTON: - case LIBINPUT_EVENT_POINTER_AXIS: - case LIBINPUT_EVENT_TOUCH_TOUCH: - return LIBINPUT_EVENT_CLASS_DEVICE; - } - /* We should never end up here. */ - abort(); + return NULL; } LIBINPUT_EXPORT void @@ -448,16 +578,8 @@ libinput_event_destroy(struct libinput_event *event) if (event == NULL) return; - switch (libinput_event_get_class(event)) { - case LIBINPUT_EVENT_CLASS_BASE: - break; - case LIBINPUT_EVENT_CLASS_SEAT: - libinput_seat_unref(event->target.seat); - break; - case LIBINPUT_EVENT_CLASS_DEVICE: - libinput_device_unref(event->target.device); - break; - } + if (event->device) + libinput_device_unref(event->device); free(event); } @@ -480,34 +602,46 @@ close_restricted(struct libinput *libinput, int fd) void libinput_seat_init(struct libinput_seat *seat, struct libinput *libinput, - const char *name) + const char *physical_name, + const char *logical_name, + libinput_seat_destroy_func destroy) { seat->refcount = 1; seat->libinput = libinput; - seat->name = strdup(name); + seat->physical_name = strdup(physical_name); + seat->logical_name = strdup(logical_name); + seat->destroy = destroy; list_init(&seat->devices_list); + list_insert(&libinput->seat_list, &seat->link); } -LIBINPUT_EXPORT void +LIBINPUT_EXPORT struct libinput_seat * libinput_seat_ref(struct libinput_seat *seat) { seat->refcount++; + return seat; } static void libinput_seat_destroy(struct libinput_seat *seat) { - free(seat->name); - udev_seat_destroy((struct udev_seat *) seat); + list_remove(&seat->link); + free(seat->logical_name); + free(seat->physical_name); + seat->destroy(seat); } -LIBINPUT_EXPORT void +LIBINPUT_EXPORT struct libinput_seat * libinput_seat_unref(struct libinput_seat *seat) { assert(seat->refcount > 0); seat->refcount--; - if (seat->refcount == 0) + if (seat->refcount == 0) { libinput_seat_destroy(seat); + return NULL; + } else { + return seat; + } } LIBINPUT_EXPORT void @@ -523,9 +657,15 @@ libinput_seat_get_user_data(struct libinput_seat *seat) } LIBINPUT_EXPORT const char * -libinput_seat_get_name(struct libinput_seat *seat) +libinput_seat_get_physical_name(struct libinput_seat *seat) +{ + return seat->physical_name; +} + +LIBINPUT_EXPORT const char * +libinput_seat_get_logical_name(struct libinput_seat *seat) { - return seat->name; + return seat->logical_name; } void @@ -536,10 +676,11 @@ libinput_device_init(struct libinput_device *device, device->refcount = 1; } -LIBINPUT_EXPORT void +LIBINPUT_EXPORT struct libinput_device * libinput_device_ref(struct libinput_device *device) { device->refcount++; + return device; } static void @@ -548,13 +689,17 @@ libinput_device_destroy(struct libinput_device *device) evdev_device_destroy((struct evdev_device *) device); } -LIBINPUT_EXPORT void +LIBINPUT_EXPORT struct libinput_device * libinput_device_unref(struct libinput_device *device) { assert(device->refcount > 0); device->refcount--; - if (device->refcount == 0) + if (device->refcount == 0) { libinput_device_destroy(device); + return NULL; + } else { + return device; + } } LIBINPUT_EXPORT int @@ -566,7 +711,7 @@ libinput_get_fd(struct libinput *libinput) LIBINPUT_EXPORT int libinput_dispatch(struct libinput *libinput) { - struct libinput_source *source, *next; + struct libinput_source *source; struct epoll_event ep[32]; int i, count; @@ -582,29 +727,69 @@ libinput_dispatch(struct libinput *libinput) source->dispatch(source->user_data); } - list_for_each_safe(source, next, &libinput->source_destroy_list, link) - free(source); - list_init(&libinput->source_destroy_list); + libinput_drop_destroyed_sources(libinput); + + return 0; +} + +static uint32_t +update_seat_key_count(struct libinput_seat *seat, + int32_t key, + enum libinput_key_state state) +{ + assert(key >= 0 && key <= KEY_MAX); + + switch (state) { + case LIBINPUT_KEY_STATE_PRESSED: + return ++seat->button_count[key]; + case LIBINPUT_KEY_STATE_RELEASED: + /* We might not have received the first PRESSED event. */ + if (seat->button_count[key] == 0) + return 0; + + return --seat->button_count[key]; + } + + return 0; +} + +static uint32_t +update_seat_button_count(struct libinput_seat *seat, + int32_t button, + enum libinput_button_state state) +{ + assert(button >= 0 && button <= KEY_MAX); + + switch (state) { + case LIBINPUT_BUTTON_STATE_PRESSED: + return ++seat->button_count[button]; + case LIBINPUT_BUTTON_STATE_RELEASED: + /* We might not have received the first PRESSED event. */ + if (seat->button_count[button] == 0) + return 0; + + return --seat->button_count[button]; + } return 0; } static void init_event_base(struct libinput_event *event, - enum libinput_event_type type, - union libinput_event_target target) + struct libinput_device *device, + enum libinput_event_type type) { event->type = type; - event->target = target; + event->device = device; } static void -post_base_event(struct libinput *libinput, +post_base_event(struct libinput_device *device, enum libinput_event_type type, struct libinput_event *event) { - init_event_base(event, type, - (union libinput_event_target) { .libinput = libinput }); + struct libinput *libinput = device->seat->libinput; + init_event_base(event, device, type); libinput_post_event(libinput, event); } @@ -613,133 +798,58 @@ post_device_event(struct libinput_device *device, enum libinput_event_type type, struct libinput_event *event) { - init_event_base(event, type, - (union libinput_event_target) { .device = device }); + init_event_base(event, device, type); libinput_post_event(device->seat->libinput, event); } void -notify_added_seat(struct libinput_seat *seat) -{ - struct libinput_event_added_seat *added_seat_event; - - added_seat_event = malloc(sizeof *added_seat_event); - if (!added_seat_event) - return; - - *added_seat_event = (struct libinput_event_added_seat) { - .seat = seat, - }; - - post_base_event(seat->libinput, - LIBINPUT_EVENT_ADDED_SEAT, - &added_seat_event->base); -} - -void -notify_removed_seat(struct libinput_seat *seat) -{ - struct libinput_event_removed_seat *removed_seat_event; - - removed_seat_event = malloc(sizeof *removed_seat_event); - if (!removed_seat_event) - return; - - *removed_seat_event = (struct libinput_event_removed_seat) { - .seat = seat, - }; - - post_base_event(seat->libinput, - LIBINPUT_EVENT_REMOVED_SEAT, - &removed_seat_event->base); -} - -void notify_added_device(struct libinput_device *device) { - struct libinput_event_added_device *added_device_event; + struct libinput_event_device_notify *added_device_event; - added_device_event = malloc(sizeof *added_device_event); + added_device_event = zalloc(sizeof *added_device_event); if (!added_device_event) return; - *added_device_event = (struct libinput_event_added_device) { - .device = device, - }; - - post_base_event(device->seat->libinput, - LIBINPUT_EVENT_ADDED_DEVICE, + post_base_event(device, + LIBINPUT_EVENT_DEVICE_ADDED, &added_device_event->base); } void notify_removed_device(struct libinput_device *device) { - struct libinput_event_removed_device *removed_device_event; + struct libinput_event_device_notify *removed_device_event; - removed_device_event = malloc(sizeof *removed_device_event); + removed_device_event = zalloc(sizeof *removed_device_event); if (!removed_device_event) return; - *removed_device_event = (struct libinput_event_removed_device) { - .device = device, - }; - - post_base_event(device->seat->libinput, - LIBINPUT_EVENT_REMOVED_DEVICE, + post_base_event(device, + LIBINPUT_EVENT_DEVICE_REMOVED, &removed_device_event->base); } void -device_register_capability(struct libinput_device *device, - enum libinput_device_capability capability) -{ - struct libinput_event_device_register_capability *capability_event; - - capability_event = malloc(sizeof *capability_event); - - *capability_event = (struct libinput_event_device_register_capability) { - .capability = capability, - }; - - post_device_event(device, - LIBINPUT_EVENT_DEVICE_REGISTER_CAPABILITY, - &capability_event->base); -} - -void -device_unregister_capability(struct libinput_device *device, - enum libinput_device_capability capability) -{ - struct libinput_event_device_unregister_capability *capability_event; - - capability_event = malloc(sizeof *capability_event); - - *capability_event = (struct libinput_event_device_unregister_capability) { - .capability = capability, - }; - - post_device_event(device, - LIBINPUT_EVENT_DEVICE_UNREGISTER_CAPABILITY, - &capability_event->base); -} - -void keyboard_notify_key(struct libinput_device *device, uint32_t time, uint32_t key, - enum libinput_keyboard_key_state state) + enum libinput_key_state state) { - struct libinput_event_keyboard_key *key_event; + struct libinput_event_keyboard *key_event; + uint32_t seat_key_count; - key_event = malloc(sizeof *key_event); + key_event = zalloc(sizeof *key_event); if (!key_event) return; - *key_event = (struct libinput_event_keyboard_key) { + seat_key_count = update_seat_key_count(device->seat, key, state); + + *key_event = (struct libinput_event_keyboard) { .time = time, .key = key, .state = state, + .seat_key_count = seat_key_count, }; post_device_event(device, @@ -750,19 +860,19 @@ keyboard_notify_key(struct libinput_device *device, void pointer_notify_motion(struct libinput_device *device, uint32_t time, - li_fixed_t dx, - li_fixed_t dy) + double dx, + double dy) { - struct libinput_event_pointer_motion *motion_event; + struct libinput_event_pointer *motion_event; - motion_event = malloc(sizeof *motion_event); + motion_event = zalloc(sizeof *motion_event); if (!motion_event) return; - *motion_event = (struct libinput_event_pointer_motion) { + *motion_event = (struct libinput_event_pointer) { .time = time, - .dx = dx, - .dy = dy, + .x = dx, + .y = dy, }; post_device_event(device, @@ -773,16 +883,16 @@ pointer_notify_motion(struct libinput_device *device, void pointer_notify_motion_absolute(struct libinput_device *device, uint32_t time, - li_fixed_t x, - li_fixed_t y) + double x, + double y) { - struct libinput_event_pointer_motion_absolute *motion_absolute_event; + struct libinput_event_pointer *motion_absolute_event; - motion_absolute_event = malloc(sizeof *motion_absolute_event); + motion_absolute_event = zalloc(sizeof *motion_absolute_event); if (!motion_absolute_event) return; - *motion_absolute_event = (struct libinput_event_pointer_motion_absolute) { + *motion_absolute_event = (struct libinput_event_pointer) { .time = time, .x = x, .y = y, @@ -797,18 +907,24 @@ void pointer_notify_button(struct libinput_device *device, uint32_t time, int32_t button, - enum libinput_pointer_button_state state) + enum libinput_button_state state) { - struct libinput_event_pointer_button *button_event; + struct libinput_event_pointer *button_event; + int32_t seat_button_count; - button_event = malloc(sizeof *button_event); + button_event = zalloc(sizeof *button_event); if (!button_event) return; - *button_event = (struct libinput_event_pointer_button) { + seat_button_count = update_seat_button_count(device->seat, + button, + state); + + *button_event = (struct libinput_event_pointer) { .time = time, .button = button, .state = state, + .seat_button_count = seat_button_count, }; post_device_event(device, @@ -820,15 +936,15 @@ void pointer_notify_axis(struct libinput_device *device, uint32_t time, enum libinput_pointer_axis axis, - li_fixed_t value) + double value) { - struct libinput_event_pointer_axis *axis_event; + struct libinput_event_pointer *axis_event; - axis_event = malloc(sizeof *axis_event); + axis_event = zalloc(sizeof *axis_event); if (!axis_event) return; - *axis_event = (struct libinput_event_pointer_axis) { + *axis_event = (struct libinput_event_pointer) { .time = time, .axis = axis, .value = value, @@ -840,29 +956,98 @@ pointer_notify_axis(struct libinput_device *device, } void -touch_notify_touch(struct libinput_device *device, - uint32_t time, - int32_t slot, - li_fixed_t x, - li_fixed_t y, - enum libinput_touch_type touch_type) +touch_notify_touch_down(struct libinput_device *device, + uint32_t time, + int32_t slot, + int32_t seat_slot, + double x, + double y) { - struct libinput_event_touch_touch *touch_event; + struct libinput_event_touch *touch_event; - touch_event = malloc(sizeof *touch_event); + touch_event = zalloc(sizeof *touch_event); if (!touch_event) return; - *touch_event = (struct libinput_event_touch_touch) { + *touch_event = (struct libinput_event_touch) { .time = time, .slot = slot, + .seat_slot = seat_slot, .x = x, .y = y, - .touch_type = touch_type, }; post_device_event(device, - LIBINPUT_EVENT_TOUCH_TOUCH, + LIBINPUT_EVENT_TOUCH_DOWN, + &touch_event->base); +} + +void +touch_notify_touch_motion(struct libinput_device *device, + uint32_t time, + int32_t slot, + int32_t seat_slot, + double x, + double y) +{ + struct libinput_event_touch *touch_event; + + touch_event = zalloc(sizeof *touch_event); + if (!touch_event) + return; + + *touch_event = (struct libinput_event_touch) { + .time = time, + .slot = slot, + .seat_slot = seat_slot, + .x = x, + .y = y, + }; + + post_device_event(device, + LIBINPUT_EVENT_TOUCH_MOTION, + &touch_event->base); +} + +void +touch_notify_touch_up(struct libinput_device *device, + uint32_t time, + int32_t slot, + int32_t seat_slot) +{ + struct libinput_event_touch *touch_event; + + touch_event = zalloc(sizeof *touch_event); + if (!touch_event) + return; + + *touch_event = (struct libinput_event_touch) { + .time = time, + .slot = slot, + .seat_slot = seat_slot, + }; + + post_device_event(device, + LIBINPUT_EVENT_TOUCH_UP, + &touch_event->base); +} + +void +touch_notify_frame(struct libinput_device *device, + uint32_t time) +{ + struct libinput_event_touch *touch_event; + + touch_event = zalloc(sizeof *touch_event); + if (!touch_event) + return; + + *touch_event = (struct libinput_event_touch) { + .time = time, + }; + + post_device_event(device, + LIBINPUT_EVENT_TOUCH_FRAME, &touch_event->base); } @@ -902,16 +1087,8 @@ libinput_post_event(struct libinput *libinput, libinput->events_len = events_len; } - switch (libinput_event_get_class(event)) { - case LIBINPUT_EVENT_CLASS_BASE: - break; - case LIBINPUT_EVENT_CLASS_SEAT: - libinput_seat_ref(event->target.seat); - break; - case LIBINPUT_EVENT_CLASS_DEVICE: - libinput_device_ref(event->target.device); - break; - } + if (event->device) + libinput_device_ref(event->device); libinput->events_count = events_count; events[libinput->events_in] = event; @@ -934,6 +1111,18 @@ libinput_get_event(struct libinput *libinput) return event; } +LIBINPUT_EXPORT enum libinput_event_type +libinput_next_event_type(struct libinput *libinput) +{ + struct libinput_event *event; + + if (libinput->events_count == 0) + return LIBINPUT_EVENT_NONE; + + event = libinput->events[libinput->events_out]; + return event->type; +} + LIBINPUT_EXPORT void * libinput_get_user_data(struct libinput *libinput) { @@ -943,13 +1132,13 @@ libinput_get_user_data(struct libinput *libinput) LIBINPUT_EXPORT int libinput_resume(struct libinput *libinput) { - return udev_input_enable((struct udev_input *) libinput); + return libinput->interface_backend->resume(libinput); } LIBINPUT_EXPORT void libinput_suspend(struct libinput *libinput) { - udev_input_disable((struct udev_input *) libinput); + libinput->interface_backend->suspend(libinput); } LIBINPUT_EXPORT void @@ -971,6 +1160,24 @@ libinput_device_get_sysname(struct libinput_device *device) } LIBINPUT_EXPORT const char * +libinput_device_get_name(struct libinput_device *device) +{ + return evdev_device_get_name((struct evdev_device *) device); +} + +LIBINPUT_EXPORT unsigned int +libinput_device_get_id_product(struct libinput_device *device) +{ + return evdev_device_get_id_product((struct evdev_device *) device); +} + +LIBINPUT_EXPORT unsigned int +libinput_device_get_id_vendor(struct libinput_device *device) +{ + return evdev_device_get_id_vendor((struct evdev_device *) device); +} + +LIBINPUT_EXPORT const char * libinput_device_get_output_name(struct libinput_device *device) { return evdev_device_get_output((struct evdev_device *) device); @@ -1012,3 +1219,285 @@ libinput_device_has_capability(struct libinput_device *device, return evdev_device_has_capability((struct evdev_device *) device, capability); } + +LIBINPUT_EXPORT int +libinput_device_get_size(struct libinput_device *device, + double *width, + double *height) +{ + return evdev_device_get_size((struct evdev_device *)device, + width, + height); +} + +LIBINPUT_EXPORT struct libinput_event * +libinput_event_device_notify_get_base_event(struct libinput_event_device_notify *event) +{ + return &event->base; +} + +LIBINPUT_EXPORT struct libinput_event * +libinput_event_keyboard_get_base_event(struct libinput_event_keyboard *event) +{ + return &event->base; +} + +LIBINPUT_EXPORT struct libinput_event * +libinput_event_pointer_get_base_event(struct libinput_event_pointer *event) +{ + return &event->base; +} + +LIBINPUT_EXPORT struct libinput_event * +libinput_event_touch_get_base_event(struct libinput_event_touch *event) +{ + return &event->base; +} + +LIBINPUT_EXPORT const char * +libinput_config_status_to_str(enum libinput_config_status status) +{ + const char *str = NULL; + + switch(status) { + case LIBINPUT_CONFIG_STATUS_SUCCESS: + str = "Success"; + break; + case LIBINPUT_CONFIG_STATUS_UNSUPPORTED: + str = "Unsupported configuration option"; + break; + case LIBINPUT_CONFIG_STATUS_INVALID: + str = "Invalid argument range"; + break; + } + + return str; +} + +LIBINPUT_EXPORT int +libinput_device_config_tap_get_finger_count(struct libinput_device *device) +{ + return device->config.tap ? device->config.tap->count(device) : 0; +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_tap_set_enabled(struct libinput_device *device, + enum libinput_config_tap_state enable) +{ + if (enable != LIBINPUT_CONFIG_TAP_ENABLED && + enable != LIBINPUT_CONFIG_TAP_DISABLED) + return LIBINPUT_CONFIG_STATUS_INVALID; + + if (enable && + libinput_device_config_tap_get_finger_count(device) == 0) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + return device->config.tap->set_enabled(device, enable); +} + +LIBINPUT_EXPORT enum libinput_config_tap_state +libinput_device_config_tap_get_enabled(struct libinput_device *device) +{ + if (libinput_device_config_tap_get_finger_count(device) == 0) + return LIBINPUT_CONFIG_TAP_DISABLED; + + return device->config.tap->get_enabled(device); +} + +LIBINPUT_EXPORT enum libinput_config_tap_state +libinput_device_config_tap_get_default_enabled(struct libinput_device *device) +{ + if (libinput_device_config_tap_get_finger_count(device) == 0) + return LIBINPUT_CONFIG_TAP_DISABLED; + + return device->config.tap->get_default(device); +} + +LIBINPUT_EXPORT int +libinput_device_config_calibration_has_matrix(struct libinput_device *device) +{ + return device->config.calibration ? + device->config.calibration->has_matrix(device) : 0; +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_calibration_set_matrix(struct libinput_device *device, + const float matrix[6]) +{ + if (!libinput_device_config_calibration_has_matrix(device)) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + return device->config.calibration->set_matrix(device, matrix); +} + +LIBINPUT_EXPORT int +libinput_device_config_calibration_get_matrix(struct libinput_device *device, + float matrix[6]) +{ + if (!libinput_device_config_calibration_has_matrix(device)) + return 0; + + return device->config.calibration->get_matrix(device, matrix); +} + +LIBINPUT_EXPORT int +libinput_device_config_calibration_get_default_matrix(struct libinput_device *device, + float matrix[6]) +{ + if (!libinput_device_config_calibration_has_matrix(device)) + return 0; + + return device->config.calibration->get_default_matrix(device, matrix); +} + +LIBINPUT_EXPORT uint32_t +libinput_device_config_send_events_get_modes(struct libinput_device *device) +{ + uint32_t modes = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; + + if (device->config.sendevents) + modes |= device->config.sendevents->get_modes(device); + + return modes; +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_send_events_set_mode(struct libinput_device *device, + enum libinput_config_send_events_mode mode) +{ + if ((libinput_device_config_send_events_get_modes(device) & mode) == 0) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + if (device->config.sendevents) + return device->config.sendevents->set_mode(device, mode); + else /* mode must be _ENABLED to get here */ + return LIBINPUT_CONFIG_STATUS_SUCCESS; +} + +LIBINPUT_EXPORT enum libinput_config_send_events_mode +libinput_device_config_send_events_get_mode(struct libinput_device *device) +{ + if (device->config.sendevents) + return device->config.sendevents->get_mode(device); + else + return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; +} + +LIBINPUT_EXPORT enum libinput_config_send_events_mode +libinput_device_config_send_events_get_default_mode(struct libinput_device *device) +{ + return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; +} + + +LIBINPUT_EXPORT int +libinput_device_config_accel_is_available(struct libinput_device *device) +{ + return device->config.accel ? + device->config.accel->available(device) : 0; +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_accel_set_speed(struct libinput_device *device, + double speed) +{ + if (!libinput_device_config_accel_is_available(device)) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + if (speed < -1.0 || speed > 1.0) + return LIBINPUT_CONFIG_STATUS_INVALID; + + return device->config.accel->set_speed(device, speed); +} + +LIBINPUT_EXPORT double +libinput_device_config_accel_get_speed(struct libinput_device *device) +{ + if (!libinput_device_config_accel_is_available(device)) + return 0; + + return device->config.accel->get_speed(device); +} + +LIBINPUT_EXPORT double +libinput_device_config_accel_get_default_speed(struct libinput_device *device) +{ + if (!libinput_device_config_accel_is_available(device)) + return 0; + + return device->config.accel->get_default_speed(device); +} + +LIBINPUT_EXPORT int +libinput_device_config_scroll_has_natural_scroll(struct libinput_device *device) +{ + if (!device->config.natural_scroll) + return 0; + + return device->config.natural_scroll->has(device); +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_scroll_set_natural_scroll_enabled(struct libinput_device *device, + int enabled) +{ + if (!libinput_device_config_scroll_has_natural_scroll(device)) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + return device->config.natural_scroll->set_enabled(device, enabled); +} + +LIBINPUT_EXPORT int +libinput_device_config_scroll_get_natural_scroll_enabled(struct libinput_device *device) +{ + if (!device->config.natural_scroll) + return 0; + + return device->config.natural_scroll->get_enabled(device); +} + +LIBINPUT_EXPORT int +libinput_device_config_scroll_get_default_natural_scroll_enabled(struct libinput_device *device) +{ + if (!device->config.natural_scroll) + return 0; + + return device->config.natural_scroll->get_default_enabled(device); +} + +LIBINPUT_EXPORT int +libinput_device_config_buttons_has_left_handed(struct libinput_device *device) +{ + if (!device->config.left_handed) + return 0; + + return device->config.left_handed->has(device); +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_buttons_set_left_handed(struct libinput_device *device, + int left_handed) +{ + if (!libinput_device_config_buttons_has_left_handed(device)) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + return device->config.left_handed->set(device, left_handed); +} + +LIBINPUT_EXPORT int +libinput_device_config_buttons_get_left_handed(struct libinput_device *device) +{ + if (!libinput_device_config_buttons_has_left_handed(device)) + return 0; + + return device->config.left_handed->get(device); +} + +LIBINPUT_EXPORT int +libinput_device_config_buttons_get_default_left_handed(struct libinput_device *device) +{ + if (!libinput_device_config_buttons_has_left_handed(device)) + return 0; + + return device->config.left_handed->get_default(device); +}