From: Jonas Ådahl Date: Sat, 23 Nov 2013 12:04:32 +0000 (+0100) Subject: Port udev-seat to be used in libinput X-Git-Tag: 0.1.0~161 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=56f7ddec82547a78010786b1d20ec00853028469;p=platform%2Fupstream%2Flibinput.git Port udev-seat to be used in libinput This patch ports udev-seat from weston to libinput, including adapting libinput internals and API to provide seat and device discovery. The public API is extended with device discovery, object reference, a seat object. As libinput takes care of creating and destroying its objects user data getter/setter is added in order to make it possible for the client to directly associate an object application side with an object library side. Device discovery API is made up of the 'seat added', 'seat removed', 'device added' and 'device removed' events. The seat added/removed events contains a pointer to a libinput_seat struct, while the device added/removed events contains a pointer to a libinput_device event. The objects are reference counted with libinput holding one reference by default. The application can increase the reference count with libinput_seat_ref() and libinput_device_ref() and decrease the reference count with libinput_seat_unref() and libinput_device_unref(). The basic event struct is changed to have a 'target' union parameter that can be either a libinput, libinput_seat or libinput_device struct pointer. There is one known problem with the current API that is the potentially racy initialization. The problem is when a device is both discovered and lost during initial dispatchig, causing libinput to first queue a 'added' message, creating the device with default reference count 1, then before going back to the application queuing a 'removed' message, while at same time decreasing reference count of the device to 0, causing it o be destroyed. The queue will at this state contain two messages with pointers to free:ed memory. Signed-off-by: Jonas Ådahl --- diff --git a/src/Makefile.am b/src/Makefile.am index c1e3149..ffda1e0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,7 +12,9 @@ libinput_la_SOURCES = \ evdev.h \ evdev-touchpad.c \ filter.c \ - filter.h + filter.h \ + udev-seat.c \ + udev-seat.h libinput_la_LIBADD = $(MTDEV_LIBS) libinput_la_CFLAGS = $(MTDEV_CFLAGS) \ diff --git a/src/evdev-touchpad.c b/src/evdev-touchpad.c index a673a7b..778dcf9 100644 --- a/src/evdev-touchpad.c +++ b/src/evdev-touchpad.c @@ -709,7 +709,7 @@ touchpad_destroy(struct evdev_dispatch *dispatch) { struct touchpad_dispatch *touchpad = (struct touchpad_dispatch *) dispatch; - struct libinput *libinput = touchpad->device->base.libinput; + struct libinput *libinput = touchpad->device->base.seat->libinput; touchpad->filter->interface->destroy(touchpad->filter); libinput_remove_source(libinput, touchpad->fsm.timer.source); @@ -798,7 +798,7 @@ touchpad_init(struct touchpad_dispatch *touchpad, touchpad->fsm.timer.fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); touchpad->fsm.timer.source = - libinput_add_fd(touchpad->device->base.libinput, + libinput_add_fd(touchpad->device->base.seat->libinput, touchpad->fsm.timer.fd, fsm_timeout_handler, touchpad); diff --git a/src/evdev.c b/src/evdev.c index 55d8a15..81539c8 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -227,7 +227,7 @@ evdev_process_touch(struct evdev_device *device, struct input_event *e, uint32_t time) { - struct libinput *libinput = device->base.libinput; + struct libinput *libinput = device->base.seat->libinput; int screen_width; int screen_height; @@ -272,7 +272,7 @@ static inline void evdev_process_absolute_motion(struct evdev_device *device, struct input_event *e) { - struct libinput *libinput = device->base.libinput; + struct libinput *libinput = device->base.seat->libinput; int screen_width; int screen_height; @@ -434,6 +434,7 @@ static void evdev_device_dispatch(void *data) { struct evdev_device *device = data; + struct libinput *libinput = device->base.seat->libinput; int fd = device->fd; struct input_event ev[32]; int len; @@ -451,7 +452,7 @@ evdev_device_dispatch(void *data) if (len < 0 || len % sizeof ev[0] != 0) { if (len < 0 && errno != EAGAIN && errno != EINTR) { - libinput_remove_source(device->base.libinput, + libinput_remove_source(libinput, device->source); device->source = NULL; } @@ -584,36 +585,41 @@ evdev_handle_device(struct evdev_device *device) return 1; } -static int +static void evdev_configure_device(struct evdev_device *device) { if ((device->caps & (EVDEV_MOTION_ABS | EVDEV_MOTION_REL)) && - (device->caps & EVDEV_BUTTON)) { + (device->caps & EVDEV_BUTTON)) + device->seat_caps |= EVDEV_DEVICE_POINTER; + if ((device->caps & EVDEV_KEYBOARD)) + device->seat_caps |= EVDEV_DEVICE_KEYBOARD; + if ((device->caps & EVDEV_TOUCH)) + device->seat_caps |= EVDEV_DEVICE_TOUCH; +} + +static void +register_device_capabilities(struct evdev_device *device) +{ + if (device->seat_caps & EVDEV_DEVICE_POINTER) { device_register_capability(&device->base, LIBINPUT_DEVICE_CAP_POINTER); - device->seat_caps |= EVDEV_DEVICE_POINTER; } - if ((device->caps & EVDEV_KEYBOARD)) { + if (device->seat_caps & EVDEV_DEVICE_KEYBOARD) { device_register_capability(&device->base, LIBINPUT_DEVICE_CAP_KEYBOARD); - device->seat_caps |= EVDEV_DEVICE_KEYBOARD; } - if ((device->caps & EVDEV_TOUCH)) { + if (device->seat_caps & EVDEV_DEVICE_TOUCH) { device_register_capability(&device->base, LIBINPUT_DEVICE_CAP_TOUCH); - device->seat_caps |= EVDEV_DEVICE_TOUCH; } - - return 0; } -LIBINPUT_EXPORT struct libinput_device * -libinput_device_create_evdev( - struct libinput *libinput, - const char *devnode, - int fd, - void *user_data) +struct evdev_device * +evdev_device_create(struct libinput_seat *seat, + const char *devnode, + int fd) { + struct libinput *libinput = seat->libinput; struct evdev_device *device; char devname[256] = "unknown"; @@ -621,8 +627,7 @@ libinput_device_create_evdev( if (device == NULL) return NULL; - device->base.libinput = libinput; - device->base.user_data = user_data; + libinput_device_init(&device->base, seat); device->seat_caps = 0; device->is_mt = 0; @@ -644,8 +649,7 @@ libinput_device_create_evdev( return NULL; } - if (evdev_configure_device(device) == -1) - goto err; + evdev_configure_device(device); /* If the dispatch was not set up use the fallback. */ if (device->dispatch == NULL) @@ -658,7 +662,11 @@ libinput_device_create_evdev( if (!device->source) goto err; - return &device->base; + list_insert(seat->devices_list.prev, &device->base.link); + notify_added_device(&device->base); + register_device_capabilities(device); + + return device; err: evdev_device_destroy(device); @@ -672,6 +680,12 @@ evdev_device_get_keys(struct evdev_device *device, char *keys, size_t size) return ioctl(device->fd, EVIOCGKEY(size), keys); } +const char * +evdev_device_get_output(struct evdev_device *device) +{ + return device->output_name; +} + void evdev_device_calibrate(struct evdev_device *device, float calibration[6]) { @@ -680,7 +694,7 @@ evdev_device_calibrate(struct evdev_device *device, float calibration[6]) } void -evdev_device_terminate(struct evdev_device *device) +evdev_device_remove(struct evdev_device *device) { if (device->seat_caps & EVDEV_DEVICE_POINTER) { device_unregister_capability(&device->base, @@ -694,6 +708,18 @@ evdev_device_terminate(struct evdev_device *device) device_unregister_capability(&device->base, LIBINPUT_DEVICE_CAP_TOUCH); } + + if (device->source) + libinput_remove_source(device->base.seat->libinput, + device->source); + + if (device->mtdev) + mtdev_close_delete(device->mtdev); + close(device->fd); + list_remove(&device->base.link); + + notify_removed_device(&device->base); + libinput_device_unref(&device->base); } void @@ -705,9 +731,6 @@ evdev_device_destroy(struct evdev_device *device) if (dispatch) dispatch->interface->destroy(dispatch); - if (device->mtdev) - mtdev_close_delete(device->mtdev); - close(device->fd); free(device->devname); free(device->devnode); free(device); diff --git a/src/evdev.h b/src/evdev.h index c8cb405..9b904aa 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -70,6 +70,7 @@ struct evdev_device { struct libinput_source *source; struct evdev_dispatch *dispatch; + char *output_name; char *devnode; char *devname; int fd; @@ -129,6 +130,11 @@ struct evdev_dispatch { struct evdev_dispatch_interface *interface; }; +struct evdev_device * +evdev_device_create(struct libinput_seat *seat, + const char *devnode, + int fd); + struct evdev_dispatch * evdev_touchpad_create(struct evdev_device *device); @@ -141,11 +147,14 @@ evdev_device_led_update(struct evdev_device *device, enum libinput_led leds); int evdev_device_get_keys(struct evdev_device *device, char *keys, size_t size); +const char * +evdev_device_get_output(struct evdev_device *device); + void evdev_device_calibrate(struct evdev_device *device, float calibration[6]); void -evdev_device_terminate(struct evdev_device *terminate); +evdev_device_remove(struct evdev_device *device); void evdev_device_destroy(struct evdev_device *device); diff --git a/src/libinput-private.h b/src/libinput-private.h index f49badc..529e002 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -30,6 +30,8 @@ struct libinput { int epoll_fd; struct list source_destroy_list; + struct list seat_list; + struct libinput_event **events; size_t events_count; size_t events_len; @@ -40,16 +42,32 @@ struct libinput { void *user_data; }; -struct libinput_device { +struct libinput_seat { struct libinput *libinput; + struct list link; + struct list devices_list; + void *user_data; + int refcount; + char *name; +}; + +struct libinput_device { + struct libinput_seat *seat; + struct list link; void *user_data; int terminated; + int refcount; }; typedef void (*libinput_source_dispatch_t)(void *data); struct libinput_source; +int +libinput_init(struct libinput *libinput, + const struct libinput_interface *interface, + void *user_data); + struct libinput_source * libinput_add_fd(struct libinput *libinput, int fd, @@ -60,9 +78,33 @@ void libinput_remove_source(struct libinput *libinput, struct libinput_source *source); +int +open_restricted(struct libinput *libinput, + const char *path, int flags); + +void +close_restricted(struct libinput *libinput, int fd); + +void +libinput_seat_init(struct libinput_seat *seat, + struct libinput *libinput, + const char *name); + +void +libinput_device_init(struct libinput_device *device, + struct libinput_seat *seat); + +void +notify_added_seat(struct libinput_seat *seat); + +void +notify_removed_seat(struct libinput_seat *seat); + +void +notify_added_device(struct libinput_device *device); + void -libinput_post_event(struct libinput *libinput, - struct libinput_event *event); +notify_removed_device(struct libinput_device *device); void device_register_capability(struct libinput_device *device, diff --git a/src/libinput.c b/src/libinput.c index 10d6fc1..b7dc30b 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -30,8 +30,9 @@ #include #include "libinput.h" -#include "evdev.h" #include "libinput-private.h" +#include "evdev.h" +#include "udev-seat.h" struct libinput_source { libinput_source_dispatch_t dispatch; @@ -40,6 +41,10 @@ struct libinput_source { struct list link; }; +static void +libinput_post_event(struct libinput *libinput, + struct libinput_event *event); + struct libinput_source * libinput_add_fd(struct libinput *libinput, int fd, @@ -80,25 +85,21 @@ libinput_remove_source(struct libinput *libinput, list_insert(&libinput->source_destroy_list, &source->link); } -LIBINPUT_EXPORT struct libinput * -libinput_create(const struct libinput_interface *interface, void *user_data) +int +libinput_init(struct libinput *libinput, + const struct libinput_interface *interface, + void *user_data) { - struct libinput *libinput; - - libinput = zalloc(sizeof *libinput); - if (!libinput) - return NULL; - - list_init(&libinput->source_destroy_list); + libinput->epoll_fd = epoll_create1(EPOLL_CLOEXEC);; + if (libinput->epoll_fd < 0) + return -1; libinput->interface = interface; libinput->user_data = user_data; + list_init(&libinput->source_destroy_list); + list_init(&libinput->seat_list); - libinput->epoll_fd = epoll_create1(EPOLL_CLOEXEC);; - if (libinput->epoll_fd < 0) - return NULL; - - return libinput; + return 0; } LIBINPUT_EXPORT void @@ -114,6 +115,88 @@ libinput_destroy(struct libinput *libinput) free(libinput); } +int +open_restricted(struct libinput *libinput, + const char *path, int flags) +{ + return libinput->interface->open_restricted(path, + flags, + libinput->user_data); +} + +void +close_restricted(struct libinput *libinput, int fd) +{ + return libinput->interface->close_restricted(fd, libinput->user_data); +} + +void +libinput_seat_init(struct libinput_seat *seat, + struct libinput *libinput, + const char *name) +{ + seat->refcount = 1; + seat->libinput = libinput; + seat->name = strdup(name); + list_init(&seat->devices_list); +} + +LIBINPUT_EXPORT void +libinput_seat_ref(struct libinput_seat *seat) +{ + seat->refcount++; +} + +LIBINPUT_EXPORT void +libinput_seat_unref(struct libinput_seat *seat) +{ + seat->refcount--; + if (seat->refcount == 0) { + free(seat->name); + udev_seat_destroy((struct udev_seat *) seat); + } +} + +LIBINPUT_EXPORT void +libinput_seat_set_user_data(struct libinput_seat *seat, void *user_data) +{ + seat->user_data = user_data; +} + +LIBINPUT_EXPORT void * +libinput_seat_get_user_data(struct libinput_seat *seat) +{ + return seat->user_data; +} + +LIBINPUT_EXPORT const char * +libinput_seat_get_name(struct libinput_seat *seat) +{ + return seat->name; +} + +void +libinput_device_init(struct libinput_device *device, + struct libinput_seat *seat) +{ + device->seat = seat; + device->refcount = 1; +} + +LIBINPUT_EXPORT void +libinput_device_ref(struct libinput_device *device) +{ + device->refcount++; +} + +LIBINPUT_EXPORT void +libinput_device_unref(struct libinput_device *device) +{ + device->refcount--; + if (device->refcount == 0) + evdev_device_destroy((struct evdev_device *) device); +} + LIBINPUT_EXPORT int libinput_get_fd(struct libinput *libinput) { @@ -149,19 +232,114 @@ libinput_dispatch(struct libinput *libinput) static void init_event_base(struct libinput_event *event, enum libinput_event_type type, - struct libinput_device *device) + union libinput_event_target target) { event->type = type; - event->device = device; + event->target = target; } static void +post_base_event(struct libinput *libinput, + enum libinput_event_type type, + struct libinput_event *event) +{ + init_event_base(event, type, + (union libinput_event_target) { .libinput = libinput }); + libinput_post_event(libinput, event); +} + +#if 0 +static void +post_seat_event(struct libinput_seat *seat, + enum libinput_event_type type, + struct libinput_event *event) +{ + init_event_base(event, type, + (union libinput_event_target) { .seat = seat }); + libinput_post_event(seat->libinput, event); +} +#endif + +static void post_device_event(struct libinput_device *device, enum libinput_event_type type, struct libinput_event *event) { - init_event_base(event, type, device); - libinput_post_event(device->libinput, event); + init_event_base(event, type, + (union libinput_event_target) { .device = device }); + 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; + + added_device_event = malloc(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, + &added_device_event->base); +} + +void +notify_removed_device(struct libinput_device *device) +{ + struct libinput_event_removed_device *removed_device_event; + + removed_device_event = malloc(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, + &removed_device_event->base); } void @@ -340,7 +518,7 @@ touch_notify_touch(struct libinput_device *device, &touch_event->base); } -void +static void libinput_post_event(struct libinput *libinput, struct libinput_event *event) { @@ -400,18 +578,28 @@ libinput_get_event(struct libinput *libinput) return event; } +LIBINPUT_EXPORT void * +libinput_get_user_data(struct libinput *libinput) +{ + return libinput->user_data; +} + +LIBINPUT_EXPORT int +libinput_resume(struct libinput *libinput) +{ + return udev_input_enable((struct udev_input *) libinput); +} + LIBINPUT_EXPORT void -libinput_device_terminate(struct libinput_device *device) +libinput_suspend(struct libinput *libinput) { - evdev_device_terminate((struct evdev_device *) device); - device->terminated = 1; + udev_input_disable((struct udev_input *) libinput); } LIBINPUT_EXPORT void -libinput_device_destroy(struct libinput_device *device) +libinput_device_set_user_data(struct libinput_device *device, void *user_data) { - assert(device->terminated); - evdev_device_destroy((struct evdev_device *) device); + device->user_data = user_data; } LIBINPUT_EXPORT void * @@ -420,6 +608,18 @@ libinput_device_get_user_data(struct libinput_device *device) return device->user_data; } +LIBINPUT_EXPORT const char * +libinput_device_get_output_name(struct libinput_device *device) +{ + return evdev_device_get_output((struct evdev_device *) device); +} + +LIBINPUT_EXPORT struct libinput_seat * +libinput_device_get_seat(struct libinput_device *device) +{ + return device->seat; +} + LIBINPUT_EXPORT void libinput_device_led_update(struct libinput_device *device, enum libinput_led leds) diff --git a/src/libinput.h b/src/libinput.h index a051e4a..e9be9a4 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -25,6 +25,7 @@ #include #include +#include typedef int32_t li_fixed_t; @@ -64,6 +65,11 @@ enum libinput_touch_type { }; enum libinput_event_type { + LIBINPUT_EVENT_ADDED_SEAT = 0, + LIBINPUT_EVENT_REMOVED_SEAT, + LIBINPUT_EVENT_ADDED_DEVICE, + LIBINPUT_EVENT_REMOVED_DEVICE, + LIBINPUT_EVENT_DEVICE_REGISTER_CAPABILITY = 200, LIBINPUT_EVENT_DEVICE_UNREGISTER_CAPABILITY, @@ -77,8 +83,34 @@ enum libinput_event_type { LIBINPUT_EVENT_TOUCH_TOUCH = 500, }; +union libinput_event_target { + struct libinput *libinput; + struct libinput_seat *seat; + struct libinput_device *device; +}; + 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; }; @@ -141,6 +173,9 @@ struct libinput_fd_handle; typedef void (*libinput_fd_callback)(int fd, void *data); struct libinput_interface { + int (*open_restricted)(const char *path, int flags, void *user_data); + void (*close_restricted)(int fd, void *user_data); + void (*get_current_screen_dimensions)(struct libinput_device *device, int *width, int *height, @@ -150,8 +185,15 @@ struct libinput_interface { struct libinput; struct libinput_device; +/* + * Base + */ + struct libinput * -libinput_create(const struct libinput_interface *interface, void *user_data); +libinput_create_udev(const struct libinput_interface *interface, + void *user_data, + struct udev *udev, + const char *seat_id); int libinput_get_fd(struct libinput *libinput); @@ -162,24 +204,59 @@ libinput_dispatch(struct libinput *libinput); struct libinput_event * libinput_get_event(struct libinput *libinput); +void * +libinput_get_user_data(struct libinput *libinput); + +int +libinput_resume(struct libinput *libinput); + +void +libinput_suspend(struct libinput *libinput); + void libinput_destroy(struct libinput *libinput); -struct libinput_device * -libinput_device_create_evdev(struct libinput *libinput, - const char *devnode, - int fd, - void *user_data); +/* + * Seat + */ + +void +libinput_seat_ref(struct libinput_seat *seat); + +void +libinput_seat_unref(struct libinput_seat *seat); + +void +libinput_seat_set_user_data(struct libinput_seat *seat, void *user_data); + +void * +libinput_seat_get_user_data(struct libinput_seat *seat); + +const char * +libinput_seat_get_name(struct libinput_seat *seat); + +/* + * Device + */ + +void +libinput_device_ref(struct libinput_device *device); void -libinput_device_terminate(struct libinput_device *device); +libinput_device_unref(struct libinput_device *device); void -libinput_device_destroy(struct libinput_device *device); +libinput_device_set_user_data(struct libinput_device *device, void *user_data); void * libinput_device_get_user_data(struct libinput_device *device); +const char * +libinput_device_get_output_name(struct libinput_device *device); + +struct libinput_seat * +libinput_device_get_seat(struct libinput_device *device); + void libinput_device_led_update(struct libinput_device *device, enum libinput_led leds); diff --git a/src/udev-seat.c b/src/udev-seat.c index deceb50..9a1ce7a 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -23,12 +23,11 @@ #include "config.h" #include +#include #include #include #include -#include "compositor.h" -#include "launcher-util.h" #include "evdev.h" #include "udev-seat.h" @@ -36,16 +35,15 @@ static const char default_seat[] = "seat0"; static const char default_seat_name[] = "default"; static struct udev_seat * -udev_seat_create(struct weston_compositor *c, const char *seat_name); -static void -udev_seat_destroy(struct udev_seat *seat); +udev_seat_create(struct udev_input *input, const char *seat_name); +static struct udev_seat * +udev_seat_get_named(struct udev_input *input, const char *seat_name); static int device_added(struct udev_device *udev_device, struct udev_input *input) { - struct weston_compositor *c; + struct libinput *libinput = &input->base; struct evdev_device *device; - struct weston_output *output; const char *devnode; const char *device_seat, *seat_name, *output_name; const char *calibration_values; @@ -59,7 +57,6 @@ device_added(struct udev_device *udev_device, struct udev_input *input) if (strcmp(device_seat, input->seat_id)) return 0; - c = input->compositor; devnode = udev_device_get_devnode(udev_device); /* Search for matching logical seat */ @@ -67,7 +64,7 @@ device_added(struct udev_device *udev_device, struct udev_input *input) if (!seat_name) seat_name = default_seat_name; - seat = udev_seat_get_named(c, seat_name); + seat = udev_seat_get_named(input, seat_name); if (seat == NULL) return -1; @@ -75,20 +72,20 @@ device_added(struct udev_device *udev_device, struct udev_input *input) /* Use non-blocking mode so that we can loop on read on * evdev_device_data() until all events on the fd are * read. mtdev_get() also expects this. */ - fd = weston_launcher_open(c->launcher, devnode, O_RDWR | O_NONBLOCK); + fd = open_restricted(libinput, devnode, O_RDWR | O_NONBLOCK); if (fd < 0) { - weston_log("opening input device '%s' failed.\n", devnode); + log_info("opening input device '%s' failed.\n", devnode); return 0; } device = evdev_device_create(&seat->base, devnode, fd); if (device == EVDEV_UNHANDLED_DEVICE) { - weston_launcher_close(c->launcher, fd); - weston_log("not using input device '%s'.\n", devnode); + close_restricted(libinput, fd); + log_info("not using input device '%s'.\n", devnode); return 0; } else if (device == NULL) { - weston_launcher_close(c->launcher, fd); - weston_log("failed to create input device '%s'.\n", devnode); + close_restricted(libinput, fd); + log_info("failed to create input device '%s'.\n", devnode); return 0; } @@ -105,31 +102,18 @@ device_added(struct udev_device *udev_device, struct udev_input *input) &device->abs.calibration[4], &device->abs.calibration[5]) == 6) { device->abs.apply_calibration = 1; - weston_log ("Applying calibration: %f %f %f %f %f %f\n", - device->abs.calibration[0], - device->abs.calibration[1], - device->abs.calibration[2], - device->abs.calibration[3], - device->abs.calibration[4], - device->abs.calibration[5]); + log_info("Applying calibration: %f %f %f %f %f %f\n", + device->abs.calibration[0], + device->abs.calibration[1], + device->abs.calibration[2], + device->abs.calibration[3], + device->abs.calibration[4], + device->abs.calibration[5]); } - wl_list_insert(seat->devices_list.prev, &device->link); - - if (seat->base.output && seat->base.pointer) - weston_pointer_clamp(seat->base.pointer, - &seat->base.pointer->x, - &seat->base.pointer->y); - output_name = udev_device_get_property_value(udev_device, "WL_OUTPUT"); - if (output_name) { - wl_list_for_each(output, &c->output_list, link) - if (strcmp(output->name, output_name) == 0) - device->output = output; - } - - if (input->enabled == 1) - weston_seat_repick(&seat->base); + if (output_name) + device->output_name = strdup(output_name); return 0; } @@ -141,8 +125,6 @@ udev_input_add_devices(struct udev_input *input, struct udev *udev) struct udev_list_entry *entry; struct udev_device *device; const char *path, *sysname; - struct udev_seat *seat; - int devices_found = 0; e = udev_enumerate_new(udev); udev_enumerate_add_match_subsystem(e, "input"); @@ -167,31 +149,14 @@ udev_input_add_devices(struct udev_input *input, struct udev *udev) } udev_enumerate_unref(e); - wl_list_for_each(seat, &input->compositor->seat_list, base.link) { - evdev_notify_keyboard_focus(&seat->base, &seat->devices_list); - - if (!wl_list_empty(&seat->devices_list)) - devices_found = 1; - } - - if (devices_found == 0) { - weston_log( - "warning: no input devices on entering Weston. " - "Possible causes:\n" - "\t- no permissions to read /dev/input/event*\n" - "\t- seats misconfigured " - "(Weston backend option 'seat', " - "udev device property ID_SEAT)\n"); - return -1; - } - return 0; } -static int -evdev_udev_handler(int fd, uint32_t mask, void *data) +static void +evdev_udev_handler(void *data) { struct udev_input *input = data; + struct libinput *libinput = &input->base; struct udev_device *udev_device; struct evdev_device *device, *next; const char *action; @@ -200,7 +165,7 @@ evdev_udev_handler(int fd, uint32_t mask, void *data) udev_device = udev_monitor_receive_device(input->udev_monitor); if (!udev_device) - return 1; + return; action = udev_device_get_action(udev_device); if (!action) @@ -214,14 +179,14 @@ evdev_udev_handler(int fd, uint32_t mask, void *data) } else if (!strcmp(action, "remove")) { devnode = udev_device_get_devnode(udev_device); - wl_list_for_each(seat, &input->compositor->seat_list, base.link) { - wl_list_for_each_safe(device, next, &seat->devices_list, link) + list_for_each(seat, &input->base.seat_list, base.link) { + list_for_each_safe(device, next, + &seat->base.devices_list, base.link) if (!strcmp(device->devnode, devnode)) { - weston_log("input device %s, %s removed\n", - device->devname, device->devnode); - weston_launcher_close(input->compositor->launcher, - device->fd); - evdev_device_destroy(device); + log_info("input device %s, %s removed\n", + device->devname, device->devnode); + close_restricted(libinput, device->fd); + evdev_device_remove(device); break; } } @@ -229,20 +194,17 @@ evdev_udev_handler(int fd, uint32_t mask, void *data) out: udev_device_unref(udev_device); - - return 0; } int -udev_input_enable(struct udev_input *input, struct udev *udev) +udev_input_enable(struct udev_input *input) { - struct wl_event_loop *loop; - struct weston_compositor *c = input->compositor; + struct udev *udev = input->udev; int fd; input->udev_monitor = udev_monitor_new_from_netlink(udev, "udev"); if (!input->udev_monitor) { - weston_log("udev: failed to create the udev monitor\n"); + log_info("udev: failed to create the udev monitor\n"); return -1; } @@ -250,16 +212,16 @@ udev_input_enable(struct udev_input *input, struct udev *udev) "input", NULL); if (udev_monitor_enable_receiving(input->udev_monitor)) { - weston_log("udev: failed to bind the udev monitor\n"); + log_info("udev: failed to bind the udev monitor\n"); udev_monitor_unref(input->udev_monitor); return -1; } - loop = wl_display_get_event_loop(c->wl_display); fd = udev_monitor_get_fd(input->udev_monitor); - input->udev_monitor_source = - wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE, - evdev_udev_handler, input); + input->udev_monitor_source = libinput_add_fd(&input->base, + fd, + evdev_udev_handler, + input); if (!input->udev_monitor_source) { udev_monitor_unref(input->udev_monitor); return -1; @@ -268,8 +230,6 @@ udev_input_enable(struct udev_input *input, struct udev *udev) if (udev_input_add_devices(input, udev) < 0) return -1; - input->enabled = 1; - return 0; } @@ -279,15 +239,12 @@ udev_input_remove_devices(struct udev_input *input) struct evdev_device *device, *next; struct udev_seat *seat; - wl_list_for_each(seat, &input->compositor->seat_list, base.link) { - wl_list_for_each_safe(device, next, &seat->devices_list, link) { - weston_launcher_close(input->compositor->launcher, - device->fd); - evdev_device_destroy(device); + list_for_each(seat, &input->base.seat_list, base.link) { + list_for_each_safe(device, next, + &seat->base.devices_list, base.link) { + close_restricted(&input->base, device->fd); + evdev_device_remove(device); } - - if (seat->base.keyboard) - notify_keyboard_focus_out(&seat->base); } } @@ -299,87 +256,92 @@ udev_input_disable(struct udev_input *input) udev_monitor_unref(input->udev_monitor); input->udev_monitor = NULL; - wl_event_source_remove(input->udev_monitor_source); + libinput_remove_source(&input->base, input->udev_monitor_source); input->udev_monitor_source = NULL; udev_input_remove_devices(input); } - -int -udev_input_init(struct udev_input *input, struct weston_compositor *c, struct udev *udev, - const char *seat_id) -{ - memset(input, 0, sizeof *input); - input->seat_id = strdup(seat_id); - input->compositor = c; - if (udev_input_enable(input, udev) < 0) - goto err; - - return 0; - - err: - free(input->seat_id); - return -1; -} - void udev_input_destroy(struct udev_input *input) { - struct udev_seat *seat, *next; + struct libinput_seat *seat, *next; udev_input_disable(input); - wl_list_for_each_safe(seat, next, &input->compositor->seat_list, base.link) - udev_seat_destroy(seat); + list_for_each_safe(seat, next, &input->base.seat_list, link) { + notify_removed_seat(seat); + libinput_seat_unref(seat); + } + udev_unref(input->udev); free(input->seat_id); } -static void -drm_led_update(struct weston_seat *seat_base, enum weston_led leds) -{ - struct udev_seat *seat = (struct udev_seat *) seat_base; - struct evdev_device *device; - - wl_list_for_each(device, &seat->devices_list, link) - evdev_led_update(device, leds); -} - static struct udev_seat * -udev_seat_create(struct weston_compositor *c, const char *seat_name) +udev_seat_create(struct udev_input *input, const char *seat_name) { struct udev_seat *seat; seat = zalloc(sizeof *seat); - if (!seat) return NULL; - weston_seat_init(&seat->base, c, seat_name); - seat->base.led_update = drm_led_update; - wl_list_init(&seat->devices_list); + libinput_seat_init(&seat->base, &input->base, seat_name); + list_insert(&input->base.seat_list, &seat->base.link); + notify_added_seat(&seat->base); + return seat; } -static void +void udev_seat_destroy(struct udev_seat *seat) { - weston_seat_release(&seat->base); + list_remove(&seat->base.link); free(seat); } -struct udev_seat * -udev_seat_get_named(struct weston_compositor *c, const char *seat_name) +static struct udev_seat * +udev_seat_get_named(struct udev_input *input, const char *seat_name) { struct udev_seat *seat; - wl_list_for_each(seat, &c->seat_list, base.link) { - if (strcmp(seat->base.seat_name, seat_name) == 0) + list_for_each(seat, &input->base.seat_list, base.link) { + if (strcmp(seat->base.name, seat_name) == 0) return seat; } - seat = udev_seat_create(c, seat_name); + seat = udev_seat_create(input, seat_name); if (!seat) return NULL; return seat; } + +LIBINPUT_EXPORT struct libinput * +libinput_create_udev(const struct libinput_interface *interface, + void *user_data, + struct udev *udev, + const char *seat_id) +{ + struct udev_input *input; + + input = zalloc(sizeof *input); + if (!input) + return NULL; + + if (libinput_init(&input->base, interface, user_data) != 0) { + free(input); + return NULL; + } + + input->udev = udev_ref(udev); + input->seat_id = strdup(seat_id); + + if (udev_input_enable(input) < 0) { + udev_unref(udev); + libinput_destroy(&input->base); + free(input); + return NULL; + } + + return &input->base; +} diff --git a/src/udev-seat.h b/src/udev-seat.h index 4cb6f07..6ac18bc 100644 --- a/src/udev-seat.h +++ b/src/udev-seat.h @@ -27,30 +27,24 @@ #include -#include "compositor.h" - struct udev_seat { - struct weston_seat base; - struct wl_list devices_list; + struct libinput_seat base; + char *seat_name; }; struct udev_input { + struct libinput base; + struct udev *udev; struct udev_monitor *udev_monitor; - struct wl_event_source *udev_monitor_source; + struct libinput_source *udev_monitor_source; char *seat_id; - struct weston_compositor *compositor; - int enabled; }; - -int udev_input_enable(struct udev_input *input, struct udev *udev); +int udev_input_process_event(struct libinput_event); +int udev_input_enable(struct udev_input *input); void udev_input_disable(struct udev_input *input); -int udev_input_init(struct udev_input *input, - struct weston_compositor *c, - struct udev *udev, - const char *seat_id); void udev_input_destroy(struct udev_input *input); -struct udev_seat *udev_seat_get_named(struct weston_compositor *c, - const char *seat_name); +void udev_seat_destroy(struct udev_seat *seat); + #endif