From 55bf5058077fe66f42c2bf104df98139ab5d9303 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sat, 26 Apr 2014 20:01:22 +1000 Subject: [PATCH 01/22] Name-space the scroll event types To provide a generic naming system of type_direction. That will become more important once we add new axes as part of the ongoing work to support graphics tablets. [edit: and switch to the new defines] Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede --- src/evdev-mt-touchpad.c | 20 ++++++++++---------- src/evdev.c | 4 ++-- src/libinput.h | 14 ++++++++++---- test/pointer.c | 4 ++-- tools/event-debug.c | 4 ++-- 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 787afa4c..4811bf31 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -466,11 +466,11 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time) /* Require at least three px scrolling to start */ if (dy <= -3.0 || dy >= 3.0) { tp->scroll.state = SCROLL_STATE_SCROLLING; - tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL); + tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); } if (dx <= -3.0 || dx >= 3.0) { tp->scroll.state = SCROLL_STATE_SCROLLING; - tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL); + tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); } if (tp->scroll.state == SCROLL_STATE_NONE) @@ -481,18 +481,18 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time) t->is_pointer = false; if (dy != 0.0 && - (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL))) { + (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))) { pointer_notify_axis(&tp->device->base, time, - LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, dy); } if (dx != 0.0 && - (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL))) { + (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))) { pointer_notify_axis(&tp->device->base, time, - LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, dx); } } @@ -504,15 +504,15 @@ tp_stop_scroll_events(struct tp_dispatch *tp, uint64_t time) return; /* terminate scrolling with a zero scroll event */ - if (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL)) + if (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) pointer_notify_axis(&tp->device->base, time, - LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 0); - if (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL)) + if (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) pointer_notify_axis(&tp->device->base, time, - LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 0); tp->scroll.state = SCROLL_STATE_NONE; diff --git a/src/evdev.c b/src/evdev.c index 70c232ce..b6412d01 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -390,7 +390,7 @@ evdev_process_relative(struct evdev_device *device, pointer_notify_axis( base, time, - LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -1 * e->value * DEFAULT_AXIS_STEP_DISTANCE); break; case REL_HWHEEL: @@ -403,7 +403,7 @@ evdev_process_relative(struct evdev_device *device, pointer_notify_axis( base, time, - LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, e->value * DEFAULT_AXIS_STEP_DISTANCE); break; default: diff --git a/src/libinput.h b/src/libinput.h index fe75f87d..b1b1124e 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -164,8 +164,14 @@ enum libinput_button_state { * Axes on a device that are not x or y coordinates. */ enum libinput_pointer_axis { - LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL = 0, - LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL = 1 + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL = 0, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL = 1, + + + /** @deprecated Use @ref LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL instead */ + LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, + /** @deprecated Use @ref LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL instead */ + LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL }; /** @@ -595,8 +601,8 @@ libinput_event_pointer_get_axis(struct libinput_event_pointer *event); * * Return the axis value of the given axis. The interpretation of the value * is dependent on the axis. For the two scrolling axes - * LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL and - * LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL, the value of the event is in + * LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL and + * LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, the value of the event is in * relative scroll units, with the positive direction being down or right, * respectively. The dimension of a scroll unit is equal to one unit of * motion in the respective axis, where applicable (e.g. touchpad two-finger diff --git a/test/pointer.c b/test/pointer.c index fd76ffe7..346e59b7 100644 --- a/test/pointer.c +++ b/test/pointer.c @@ -181,8 +181,8 @@ test_wheel_event(struct litest_device *dev, int which, int amount) ck_assert(ptrev != NULL); ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev), which == REL_WHEEL ? - LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL : - LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL); + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL : + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev), expected); libinput_event_destroy(event); } diff --git a/tools/event-debug.c b/tools/event-debug.c index 0f0d0339..34acfce2 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -305,10 +305,10 @@ print_axis_event(struct libinput_event *ev) double val; switch (axis) { - case LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL: + case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: ax = "vscroll"; break; - case LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL: + case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: ax = "hscroll"; break; default: From 82e81e8790956cb531c9ae5a225e4425b40a1f50 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 27 May 2014 15:29:55 +1000 Subject: [PATCH 02/22] tools: add a tool for GUI-based debugging Looking at debugging output is nice but not useful when testing for the feel of a device. Add a tool that presents a canvas and draws the various events onto it. Signed-off-by: Peter Hutterer --- configure.ac | 15 ++ tools/.gitignore | 1 + tools/Makefile.am | 9 + tools/event-gui.c | 474 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 499 insertions(+) create mode 100644 tools/event-gui.c diff --git a/configure.ac b/configure.ac index 13cf3a81..361eafe7 100644 --- a/configure.ac +++ b/configure.ac @@ -74,6 +74,21 @@ else fi AM_CONDITIONAL([HAVE_DOXYGEN], [test "x$have_doxygen" = "xyes"]) +AC_ARG_ENABLE(event-gui, + AS_HELP_STRING([--enable-event-gui], [Build the GUI event viewer (default=auto)]), + [build_eventgui="$enableval"], + [build_eventgui="auto"]) +PKG_CHECK_EXISTS([cairo glib-2.0 gtk+-3.0], [HAVE_GUILIBS="yes"], [HAVE_GUILIBS="no"]) + +if test "x$build_eventgui" = "xauto"; then + build_eventgui="$HAVE_GUILIBS" +fi +if test "x$build_eventgui" = "xyes"; then + PKG_CHECK_MODULES(CAIRO, [cairo]) + PKG_CHECK_MODULES(GTK, [glib-2.0 gtk+-3.0]) +fi +AM_CONDITIONAL(BUILD_EVENTGUI, [test "x$build_eventgui" = "xyes"]) + AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests], [Build the tests (default=auto)]), [build_tests="$enableval"], diff --git a/tools/.gitignore b/tools/.gitignore index 2cdd654f..cf348a6f 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -1 +1,2 @@ event-debug +event-gui diff --git a/tools/Makefile.am b/tools/Makefile.am index 8b6e22be..f59068da 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -7,3 +7,12 @@ event_debug_SOURCES = event-debug.c event_debug_LDADD = ../src/libinput.la $(LIBUDEV_LIBS) event_debug_LDFLAGS = -static event_debug_CFLAGS = $(LIBUDEV_CFLAGS) + +if BUILD_EVENTGUI +noinst_PROGRAMS += event-gui + +event_gui_SOURCES = event-gui.c +event_gui_LDADD = ../src/libinput.la $(CAIRO_LIBS) $(GTK_LIBS) $(LIBUDEV_LIBS) +event_gui_CFLAGS = $(CAIRO_CFLAGS) $(GTK_CFLAGS) $(LIBUDEV_CFLAGS) +event_gui_LDFLAGS = -static +endif diff --git a/tools/event-gui.c b/tools/event-gui.c new file mode 100644 index 00000000..95540936 --- /dev/null +++ b/tools/event-gui.c @@ -0,0 +1,474 @@ +/* + * Copyright © 2014 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#define _GNU_SOURCE +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#define clip(val_, min_, max_) min((max_), max((min_), (val_))) + +struct touch { + int active; + int x, y; +}; + +struct window { + GtkWidget *win; + GtkWidget *area; + int width, height; /* of window */ + + /* sprite position */ + int x, y; + + /* abs position */ + int absx, absy; + + /* scroll bar positions */ + int vx, vy; + int hx, hy; + + /* touch positions */ + struct touch touches[32]; + + /* l/m/r mouse buttons */ + int l, m, r; +}; + +static int +error(const char *fmt, ...) +{ + va_list args; + fprintf(stderr, "error: "); + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + + return EXIT_FAILURE; +} + +static void +msg(const char *fmt, ...) +{ + va_list args; + printf("info: "); + + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); +} + +static void +usage(void) +{ + printf("%s [path/to/device]\n", program_invocation_short_name); +} + +static gboolean +draw(GtkWidget *widget, cairo_t *cr, gpointer data) +{ + struct window *w = data; + struct touch *t; + + cairo_set_source_rgb(cr, 1, 1, 1); + cairo_rectangle(cr, 0, 0, w->width, w->height); + cairo_fill(cr); + + /* draw pointer sprite */ + cairo_set_source_rgb(cr, 0, 0, 0); + cairo_save(cr); + cairo_move_to(cr, w->x, w->y); + cairo_rel_line_to(cr, 10, 15); + cairo_rel_line_to(cr, -10, 0); + cairo_rel_line_to(cr, 0, -15); + cairo_fill(cr); + cairo_restore(cr); + + /* draw scroll bars */ + cairo_set_source_rgb(cr, .4, .8, 0); + + cairo_save(cr); + cairo_rectangle(cr, w->vx - 10, w->vy - 20, 20, 40); + cairo_rectangle(cr, w->hx - 20, w->hy - 10, 40, 20); + cairo_fill(cr); + cairo_restore(cr); + + /* touch points */ + cairo_set_source_rgb(cr, .8, .2, .2); + + ARRAY_FOR_EACH(w->touches, t) { + cairo_save(cr); + cairo_arc(cr, t->x, t->y, 10, 0, 2 * M_PI); + cairo_fill(cr); + cairo_restore(cr); + } + + /* abs position */ + cairo_set_source_rgb(cr, .2, .4, .8); + + cairo_save(cr); + cairo_move_to(cr, w->absx, w->absy); + cairo_arc(cr, 0, 0, 10, 0, 2 * M_PI); + cairo_fill(cr); + cairo_restore(cr); + + /* lmr buttons */ + cairo_save(cr); + if (w->l || w->m || w->r) { + cairo_set_source_rgb(cr, .2, .8, .8); + if (w->l) + cairo_rectangle(cr, w->width/2 - 100, w->height - 200, 70, 30); + if (w->m) + cairo_rectangle(cr, w->width/2 - 20, w->height - 200, 40, 30); + if (w->r) + cairo_rectangle(cr, w->width/2 + 30, w->height - 200, 70, 30); + cairo_fill(cr); + } + + cairo_set_source_rgb(cr, 0, 0, 0); + cairo_rectangle(cr, w->width/2 - 100, w->height - 200, 70, 30); + cairo_rectangle(cr, w->width/2 - 20, w->height - 200, 40, 30); + cairo_rectangle(cr, w->width/2 + 30, w->height - 200, 70, 30); + cairo_stroke(cr); + cairo_restore(cr); + + return TRUE; +} + +static void +map_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + struct window *w = data; + + gtk_window_get_size(GTK_WINDOW(widget), &w->width, &w->height); + + w->x = w->width/2; + w->y = w->height/2; + + w->vx = w->width/2; + w->vy = w->height/2; + w->hx = w->width/2; + w->hy = w->height/2; + + g_signal_connect(G_OBJECT(w->area), "draw", G_CALLBACK(draw), w); + + gdk_window_set_cursor(gtk_widget_get_window(w->win), + gdk_cursor_new(GDK_BLANK_CURSOR)); +} + +static void +window_init(struct window *w) +{ + memset(w, 0, sizeof(*w)); + + w->win = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_set_events(w->win, 0); + gtk_window_set_title(GTK_WINDOW(w->win), "libinput debugging tool"); + gtk_window_set_default_size(GTK_WINDOW(w->win), 1024, 768); + gtk_window_maximize(GTK_WINDOW(w->win)); + gtk_window_set_resizable(GTK_WINDOW(w->win), TRUE); + gtk_widget_realize(w->win); + g_signal_connect(G_OBJECT(w->win), "map-event", G_CALLBACK(map_event_cb), w); + g_signal_connect(G_OBJECT(w->win), "delete-event", G_CALLBACK(gtk_main_quit), NULL); + + w->area = gtk_drawing_area_new(); + gtk_widget_set_events(w->area, 0); + gtk_container_add(GTK_CONTAINER(w->win), w->area); + gtk_widget_show_all(w->win); +} + +static void +handle_event_device_notify(struct libinput_event *ev) +{ + struct libinput_device *dev = libinput_event_get_device(ev); + const char *type; + + if (libinput_event_get_type(ev) == LIBINPUT_EVENT_DEVICE_ADDED) + type = "added"; + else + type = "removed"; + + msg("%s %s\n", libinput_device_get_sysname(dev), type); +} + +static void +handle_event_motion(struct libinput_event *ev, struct window *w) +{ + struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev); + double dx = libinput_event_pointer_get_dx(p), + dy = libinput_event_pointer_get_dy(p); + + w->x += (int)dx; + w->y += (int)dy; + w->x = clip(w->x, 0, w->width); + w->y = clip(w->y, 0, w->height); +} + +static void +handle_event_absmotion(struct libinput_event *ev, struct window *w) +{ + struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev); + double x = libinput_event_pointer_get_absolute_x(p), + y = libinput_event_pointer_get_absolute_y(p); + + w->absx = clip((int)x, 0, w->width); + w->absy = clip((int)y, 0, w->height); +} + +static void +handle_event_touch(struct libinput_event *ev, struct window *w) +{ + struct libinput_event_touch *t = libinput_event_get_touch_event(ev); + int slot = libinput_event_touch_get_seat_slot(t); + struct touch *touch; + double x, y; + + if (slot == -1 || slot >= ARRAY_LENGTH(w->touches)) + return; + + touch = &w->touches[slot]; + + if (libinput_event_get_type(ev) == LIBINPUT_EVENT_TOUCH_UP) { + touch->active = 0; + return; + } + + x = libinput_event_touch_get_x(t), + y = libinput_event_touch_get_y(t); + + touch->active = 1; + touch->x = (int)x; + touch->y = (int)y; +} + +static void +handle_event_axis(struct libinput_event *ev, struct window *w) +{ + struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev); + enum libinput_pointer_axis axis = libinput_event_pointer_get_axis(p); + double v = libinput_event_pointer_get_axis_value(p); + + switch (axis) { + case LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL: + w->vy += (int)v; + w->vy = clip(w->vy, 0, w->height); + break; + case LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL: + w->hx += (int)v; + w->hx = clip(w->hx, 0, w->width); + break; + default: + abort(); + } +} + +static int +handle_event_keyboard(struct libinput_event *ev, struct window *w) +{ + struct libinput_event_keyboard *k = libinput_event_get_keyboard_event(ev); + + if (libinput_event_keyboard_get_key(k) == KEY_ESC) + return 1; + + return 0; +} + +static void +handle_event_button(struct libinput_event *ev, struct window *w) +{ + struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev); + unsigned int button = libinput_event_pointer_get_button(p); + int is_press; + + is_press = libinput_event_pointer_get_button_state(p) == LIBINPUT_BUTTON_STATE_PRESSED; + + switch (button) { + case BTN_LEFT: + w->l = is_press; + break; + case BTN_RIGHT: + w->r = is_press; + break; + case BTN_MIDDLE: + w->m = is_press; + break; + } + +} + +static gboolean +handle_event_libinput(GIOChannel *source, GIOCondition condition, gpointer data) +{ + struct libinput *li = data; + struct window *w = libinput_get_user_data(li); + struct libinput_event *ev; + + libinput_dispatch(li); + + while ((ev = libinput_get_event(li))) { + switch (libinput_event_get_type(ev)) { + case LIBINPUT_EVENT_NONE: + abort(); + case LIBINPUT_EVENT_DEVICE_ADDED: + case LIBINPUT_EVENT_DEVICE_REMOVED: + handle_event_device_notify(ev); + break; + case LIBINPUT_EVENT_POINTER_MOTION: + handle_event_motion(ev, w); + break; + case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: + handle_event_absmotion(ev, w); + break; + case LIBINPUT_EVENT_TOUCH_DOWN: + case LIBINPUT_EVENT_TOUCH_MOTION: + case LIBINPUT_EVENT_TOUCH_UP: + handle_event_touch(ev, w); + break; + case LIBINPUT_EVENT_POINTER_AXIS: + handle_event_axis(ev, w); + break; + case LIBINPUT_EVENT_TOUCH_CANCEL: + case LIBINPUT_EVENT_TOUCH_FRAME: + break; + case LIBINPUT_EVENT_POINTER_BUTTON: + handle_event_button(ev, w); + break; + case LIBINPUT_EVENT_KEYBOARD_KEY: + if (handle_event_keyboard(ev, w)) { + libinput_event_destroy(ev); + gtk_main_quit(); + return FALSE; + } + break; + } + + libinput_event_destroy(ev); + libinput_dispatch(li); + } + gtk_widget_queue_draw(w->area); + + return TRUE; +} + +static void +sockets_init(struct libinput *li) +{ + GIOChannel *c = g_io_channel_unix_new(libinput_get_fd(li)); + + g_io_channel_set_encoding(c, NULL, NULL); + g_io_add_watch(c, G_IO_IN, handle_event_libinput, li); +} + +static int +parse_opts(int argc, char *argv[]) +{ + while (1) { + static struct option long_options[] = { + { "help", no_argument, 0, 'h' }, + }; + + int option_index = 0; + int c; + + c = getopt_long(argc, argv, "h", long_options, + &option_index); + if (c == -1) + break; + + switch(c) { + case 'h': + usage(); + return 0; + default: + usage(); + return 1; + } + } + + return 0; +} + + +static int +open_restricted(const char *path, int flags, void *user_data) +{ + int fd = open(path, flags); + return fd < 0 ? -errno : fd; +} + +static void +close_restricted(int fd, void *user_data) +{ + close(fd); +} + +const static struct libinput_interface interface = { + .open_restricted = open_restricted, + .close_restricted = close_restricted, +}; + +int +main(int argc, char *argv[]) +{ + struct window w; + struct libinput *li; + struct udev *udev; + + gtk_init(&argc, &argv); + + if (parse_opts(argc, argv) != 0) + return 1; + + udev = udev_new(); + if (!udev) + error("Failed to initialize udev\n"); + + li = libinput_udev_create_for_seat(&interface, &w, udev, "seat0"); + if (!li) + error("Failed to initialize context from udev\n"); + + window_init(&w); + sockets_init(li); + + gtk_main(); + + libinput_destroy(li); + udev_unref(udev); + + return 0; +} From 967911791f9988be63b8a2c1ffb608eb2871889b Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 17 Jun 2014 07:55:35 +1000 Subject: [PATCH 03/22] Rename KEYBOARD_KEY_STATE to KEY_STATE e912d620d0f20f415b4d3dde967648e4b9c317b9 changed from POINTER_BUTTON_STATE to simply BUTTON_STATE, replicate that for key events too. Signed-off-by: Peter Hutterer --- src/evdev.c | 4 ++-- src/libinput-private.h | 2 +- src/libinput.c | 12 ++++++------ src/libinput.h | 8 ++++---- test/keyboard.c | 4 ++-- tools/event-debug.c | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index b6412d01..63eaa4df 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -310,8 +310,8 @@ evdev_process_key(struct evdev_device *device, &device->base, time, e->code, - e->value ? LIBINPUT_KEYBOARD_KEY_STATE_PRESSED : - LIBINPUT_KEYBOARD_KEY_STATE_RELEASED); + e->value ? LIBINPUT_KEY_STATE_PRESSED : + LIBINPUT_KEY_STATE_RELEASED); break; } } diff --git a/src/libinput-private.h b/src/libinput-private.h index f0bda1f8..4a92fb95 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -146,7 +146,7 @@ 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); void pointer_notify_motion(struct libinput_device *device, diff --git a/src/libinput.c b/src/libinput.c index c4f7fe12..b468aa76 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -56,7 +56,7 @@ struct libinput_event_keyboard { uint32_t time; uint32_t key; uint32_t seat_key_count; - enum libinput_keyboard_key_state state; + enum libinput_key_state state; }; struct libinput_event_pointer { @@ -285,7 +285,7 @@ libinput_event_keyboard_get_key(struct libinput_event_keyboard *event) return event->key; } -LIBINPUT_EXPORT enum libinput_keyboard_key_state +LIBINPUT_EXPORT enum libinput_key_state libinput_event_keyboard_get_key_state(struct libinput_event_keyboard *event) { return event->state; @@ -717,14 +717,14 @@ libinput_dispatch(struct libinput *libinput) static uint32_t update_seat_key_count(struct libinput_seat *seat, int32_t key, - enum libinput_keyboard_key_state state) + enum libinput_key_state state) { assert(key >= 0 && key <= KEY_MAX); switch (state) { - case LIBINPUT_KEYBOARD_KEY_STATE_PRESSED: + case LIBINPUT_KEY_STATE_PRESSED: return ++seat->button_count[key]; - case LIBINPUT_KEYBOARD_KEY_STATE_RELEASED: + case LIBINPUT_KEY_STATE_RELEASED: /* We might not have received the first PRESSED event. */ if (seat->button_count[key] == 0) return 0; @@ -816,7 +816,7 @@ 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_event; uint32_t seat_key_count; diff --git a/src/libinput.h b/src/libinput.h index b1b1124e..fb2e4907 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -130,9 +130,9 @@ enum libinput_device_capability { * Logical state of a key. Note that the logical state may not represent * the physical state of the key. */ -enum libinput_keyboard_key_state { - LIBINPUT_KEYBOARD_KEY_STATE_RELEASED = 0, - LIBINPUT_KEYBOARD_KEY_STATE_PRESSED = 1 +enum libinput_key_state { + LIBINPUT_KEY_STATE_RELEASED = 0, + LIBINPUT_KEY_STATE_PRESSED = 1 }; /** @@ -382,7 +382,7 @@ libinput_event_keyboard_get_key(struct libinput_event_keyboard *event); * * @return The state change of the key */ -enum libinput_keyboard_key_state +enum libinput_key_state libinput_event_keyboard_get_key_state(struct libinput_event_keyboard *event); diff --git a/test/keyboard.c b/test/keyboard.c index a518b66c..e1af05f7 100644 --- a/test/keyboard.c +++ b/test/keyboard.c @@ -64,7 +64,7 @@ START_TEST(keyboard_seat_key_count) ck_assert_notnull(kev); ck_assert_int_eq(libinput_event_keyboard_get_key(kev), KEY_A); ck_assert_int_eq(libinput_event_keyboard_get_key_state(kev), - LIBINPUT_KEYBOARD_KEY_STATE_PRESSED); + LIBINPUT_KEY_STATE_PRESSED); ++expected_key_button_count; seat_key_count = @@ -93,7 +93,7 @@ START_TEST(keyboard_seat_key_count) ck_assert_notnull(kev); ck_assert_int_eq(libinput_event_keyboard_get_key(kev), KEY_A); ck_assert_int_eq(libinput_event_keyboard_get_key_state(kev), - LIBINPUT_KEYBOARD_KEY_STATE_RELEASED); + LIBINPUT_KEY_STATE_RELEASED); --expected_key_button_count; seat_key_count = diff --git a/tools/event-debug.c b/tools/event-debug.c index 34acfce2..eb43e056 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -247,13 +247,13 @@ static void print_key_event(struct libinput_event *ev) { struct libinput_event_keyboard *k = libinput_event_get_keyboard_event(ev); - enum libinput_keyboard_key_state state; + enum libinput_key_state state; print_event_time(libinput_event_keyboard_get_time(k)); state = libinput_event_keyboard_get_key_state(k); printf("%d %s\n", libinput_event_keyboard_get_key(k), - state == LIBINPUT_KEYBOARD_KEY_STATE_PRESSED ? "pressed" : "released"); + state == LIBINPUT_KEY_STATE_PRESSED ? "pressed" : "released"); } static void From 3f500b657f5e9f90ade90a6f2678d8596cd6b799 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 13 Jun 2014 11:11:05 +1000 Subject: [PATCH 04/22] test: move the interface declaration up No functional changes, just some prep work. Signed-off-by: Peter Hutterer --- test/litest.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/test/litest.c b/test/litest.c index 0a9cc72d..d3f8f0dd 100644 --- a/test/litest.c +++ b/test/litest.c @@ -267,6 +267,23 @@ litest_log_handler(enum libinput_log_priority pri, vfprintf(stderr, format, args); } +static int +open_restricted(const char *path, int flags, void *userdata) +{ + return open(path, flags); +} + +static void +close_restricted(int fd, void *userdata) +{ + close(fd); +} + +struct libinput_interface interface = { + .open_restricted = open_restricted, + .close_restricted = close_restricted, +}; + static const struct option opts[] = { { "list", 0, 0, 'l' }, { "verbose", 0, 0, 'v' }, @@ -335,24 +352,6 @@ litest_run(int argc, char **argv) { return failed; } -static int -open_restricted(const char *path, int flags, void *userdata) -{ - return open(path, flags); -} - -static void -close_restricted(int fd, void *userdata) -{ - close(fd); -} - -const struct libinput_interface interface = { - .open_restricted = open_restricted, - .close_restricted = close_restricted, -}; - - static struct input_absinfo * merge_absinfo(const struct input_absinfo *orig, const struct input_absinfo *override) From 6250397ac8a7a23fb41c726b9555d93ead0f1dc8 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 12 Jun 2014 11:44:31 +1000 Subject: [PATCH 05/22] udev: split libinput_udev context init into two functions This is preparation work for context-specific log handlers. Callers are now encouraged to first initialize the context with libinput_udev_create_context() and then set the seat for this context with libinput_udev_assign_seat(). In the upcoming patch to support context-specific log handlers this enables a caller to set the log handler for a context before any devices are initialized. Otherwise, a log message generated by a new device may pass a libinput context that the caller is not yet aware of. Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede --- doc/libinput.doxygen.in | 3 +- src/libinput.h | 51 +++++++++++++++++++++++++++++++- src/udev-seat.c | 64 ++++++++++++++++++++++++++++++++--------- test/udev.c | 48 +++++++++++++++++-------------- tools/event-debug.c | 8 +++++- tools/event-gui.c | 4 +-- 6 files changed, 139 insertions(+), 39 deletions(-) diff --git a/doc/libinput.doxygen.in b/doc/libinput.doxygen.in index f78b7cf9..9f931c34 100644 --- a/doc/libinput.doxygen.in +++ b/doc/libinput.doxygen.in @@ -1570,7 +1570,8 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = LIBINPUT_ATTRIBUTE_PRINTF(f,a)= +PREDEFINED = LIBINPUT_ATTRIBUTE_PRINTF(f, a)= \ + LIBINPUT_ATTRIBUTE_DEPRECATED # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/src/libinput.h b/src/libinput.h index fb2e4907..678e49dc 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -33,6 +33,7 @@ extern "C" { #define LIBINPUT_ATTRIBUTE_PRINTF(_format, _args) \ __attribute__ ((format (printf, _format, _args))) +#define LIBINPUT_ATTRIBUTE_DEPRECATED __attribute__ ((deprecated)) /** * @mainpage @@ -779,6 +780,49 @@ struct libinput_interface { void (*close_restricted)(int fd, void *user_data); }; +/** + * @ingroup base + * + * Create a new libinput context from udev. This context is inactive until + * assigned a seat ID with libinput_udev_assign_seat(). + * + * @param interface The callback interface + * @param user_data Caller-specific data passed to the various callback + * interfaces. + * @param udev An already initialized udev context + * + * @return An initialized, but inactive libinput context or NULL on error + */ +struct libinput * +libinput_udev_create_context(const struct libinput_interface *interface, + void *user_data, + struct udev *udev); + +/** + * @ingroup base + * + * Assign a seat to this libinput context. New devices or the removal of + * existing devices will appear as events during libinput_dispatch(). + * + * libinput_udev_assign_seat() succeeds even if no input devices are currently + * available on this seat, or if devices are available but fail to open in + * @ref libinput_interface::open_restricted. Devices that do not have the + * minimum capabilities to be recognized as pointer, keyboard or touch + * device are ignored. Such devices and those that failed to open + * ignored until the next call to libinput_resume(). + * + * This function may only be called once per context. + * + * @param libinput A libinput context initialized with + * libinput_udev_create_context() + * @param seat_id A seat identifier. This string must not be NULL. + * + * @return 0 on success or -1 on failure. + */ +int +libinput_udev_assign_seat(struct libinput *libinput, + const char *seat_id); + /** * @ingroup base * @@ -801,12 +845,17 @@ struct libinput_interface { * * @return An initialized libinput context, ready to handle events or NULL on * error. + * + * @deprecated This function was deprecated in 0.4.0 and will be removed + * soon. Use libinput_udev_create_context() and libinput_udev_assign_seat() + * instead. */ struct libinput * libinput_udev_create_for_seat(const struct libinput_interface *interface, void *user_data, struct udev *udev, - const char *seat_id); + const char *seat_id) + LIBINPUT_ATTRIBUTE_DEPRECATED; /** * @ingroup base diff --git a/src/udev-seat.c b/src/udev-seat.c index 38a13b72..89160ff8 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -333,14 +333,13 @@ static const struct libinput_interface_backend interface_backend = { }; LIBINPUT_EXPORT struct libinput * -libinput_udev_create_for_seat(const struct libinput_interface *interface, - void *user_data, - struct udev *udev, - const char *seat_id) +libinput_udev_create_context(const struct libinput_interface *interface, + void *user_data, + struct udev *udev) { struct udev_input *input; - if (!interface || !udev || !seat_id) + if (!interface || !udev) return NULL; input = zalloc(sizeof *input); @@ -354,14 +353,53 @@ libinput_udev_create_for_seat(const struct libinput_interface *interface, } input->udev = udev_ref(udev); - input->seat_id = strdup(seat_id); - - if (udev_input_enable(&input->base) < 0) { - udev_unref(udev); - libinput_destroy(&input->base); - free(input); - return NULL; - } return &input->base; } + +LIBINPUT_EXPORT int +libinput_udev_assign_seat(struct libinput *libinput, + const char *seat_id) +{ + struct udev_input *input = (struct udev_input*)libinput; + + if (!seat_id) + return -1; + if (input->seat_id != NULL) + return -1; + + if (libinput->interface_backend != &interface_backend) { + log_bug_client("Mismatching backends.\n"); + return -1; + } + + input->seat_id = strdup(seat_id); + + if (udev_input_enable(&input->base) < 0) + return -1; + + return 0; +} + +LIBINPUT_EXPORT struct libinput * +libinput_udev_create_for_seat(const struct libinput_interface *interface, + void *user_data, + struct udev *udev, + const char *seat_id) +{ + struct libinput *libinput; + + if (!interface || !udev || !seat_id) + return NULL; + + libinput = libinput_udev_create_context(interface, user_data, udev); + if (!libinput) + return NULL; + + if (libinput_udev_assign_seat(libinput, seat_id) != 0) { + libinput_destroy(libinput); + libinput = NULL; + } + + return libinput; +} diff --git a/test/udev.c b/test/udev.c index 6af2cb08..d13c6e24 100644 --- a/test/udev.c +++ b/test/udev.c @@ -52,26 +52,24 @@ START_TEST(udev_create_NULL) { struct libinput *li; const struct libinput_interface interface; - struct udev *udev = (struct udev*)0xdeadbeef; - const char *seat = (const char*)0xdeaddead; + struct udev *udev; - li = libinput_udev_create_for_seat(NULL, NULL, NULL, NULL); + udev = udev_new(); + + li = libinput_udev_create_context(NULL, NULL, NULL); ck_assert(li == NULL); - li = libinput_udev_create_for_seat(&interface, NULL, NULL, NULL); - ck_assert(li == NULL); - li = libinput_udev_create_for_seat(NULL, NULL, udev, NULL); - ck_assert(li == NULL); - li = libinput_udev_create_for_seat(NULL, NULL, NULL, seat); + li = libinput_udev_create_context(&interface, NULL, NULL); ck_assert(li == NULL); - li = libinput_udev_create_for_seat(&interface, NULL, udev, NULL); - ck_assert(li == NULL); - li = libinput_udev_create_for_seat(NULL, NULL, udev, seat); + li = libinput_udev_create_context(NULL, NULL, udev); ck_assert(li == NULL); - li = libinput_udev_create_for_seat(&interface, NULL, NULL, seat); - ck_assert(li == NULL); + li = libinput_udev_create_context(&interface, NULL, udev); + ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, NULL), -1); + libinput_destroy(li); + udev_unref(udev); } END_TEST @@ -85,8 +83,9 @@ START_TEST(udev_create_seat0) udev = udev_new(); ck_assert(udev != NULL); - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); fd = libinput_get_fd(li); ck_assert_int_ge(fd, 0); @@ -113,8 +112,9 @@ START_TEST(udev_create_empty_seat) ck_assert(udev != NULL); /* expect a libinput reference, but no events */ - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seatdoesntexist"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seatdoesntexist"), 0); fd = libinput_get_fd(li); ck_assert_int_ge(fd, 0); @@ -147,8 +147,9 @@ START_TEST(udev_added_seat_default) udev = udev_new(); ck_assert(udev != NULL); - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); libinput_dispatch(li); while (!default_seat_found && (event = libinput_get_event(li))) { @@ -184,8 +185,9 @@ START_TEST(udev_double_suspend) udev = udev_new(); ck_assert(udev != NULL); - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); fd = libinput_get_fd(li); ck_assert_int_ge(fd, 0); @@ -215,8 +217,9 @@ START_TEST(udev_double_resume) udev = udev_new(); ck_assert(udev != NULL); - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); fd = libinput_get_fd(li); ck_assert_int_ge(fd, 0); @@ -266,8 +269,9 @@ START_TEST(udev_suspend_resume) udev = udev_new(); ck_assert(udev != NULL); - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); fd = libinput_get_fd(li); ck_assert_int_ge(fd, 0); @@ -305,8 +309,9 @@ START_TEST(udev_device_sysname) udev = udev_new(); ck_assert(udev != NULL); - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); libinput_dispatch(li); @@ -342,8 +347,9 @@ START_TEST(udev_seat_recycle) udev = udev_new(); ck_assert(udev != NULL); - li = libinput_udev_create_for_seat(&simple_interface, NULL, udev, "seat0"); + li = libinput_udev_create_context(&simple_interface, NULL, udev); ck_assert(li != NULL); + ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0); libinput_dispatch(li); while ((ev = libinput_get_event(li))) { diff --git a/tools/event-debug.c b/tools/event-debug.c index eb43e056..2547da53 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -140,12 +140,18 @@ open_udev(struct libinput **li) return 1; } - *li = libinput_udev_create_for_seat(&interface, NULL, udev, seat); + *li = libinput_udev_create_context(&interface, NULL, udev); if (!*li) { fprintf(stderr, "Failed to initialize context from udev\n"); return 1; } + if (libinput_udev_assign_seat(*li, seat)) { + fprintf(stderr, "Failed to set seat\n"); + libinput_destroy(*li); + return 1; + } + return 0; } diff --git a/tools/event-gui.c b/tools/event-gui.c index 95540936..df86a520 100644 --- a/tools/event-gui.c +++ b/tools/event-gui.c @@ -458,8 +458,8 @@ main(int argc, char *argv[]) if (!udev) error("Failed to initialize udev\n"); - li = libinput_udev_create_for_seat(&interface, &w, udev, "seat0"); - if (!li) + li = libinput_udev_create_context(&interface, &w, udev); + if (!li || libinput_udev_assign_seat(li, "seat0") != 0) error("Failed to initialize context from udev\n"); window_init(&w); From 97a6bf10f95859940379787da2635b69399db40c Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 18 Jun 2014 19:51:19 +1000 Subject: [PATCH 06/22] Change the logging system to be per-context Rather than a single global logging function, make the logging dependent on the individual context. This way we won't stomp on each other's feet in the (admittedly unusual) case of having multiple libinput contexts. The userdata argument to the log handler was dropped. The caller has a ref to the libinput context now, any userdata can be attached to that context instead. Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede --- src/evdev-mt-touchpad-buttons.c | 15 ++++-- src/evdev-mt-touchpad-tap.c | 13 +++-- src/evdev.c | 23 ++++++--- src/libinput-private.h | 23 ++++++--- src/libinput.c | 48 ++++++++---------- src/libinput.h | 19 ++++--- src/path.c | 20 +++++--- src/timer.c | 4 +- src/udev-seat.c | 17 ++++--- test/litest.c | 13 +++-- test/log.c | 88 +++++++++------------------------ tools/event-debug.c | 33 +++++++------ 12 files changed, 161 insertions(+), 155 deletions(-) diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c index 45d5d703..2ac231c7 100644 --- a/src/evdev-mt-touchpad-buttons.c +++ b/src/evdev-mt-touchpad-buttons.c @@ -452,6 +452,7 @@ tp_button_handle_event(struct tp_dispatch *tp, enum button_event event, uint64_t time) { + struct libinput *libinput = tp->device->base.seat->libinput; enum button_state current = t->button.state; switch(t->button.state) { @@ -485,7 +486,8 @@ tp_button_handle_event(struct tp_dispatch *tp, } if (current != t->button.state) - log_debug("button state: from %s, event %s to %s\n", + log_debug(libinput, + "button state: from %s, event %s to %s\n", button_state_to_str(current), button_event_to_str(event), button_state_to_str(t->button.state)); @@ -538,11 +540,13 @@ tp_process_button(struct tp_dispatch *tp, const struct input_event *e, uint64_t time) { + struct libinput *libinput = tp->device->base.seat->libinput; uint32_t mask = 1 << (e->code - BTN_LEFT); /* Ignore other buttons on clickpads */ if (tp->buttons.is_clickpad && e->code != BTN_LEFT) { - log_bug_kernel("received %s button event on a clickpad\n", + log_bug_kernel(libinput, + "received %s button event on a clickpad\n", libevdev_event_code_get_name(EV_KEY, e->code)); return 0; } @@ -562,6 +566,7 @@ int tp_init_buttons(struct tp_dispatch *tp, struct evdev_device *device) { + struct libinput *libinput = tp->device->base.seat->libinput; struct tp_touch *t; int width, height; double diagonal; @@ -575,10 +580,12 @@ tp_init_buttons(struct tp_dispatch *tp, if (libevdev_has_event_code(device->evdev, EV_KEY, BTN_MIDDLE) || libevdev_has_event_code(device->evdev, EV_KEY, BTN_RIGHT)) { if (tp->buttons.is_clickpad) - log_bug_kernel("clickpad advertising right button\n"); + log_bug_kernel(libinput, + "clickpad advertising right button\n"); } else { if (!tp->buttons.is_clickpad) - log_bug_kernel("non clickpad without right button?\n"); + log_bug_kernel(libinput, + "non clickpad without right button?\n"); } absinfo_x = device->abs.absinfo_x; diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c index 34bb0d0b..25412184 100644 --- a/src/evdev-mt-touchpad-tap.c +++ b/src/evdev-mt-touchpad-tap.c @@ -130,6 +130,7 @@ tp_tap_clear_timer(struct tp_dispatch *tp) static void tp_tap_idle_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time) { + struct libinput *libinput = tp->device->base.seat->libinput; switch (event) { case TAP_EVENT_TOUCH: @@ -138,7 +139,8 @@ tp_tap_idle_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t break; case TAP_EVENT_RELEASE: case TAP_EVENT_MOTION: - log_bug_libinput("invalid event, no fingers are down\n"); + log_bug_libinput(libinput, + "invalid event, no fingers are down\n"); break; case TAP_EVENT_TIMEOUT: break; @@ -197,11 +199,13 @@ tp_tap_hold_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t static void tp_tap_tapped_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time) { + struct libinput *libinput = tp->device->base.seat->libinput; switch (event) { case TAP_EVENT_MOTION: case TAP_EVENT_RELEASE: - log_bug_libinput("invalid event when fingers are up\n"); + log_bug_libinput(libinput, + "invalid event when fingers are up\n"); break; case TAP_EVENT_TOUCH: tp->tap.state = TAP_STATE_DRAGGING_OR_DOUBLETAP; @@ -426,7 +430,9 @@ tp_tap_dead_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t static void tp_tap_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time) { + struct libinput *libinput = tp->device->base.seat->libinput; enum tp_tap_state current; + if (!tp->tap.enabled) return; @@ -477,7 +483,8 @@ tp_tap_handle_event(struct tp_dispatch *tp, enum tap_event event, uint64_t time) if (tp->tap.state == TAP_STATE_IDLE || tp->tap.state == TAP_STATE_DEAD) tp_tap_clear_timer(tp); - log_debug("tap state: %s → %s → %s\n", + log_debug(libinput, + "tap state: %s → %s → %s\n", tap_state_to_str(current), tap_event_to_str(event), tap_state_to_str(tp->tap.state)); diff --git a/src/evdev.c b/src/evdev.c index 63eaa4df..f72bd43e 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -115,6 +115,7 @@ evdev_device_transform_y(struct evdev_device *device, static void evdev_flush_pending_event(struct evdev_device *device, uint64_t time) { + struct libinput *libinput = device->base.seat->libinput; struct motion_params motion; int32_t cx, cy; double x, y; @@ -147,7 +148,8 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time) break; if (device->mt.slots[slot].seat_slot != -1) { - log_bug_kernel("%s: Driver sent multiple touch down for the " + log_bug_kernel(libinput, + "%s: Driver sent multiple touch down for the " "same slot", device->devnode); break; } @@ -196,7 +198,8 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time) break; if (device->abs.seat_slot != -1) { - log_bug_kernel("%s: Driver sent multiple touch down for the " + log_bug_kernel(libinput, + "%s: Driver sent multiple touch down for the " "same slot", device->devnode); break; } @@ -591,6 +594,7 @@ configure_pointer_acceleration(struct evdev_device *device) static int evdev_configure_device(struct evdev_device *device) { + struct libinput *libinput = device->base.seat->libinput; struct libevdev *evdev = device->evdev; const struct input_absinfo *absinfo; struct input_absinfo fixed; @@ -696,7 +700,8 @@ evdev_configure_device(struct evdev_device *device) !libevdev_has_event_code(evdev, EV_KEY, BTN_TOOL_PEN) && (has_abs || has_mt)) { device->dispatch = evdev_mt_touchpad_create(device); - log_info("input device '%s', %s is a touchpad\n", + log_info(libinput, + "input device '%s', %s is a touchpad\n", device->devname, device->devnode); } for (i = KEY_ESC; i < KEY_MAX; i++) { @@ -725,7 +730,8 @@ evdev_configure_device(struct evdev_device *device) device->seat_caps |= EVDEV_DEVICE_POINTER; - log_info("input device '%s', %s is a pointer caps =%s%s%s\n", + log_info(libinput, + "input device '%s', %s is a pointer caps =%s%s%s\n", device->devname, device->devnode, has_abs ? " absolute-motion" : "", has_rel ? " relative-motion": "", @@ -733,12 +739,14 @@ evdev_configure_device(struct evdev_device *device) } if (has_keyboard) { device->seat_caps |= EVDEV_DEVICE_KEYBOARD; - log_info("input device '%s', %s is a keyboard\n", + log_info(libinput, + "input device '%s', %s is a keyboard\n", device->devname, device->devnode); } if (has_touch && !has_button) { device->seat_caps |= EVDEV_DEVICE_TOUCH; - log_info("input device '%s', %s is a touch device\n", + log_info(libinput, + "input device '%s', %s is a touch device\n", device->devname, device->devnode); } @@ -761,7 +769,8 @@ evdev_device_create(struct libinput_seat *seat, * read. mtdev_get() also expects this. */ fd = open_restricted(libinput, devnode, O_RDWR | O_NONBLOCK); if (fd < 0) { - log_info("opening input device '%s' failed (%s).\n", + log_info(libinput, + "opening input device '%s' failed (%s).\n", devnode, strerror(-fd)); return NULL; } diff --git a/src/libinput-private.h b/src/libinput-private.h index 4a92fb95..e3d9bb1e 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -56,6 +56,9 @@ struct libinput { const struct libinput_interface *interface; const struct libinput_interface_backend *interface_backend; + + libinput_log_handler log_handler; + enum libinput_log_priority log_priority; void *user_data; }; @@ -88,17 +91,21 @@ struct libinput_device { typedef void (*libinput_source_dispatch_t)(void *data); -#define log_debug(...) log_msg(LIBINPUT_LOG_PRIORITY_DEBUG, __VA_ARGS__) -#define log_info(...) log_msg(LIBINPUT_LOG_PRIORITY_INFO, __VA_ARGS__) -#define log_error(...) log_msg(LIBINPUT_LOG_PRIORITY_ERROR, __VA_ARGS__) -#define log_bug_kernel(...) log_msg(LIBINPUT_LOG_PRIORITY_ERROR, "kernel bug: " __VA_ARGS__) -#define log_bug_libinput(...) log_msg(LIBINPUT_LOG_PRIORITY_ERROR, "libinput bug: " __VA_ARGS__); -#define log_bug_client(...) log_msg(LIBINPUT_LOG_PRIORITY_ERROR, "client bug: " __VA_ARGS__); +#define log_debug(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_DEBUG, __VA_ARGS__) +#define log_info(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_INFO, __VA_ARGS__) +#define log_error(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_ERROR, __VA_ARGS__) +#define log_bug_kernel(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_ERROR, "kernel bug: " __VA_ARGS__) +#define log_bug_libinput(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_ERROR, "libinput bug: " __VA_ARGS__); +#define log_bug_client(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_ERROR, "client bug: " __VA_ARGS__); void -log_msg(enum libinput_log_priority priority, const char *format, ...); +log_msg(struct libinput *libinput, + enum libinput_log_priority priority, + const char *format, ...); + void -log_msg_va(enum libinput_log_priority priority, +log_msg_va(struct libinput *libinput, + enum libinput_log_priority priority, const char *format, va_list args); diff --git a/src/libinput.c b/src/libinput.c index b468aa76..91557776 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -81,8 +81,8 @@ struct libinput_event_touch { }; static void -libinput_default_log_func(enum libinput_log_priority priority, - void *data, +libinput_default_log_func(struct libinput *libinput, + enum libinput_log_priority priority, const char *format, va_list args) { const char *prefix; @@ -98,55 +98,47 @@ libinput_default_log_func(enum libinput_log_priority priority, vfprintf(stderr, format, args); } -struct log_data { - enum libinput_log_priority priority; - libinput_log_handler handler; - void *user_data; -}; - -static struct log_data log_data = { - .priority = LIBINPUT_LOG_PRIORITY_ERROR, - .handler = libinput_default_log_func, - .user_data = NULL, -}; - void -log_msg_va(enum libinput_log_priority priority, +log_msg_va(struct libinput *libinput, + enum libinput_log_priority priority, const char *format, va_list args) { - if (log_data.handler && log_data.priority <= priority) - log_data.handler(priority, log_data.user_data, format, args); + if (libinput->log_handler && + libinput->log_priority <= priority) + libinput->log_handler(libinput, priority, format, args); } void -log_msg(enum libinput_log_priority priority, const char *format, ...) +log_msg(struct libinput *libinput, + enum libinput_log_priority priority, + const char *format, ...) { va_list args; va_start(args, format); - log_msg_va(priority, format, args); + log_msg_va(libinput, priority, format, args); va_end(args); } LIBINPUT_EXPORT void -libinput_log_set_priority(enum libinput_log_priority priority) +libinput_log_set_priority(struct libinput *libinput, + enum libinput_log_priority priority) { - log_data.priority = priority; + libinput->log_priority = priority; } LIBINPUT_EXPORT enum libinput_log_priority -libinput_log_get_priority(void) +libinput_log_get_priority(const struct libinput *libinput) { - return log_data.priority; + return libinput->log_priority; } LIBINPUT_EXPORT void -libinput_log_set_handler(libinput_log_handler log_handler, - void *user_data) +libinput_log_set_handler(struct libinput *libinput, + libinput_log_handler log_handler) { - log_data.handler = log_handler; - log_data.user_data = user_data; + libinput->log_handler = log_handler; } static void @@ -499,6 +491,8 @@ 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; diff --git a/src/libinput.h b/src/libinput.h index 678e49dc..5e75cc2c 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -1032,13 +1032,15 @@ libinput_destroy(struct libinput *libinput); * * The default log priority is LIBINPUT_LOG_PRIORITY_ERROR. * + * @param libinput A previously initialized libinput context * @param priority The minimum priority of log messages to print. * * @see libinput_log_set_handler * @see libinput_log_get_priority */ void -libinput_log_set_priority(enum libinput_log_priority priority); +libinput_log_set_priority(struct libinput *libinput, + enum libinput_log_priority priority); /** * @ingroup base @@ -1048,30 +1050,30 @@ libinput_log_set_priority(enum libinput_log_priority priority); * * The default log priority is LIBINPUT_LOG_PRIORITY_ERROR. * + * @param libinput A previously initialized libinput context * @return The minimum priority of log messages to print. * * @see libinput_log_set_handler * @see libinput_log_set_priority */ enum libinput_log_priority -libinput_log_get_priority(void); +libinput_log_get_priority(const struct libinput *libinput); /** * @ingroup base * * Log handler type for custom logging. * + * @param libinput The libinput context * @param priority The priority of the current message - * @param user_data Caller-specific data pointer as previously passed into - * libinput_log_set_handler() * @param format Message format in printf-style * @param args Message arguments * * @see libinput_set_log_priority * @see libinput_log_set_handler */ -typedef void (*libinput_log_handler)(enum libinput_log_priority priority, - void *user_data, +typedef void (*libinput_log_handler)(struct libinput *libinput, + enum libinput_log_priority priority, const char *format, va_list args) LIBINPUT_ATTRIBUTE_PRINTF(3, 0); @@ -1084,6 +1086,7 @@ typedef void (*libinput_log_handler)(enum libinput_log_priority priority, * * The default log handler prints to stderr. * + * @param libinput A previously initialized libinput context * @param log_handler The log handler for library messages. * @param user_data Caller-specific data pointer, passed into the log * handler. @@ -1091,8 +1094,8 @@ typedef void (*libinput_log_handler)(enum libinput_log_priority priority, * @see libinput_log_set_handler */ void -libinput_log_set_handler(libinput_log_handler log_handler, - void *user_data); +libinput_log_set_handler(struct libinput *libinput, + libinput_log_handler log_handler); /** * @defgroup seat Initialization and manipulation of seats diff --git a/src/path.c b/src/path.c index 27e5ad63..e9c0ee8d 100644 --- a/src/path.c +++ b/src/path.c @@ -160,7 +160,9 @@ path_device_enable(struct path_input *input, const char *devnode) if (path_get_udev_properties(devnode, &sysname, &seat_name, &seat_logical_name) == -1) { - log_info("failed to obtain sysname for device '%s'.\n", devnode); + log_info(&input->base, + "failed to obtain sysname for device '%s'.\n", + devnode); return NULL; } @@ -171,7 +173,9 @@ path_device_enable(struct path_input *input, const char *devnode) } else { seat = path_seat_create(input, seat_name, seat_logical_name); if (!seat) { - log_info("failed to create seat for device '%s'.\n", devnode); + log_info(&input->base, + "failed to create seat for device '%s'.\n", + devnode); goto out; } } @@ -181,10 +185,14 @@ path_device_enable(struct path_input *input, const char *devnode) if (device == EVDEV_UNHANDLED_DEVICE) { device = NULL; - log_info("not using input device '%s'.\n", devnode); + log_info(&input->base, + "not using input device '%s'.\n", + devnode); goto out; } else if (device == NULL) { - log_info("failed to create input device '%s'.\n", devnode); + log_info(&input->base, + "failed to create input device '%s'.\n", + devnode); goto out; } @@ -264,7 +272,7 @@ libinput_path_add_device(struct libinput *libinput, struct libinput_device *device; if (libinput->interface_backend != &interface_backend) { - log_bug_client("Mismatching backends.\n"); + log_bug_client(libinput, "Mismatching backends.\n"); return NULL; } @@ -301,7 +309,7 @@ libinput_path_remove_device(struct libinput_device *device) struct path_device *dev; if (libinput->interface_backend != &interface_backend) { - log_bug_client("Mismatching backends.\n"); + log_bug_client(libinput, "Mismatching backends.\n"); return; } diff --git a/src/timer.c b/src/timer.c index 65fdd17a..f5461858 100644 --- a/src/timer.c +++ b/src/timer.c @@ -59,7 +59,7 @@ libinput_timer_arm_timer_fd(struct libinput *libinput) r = timerfd_settime(libinput->timer.fd, TFD_TIMER_ABSTIME, &its, NULL); if (r) - log_error("timerfd_settime error: %s\n", strerror(errno)); + log_error(libinput, "timerfd_settime error: %s\n", strerror(errno)); } void @@ -96,7 +96,7 @@ libinput_timer_handler(void *data) r = clock_gettime(CLOCK_MONOTONIC, &ts); if (r) { - log_error("clock_gettime error: %s\n", strerror(errno)); + log_error(libinput, "clock_gettime error: %s\n", strerror(errno)); return; } diff --git a/src/udev-seat.c b/src/udev-seat.c index 89160ff8..9082697f 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -80,10 +80,10 @@ device_added(struct udev_device *udev_device, struct udev_input *input) libinput_seat_unref(&seat->base); if (device == EVDEV_UNHANDLED_DEVICE) { - log_info("not using input device '%s'.\n", devnode); + log_info(&input->base, "not using input device '%s'.\n", devnode); return 0; } else if (device == NULL) { - log_info("failed to create input device '%s'.\n", devnode); + log_info(&input->base, "failed to create input device '%s'.\n", devnode); return 0; } @@ -100,7 +100,8 @@ 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; - log_info("Applying calibration: %f %f %f %f %f %f\n", + log_info(&input->base, + "Applying calibration: %f %f %f %f %f %f\n", device->abs.calibration[0], device->abs.calibration[1], device->abs.calibration[2], @@ -128,7 +129,8 @@ device_removed(struct udev_device *udev_device, struct udev_input *input) list_for_each_safe(device, next, &seat->base.devices_list, base.link) { if (!strcmp(device->devnode, devnode)) { - log_info("input device %s, %s removed\n", + log_info(&input->base, + "input device %s, %s removed\n", device->devname, device->devnode); evdev_device_remove(device); break; @@ -243,7 +245,8 @@ udev_input_enable(struct libinput *libinput) input->udev_monitor = udev_monitor_new_from_netlink(udev, "udev"); if (!input->udev_monitor) { - log_info("udev: failed to create the udev monitor\n"); + log_info(libinput, + "udev: failed to create the udev monitor\n"); return -1; } @@ -251,7 +254,7 @@ udev_input_enable(struct libinput *libinput) "input", NULL); if (udev_monitor_enable_receiving(input->udev_monitor)) { - log_info("udev: failed to bind the udev monitor\n"); + log_info(libinput, "udev: failed to bind the udev monitor\n"); udev_monitor_unref(input->udev_monitor); input->udev_monitor = NULL; return -1; @@ -369,7 +372,7 @@ libinput_udev_assign_seat(struct libinput *libinput, return -1; if (libinput->interface_backend != &interface_backend) { - log_bug_client("Mismatching backends.\n"); + log_bug_client(libinput, "Mismatching backends.\n"); return -1; } diff --git a/test/litest.c b/test/litest.c index d3f8f0dd..793d72f7 100644 --- a/test/litest.c +++ b/test/litest.c @@ -44,6 +44,7 @@ #include "libinput-util.h" static int in_debugger = -1; +static int verbose = 0; struct test { struct list node; @@ -250,8 +251,8 @@ litest_list_tests(struct list *tests) } static void -litest_log_handler(enum libinput_log_priority pri, - void *user_data, +litest_log_handler(struct libinput *libinput, + enum libinput_log_priority pri, const char *format, va_list args) { @@ -321,8 +322,7 @@ litest_run(int argc, char **argv) { litest_list_tests(&all_tests); return 0; case 'v': - libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_DEBUG); - libinput_log_set_handler(litest_log_handler, NULL); + verbose = 1; break; default: fprintf(stderr, "usage: %s [--list]\n", argv[0]); @@ -482,6 +482,11 @@ litest_create_context(void) struct libinput *libinput = libinput_path_create_context(&interface, NULL); ck_assert_notnull(libinput); + + libinput_log_set_handler(libinput, litest_log_handler); + if (verbose) + libinput_log_set_priority(libinput, LIBINPUT_LOG_PRIORITY_DEBUG); + return libinput; } diff --git a/test/log.c b/test/log.c index a2818207..02ed4f08 100644 --- a/test/log.c +++ b/test/log.c @@ -32,7 +32,7 @@ #include "litest.h" static int log_handler_called; -static void *log_handler_userdata; +static struct libinput *log_handler_context; static int open_restricted(const char *path, int flags, void *data) { @@ -51,56 +51,41 @@ const struct libinput_interface simple_interface = { }; static void -simple_log_handler(enum libinput_log_priority priority, - void *userdata, +simple_log_handler(struct libinput *libinput, + enum libinput_log_priority priority, const char *format, va_list args) { log_handler_called++; - ck_assert(userdata == log_handler_userdata); + if (log_handler_context) + ck_assert(libinput == log_handler_context); ck_assert(format != NULL); } START_TEST(log_default_priority) { enum libinput_log_priority pri; + struct libinput *li; - pri = libinput_log_get_priority(); + li = libinput_path_create_context(&simple_interface, NULL); + pri = libinput_log_get_priority(li); ck_assert_int_eq(pri, LIBINPUT_LOG_PRIORITY_ERROR); + + libinput_destroy(li); } END_TEST START_TEST(log_handler_invoked) { struct libinput *li; - enum libinput_log_priority pri = libinput_log_get_priority(); - - libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_DEBUG); - libinput_log_set_handler(simple_log_handler, NULL); - log_handler_userdata = NULL; li = libinput_path_create_context(&simple_interface, NULL); - libinput_path_add_device(li, "/tmp"); - ck_assert_int_gt(log_handler_called, 0); - log_handler_called = 0; + libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG); + libinput_log_set_handler(li, simple_log_handler); + log_handler_context = li; - libinput_destroy(li); - libinput_log_set_priority(pri); -} -END_TEST - -START_TEST(log_userdata_NULL) -{ - struct libinput *li; - enum libinput_log_priority pri = libinput_log_get_priority(); - - libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_DEBUG); - libinput_log_set_handler(simple_log_handler, NULL); - log_handler_userdata = NULL; - - li = libinput_path_create_context(&simple_interface, NULL); libinput_path_add_device(li, "/tmp"); ck_assert_int_gt(log_handler_called, 0); @@ -108,73 +93,48 @@ START_TEST(log_userdata_NULL) libinput_destroy(li); - libinput_log_set_priority(pri); -} -END_TEST - -START_TEST(log_userdata) -{ - struct libinput *li; - enum libinput_log_priority pri = libinput_log_get_priority(); - - libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_DEBUG); - libinput_log_set_handler(simple_log_handler, &li); - log_handler_userdata = &li; - - li = libinput_path_create_context(&simple_interface, NULL); - libinput_path_add_device(li, "/tmp"); - - ck_assert_int_gt(log_handler_called, 0); - log_handler_called = 0; - - libinput_destroy(li); - libinput_log_set_priority(pri); + log_handler_context = NULL; } END_TEST START_TEST(log_handler_NULL) { struct libinput *li; - enum libinput_log_priority pri = libinput_log_get_priority(); - - libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_DEBUG); - libinput_log_set_handler(NULL, NULL); - log_handler_userdata = NULL; li = libinput_path_create_context(&simple_interface, NULL); + libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG); + libinput_log_set_handler(li, NULL); + libinput_path_add_device(li, "/tmp"); ck_assert_int_eq(log_handler_called, 0); log_handler_called = 0; - libinput_log_set_handler(simple_log_handler, NULL); libinput_destroy(li); - libinput_log_set_priority(pri); } END_TEST START_TEST(log_priority) { struct libinput *li; - enum libinput_log_priority pri = libinput_log_get_priority(); - - libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_ERROR); - libinput_log_set_handler(simple_log_handler, NULL); - log_handler_userdata = NULL; li = libinput_path_create_context(&simple_interface, NULL); + libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_ERROR); + libinput_log_set_handler(li, simple_log_handler); + log_handler_context = li; + libinput_path_add_device(li, "/tmp"); ck_assert_int_eq(log_handler_called, 0); - libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_INFO); + libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_INFO); libinput_path_add_device(li, "/tmp"); ck_assert_int_gt(log_handler_called, 0); log_handler_called = 0; libinput_destroy(li); - libinput_log_set_priority(pri); + log_handler_context = NULL; } END_TEST @@ -182,8 +142,6 @@ int main (int argc, char **argv) { litest_add_no_device("log:defaults", log_default_priority); litest_add_no_device("log:logging", log_handler_invoked); litest_add_no_device("log:logging", log_handler_NULL); - litest_add_no_device("log:logging", log_userdata); - litest_add_no_device("log:logging", log_userdata_NULL); litest_add_no_device("log:logging", log_priority); return litest_run(argc, argv); diff --git a/tools/event-debug.c b/tools/event-debug.c index 2547da53..824c6b20 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -131,6 +131,15 @@ static const struct libinput_interface interface = { .close_restricted = close_restricted, }; +static void +log_handler(struct libinput *li, + enum libinput_log_priority priority, + const char *format, + va_list args) +{ + vprintf(format, args); +} + static int open_udev(struct libinput **li) { @@ -146,6 +155,11 @@ open_udev(struct libinput **li) return 1; } + if (verbose) { + libinput_log_set_handler(*li, log_handler); + libinput_log_set_priority(*li, LIBINPUT_LOG_PRIORITY_DEBUG); + } + if (libinput_udev_assign_seat(*li, seat)) { fprintf(stderr, "Failed to set seat\n"); libinput_destroy(*li); @@ -166,6 +180,11 @@ open_device(struct libinput **li, const char *path) return 1; } + if (verbose) { + libinput_log_set_handler(*li, log_handler); + libinput_log_set_priority(*li, LIBINPUT_LOG_PRIORITY_DEBUG); + } + device = libinput_path_add_device(*li, path); if (!device) { fprintf(stderr, "Failed to initialized device %s\n", path); @@ -447,15 +466,6 @@ mainloop(struct libinput *li) close(fds[1].fd); } -static void -log_handler(enum libinput_log_priority priority, - void *user_data, - const char *format, - va_list args) -{ - vprintf(format, args); -} - int main(int argc, char **argv) { @@ -465,11 +475,6 @@ main(int argc, char **argv) if (parse_args(argc, argv)) return 1; - if (verbose) { - libinput_log_set_handler(log_handler, NULL); - libinput_log_set_priority(LIBINPUT_LOG_PRIORITY_DEBUG); - } - if (mode == MODE_UDEV) { if (open_udev(&li)) return 1; From 86c5fba0d294fba1d09224b48ff1ead9a5d5dad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 23 Jun 2014 23:32:29 +0200 Subject: [PATCH 07/22] event-gui: Don't drop fraction of pointer motion events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonas Ådahl --- tools/event-gui.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/event-gui.c b/tools/event-gui.c index 95540936..e080ea86 100644 --- a/tools/event-gui.c +++ b/tools/event-gui.c @@ -53,7 +53,7 @@ struct window { int width, height; /* of window */ /* sprite position */ - int x, y; + double x, y; /* abs position */ int absx, absy; @@ -233,10 +233,10 @@ handle_event_motion(struct libinput_event *ev, struct window *w) double dx = libinput_event_pointer_get_dx(p), dy = libinput_event_pointer_get_dy(p); - w->x += (int)dx; - w->y += (int)dy; - w->x = clip(w->x, 0, w->width); - w->y = clip(w->y, 0, w->height); + w->x += dx; + w->y += dy; + w->x = clip(w->x, 0.0, w->width); + w->y = clip(w->y, 0.0, w->height); } static void From 13e9a1d7449d3b5db1dc7d9cf3aa6187911ee08c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 25 Jun 2014 00:06:57 +0200 Subject: [PATCH 08/22] Make ref count unref/ref() functions return resulting object pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to know if an unref() destroyed an object and to allow more convenient use of ref(), make both functions return a pointer to the object it was passed, or NULL if that object was destroyed. Signed-off-by: Jonas Ådahl Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- src/libinput.c | 22 ++++++++++++++++------ src/libinput.h | 12 ++++++++---- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/libinput.c b/src/libinput.c index c4f7fe12..d4d57117 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -607,10 +607,11 @@ libinput_seat_init(struct libinput_seat *seat, 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 @@ -622,13 +623,17 @@ libinput_seat_destroy(struct libinput_seat *seat) 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 @@ -663,10 +668,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 @@ -675,13 +681,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 diff --git a/src/libinput.h b/src/libinput.h index b1b1124e..3503b76f 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -1080,8 +1080,9 @@ libinput_log_set_handler(libinput_log_handler log_handler, * the seat correctly to avoid dangling pointers. * * @param seat A previously obtained seat + * @return The passed seat */ -void +struct libinput_seat * libinput_seat_ref(struct libinput_seat *seat); /** @@ -1093,8 +1094,9 @@ libinput_seat_ref(struct libinput_seat *seat); * the seat correctly to avoid dangling pointers. * * @param seat A previously obtained seat + * @return NULL if seat was destroyed, otherwise the passed seat */ -void +struct libinput_seat * libinput_seat_unref(struct libinput_seat *seat); /** @@ -1167,8 +1169,9 @@ libinput_seat_get_logical_name(struct libinput_seat *seat); * the device correctly to avoid dangling pointers. * * @param device A previously obtained device + * @return The passed device */ -void +struct libinput_device * libinput_device_ref(struct libinput_device *device); /** @@ -1180,8 +1183,9 @@ libinput_device_ref(struct libinput_device *device); * the device correctly to avoid dangling pointers. * * @param device A previously obtained device + * @return NULL if device was destroyed, otherwise the passed device */ -void +struct libinput_device * libinput_device_unref(struct libinput_device *device); /** From faab25c25cd9cf1b76962e9cb8b26c2c754c0cde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 25 Jun 2014 00:06:58 +0200 Subject: [PATCH 09/22] Make context reference counted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of only allowing one owner keeping a libinput context alive, make context reference counted, replacing libinput_destroy() with libinput_unref() while adding another function libinput_ref(). Even though there might not be any current use cases, it doesn't mean we should hard code this usage model in the API. The old behaviour can be emulated by never calling libinput_ref() while replacing libinput_destroy() with libinput_unref(). Signed-off-by: Jonas Ådahl Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- src/libinput-private.h | 1 + src/libinput.c | 21 ++++++++++++++++++--- src/libinput.h | 28 ++++++++++++++++++++++++---- src/udev-seat.c | 2 +- test/keyboard.c | 2 +- test/litest.c | 2 +- test/log.c | 10 +++++----- test/misc.c | 10 +++++----- test/path.c | 20 ++++++++++---------- test/pointer.c | 2 +- test/udev.c | 16 ++++++++-------- tools/event-debug.c | 4 ++-- tools/event-gui.c | 2 +- 13 files changed, 78 insertions(+), 42 deletions(-) diff --git a/src/libinput-private.h b/src/libinput-private.h index f0bda1f8..cfe6535b 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -57,6 +57,7 @@ struct libinput { const struct libinput_interface *interface; const struct libinput_interface_backend *interface_backend; void *user_data; + int refcount; }; typedef void (*libinput_seat_destroy_func) (struct libinput_seat *seat); diff --git a/src/libinput.c b/src/libinput.c index d4d57117..3aeca7dc 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -502,6 +502,7 @@ libinput_init(struct libinput *libinput, 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); @@ -530,15 +531,27 @@ libinput_drop_destroyed_sources(struct libinput *libinput) list_init(&libinput->source_destroy_list); } -LIBINPUT_EXPORT void -libinput_destroy(struct libinput *libinput) +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; + return NULL; + + assert(libinput->refcount > 0); + libinput->refcount--; + if (libinput->refcount > 0) + return libinput; libinput_suspend(libinput); @@ -562,6 +575,8 @@ libinput_destroy(struct libinput *libinput) libinput_drop_destroyed_sources(libinput); close(libinput->epoll_fd); free(libinput); + + return NULL; } LIBINPUT_EXPORT void diff --git a/src/libinput.h b/src/libinput.h index 3503b76f..72375f7b 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -793,6 +793,9 @@ struct libinput_interface { * device are ignored. Such devices and those that failed to open * ignored until the next call to libinput_resume(). * + * The reference count of the context is initialized to 1. See @ref + * libinput_unref. + * * @param interface The callback interface * @param user_data Caller-specific data passed to the various callback * interfaces. @@ -818,6 +821,9 @@ libinput_udev_create_for_seat(const struct libinput_interface *interface, * The context is fully initialized but will not generate events until at * least one device has been added. * + * The reference count of the context is initialized to 1. See @ref + * libinput_unref. + * * @param interface The callback interface * @param user_data Caller-specific data passed to the various callback * interfaces. @@ -967,13 +973,27 @@ libinput_suspend(struct libinput *libinput); /** * @ingroup base * - * Destroy the libinput context. After this, object references associated with - * the destroyed context are invalid and may not be interacted with. + * Add a reference to the context. A context is destroyed whenever the + * reference count reaches 0. See @ref libinput_unref. + * + * @param libinput A previously initialized valid libinput context + * @return The passed libinput context + */ +struct libinput * +libinput_ref(struct libinput *libinput); + +/** + * @ingroup base + * + * Dereference the libinput context. After this, the context may have been + * destroyed, if the last reference was dereferenced. If so, the context is + * invalid and may not be interacted with. * * @param libinput A previously initialized libinput context + * @return NULL if context was destroyed otherwise the passed context */ -void -libinput_destroy(struct libinput *libinput); +struct libinput * +libinput_unref(struct libinput *libinput); /** * @ingroup base diff --git a/src/udev-seat.c b/src/udev-seat.c index 38a13b72..5b61dee6 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -358,7 +358,7 @@ libinput_udev_create_for_seat(const struct libinput_interface *interface, if (udev_input_enable(&input->base) < 0) { udev_unref(udev); - libinput_destroy(&input->base); + libinput_unref(&input->base); free(input); return NULL; } diff --git a/test/keyboard.c b/test/keyboard.c index a518b66c..83153bb9 100644 --- a/test/keyboard.c +++ b/test/keyboard.c @@ -108,7 +108,7 @@ START_TEST(keyboard_seat_key_count) for (i = 0; i < num_devices; ++i) litest_delete_device(devices[i]); - libinput_destroy(libinput); + libinput_unref(libinput); } END_TEST diff --git a/test/litest.c b/test/litest.c index 0a9cc72d..55ba678b 100644 --- a/test/litest.c +++ b/test/litest.c @@ -573,7 +573,7 @@ litest_delete_device(struct litest_device *d) libinput_device_unref(d->libinput_device); if (d->owns_context) - libinput_destroy(d->libinput); + libinput_unref(d->libinput); libevdev_free(d->evdev); libevdev_uinput_destroy(d->uinput); memset(d,0, sizeof(*d)); diff --git a/test/log.c b/test/log.c index a2818207..fe67d68e 100644 --- a/test/log.c +++ b/test/log.c @@ -86,7 +86,7 @@ START_TEST(log_handler_invoked) ck_assert_int_gt(log_handler_called, 0); log_handler_called = 0; - libinput_destroy(li); + libinput_unref(li); libinput_log_set_priority(pri); } END_TEST @@ -106,7 +106,7 @@ START_TEST(log_userdata_NULL) ck_assert_int_gt(log_handler_called, 0); log_handler_called = 0; - libinput_destroy(li); + libinput_unref(li); libinput_log_set_priority(pri); } @@ -127,7 +127,7 @@ START_TEST(log_userdata) ck_assert_int_gt(log_handler_called, 0); log_handler_called = 0; - libinput_destroy(li); + libinput_unref(li); libinput_log_set_priority(pri); } END_TEST @@ -148,7 +148,7 @@ START_TEST(log_handler_NULL) log_handler_called = 0; libinput_log_set_handler(simple_log_handler, NULL); - libinput_destroy(li); + libinput_unref(li); libinput_log_set_priority(pri); } END_TEST @@ -173,7 +173,7 @@ START_TEST(log_priority) log_handler_called = 0; - libinput_destroy(li); + libinput_unref(li); libinput_log_set_priority(pri); } END_TEST diff --git a/test/misc.c b/test/misc.c index 133bdb60..ad2e1f66 100644 --- a/test/misc.c +++ b/test/misc.c @@ -133,7 +133,7 @@ START_TEST(event_conversion_device_notify) libinput_event_destroy(event); } - libinput_destroy(li); + libinput_unref(li); libevdev_uinput_destroy(uinput); ck_assert_int_gt(device_added, 0); @@ -194,7 +194,7 @@ START_TEST(event_conversion_pointer) libinput_event_destroy(event); } - libinput_destroy(li); + libinput_unref(li); libevdev_uinput_destroy(uinput); ck_assert_int_gt(motion, 0); @@ -254,7 +254,7 @@ START_TEST(event_conversion_pointer_abs) libinput_event_destroy(event); } - libinput_destroy(li); + libinput_unref(li); libevdev_uinput_destroy(uinput); ck_assert_int_gt(motion, 0); @@ -304,7 +304,7 @@ START_TEST(event_conversion_key) libinput_event_destroy(event); } - libinput_destroy(li); + libinput_unref(li); libevdev_uinput_destroy(uinput); ck_assert_int_gt(key, 0); @@ -364,7 +364,7 @@ START_TEST(event_conversion_touch) libinput_event_destroy(event); } - libinput_destroy(li); + libinput_unref(li); libevdev_uinput_destroy(uinput); ck_assert_int_gt(touch, 0); diff --git a/test/path.c b/test/path.c index 24f60e01..99b474eb 100644 --- a/test/path.c +++ b/test/path.c @@ -65,7 +65,7 @@ START_TEST(path_create_NULL) ck_assert(li == NULL); li = libinput_path_create_context(&simple_interface, NULL); ck_assert(li != NULL); - libinput_destroy(li); + libinput_unref(li); ck_assert_int_eq(open_func_count, 0); ck_assert_int_eq(close_func_count, 0); @@ -92,7 +92,7 @@ START_TEST(path_create_invalid) ck_assert_int_eq(open_func_count, 0); ck_assert_int_eq(close_func_count, 0); - libinput_destroy(li); + libinput_unref(li); ck_assert_int_eq(close_func_count, 0); open_func_count = 0; @@ -126,7 +126,7 @@ START_TEST(path_create_destroy) ck_assert_int_eq(open_func_count, 1); libevdev_uinput_destroy(uinput); - libinput_destroy(li); + libinput_unref(li); ck_assert_int_eq(close_func_count, 1); open_func_count = 0; @@ -372,7 +372,7 @@ START_TEST(path_suspend) libinput_resume(li); libevdev_uinput_destroy(uinput); - libinput_destroy(li); + libinput_unref(li); open_func_count = 0; close_func_count = 0; @@ -406,7 +406,7 @@ START_TEST(path_double_suspend) libinput_resume(li); libevdev_uinput_destroy(uinput); - libinput_destroy(li); + libinput_unref(li); open_func_count = 0; close_func_count = 0; @@ -440,7 +440,7 @@ START_TEST(path_double_resume) libinput_resume(li); libevdev_uinput_destroy(uinput); - libinput_destroy(li); + libinput_unref(li); open_func_count = 0; close_func_count = 0; @@ -523,7 +523,7 @@ START_TEST(path_add_device_suspend_resume) libevdev_uinput_destroy(uinput1); libevdev_uinput_destroy(uinput2); - libinput_destroy(li); + libinput_unref(li); open_func_count = 0; close_func_count = 0; @@ -614,7 +614,7 @@ START_TEST(path_add_device_suspend_resume_fail) ck_assert_int_eq(nevents, 2); libevdev_uinput_destroy(uinput2); - libinput_destroy(li); + libinput_unref(li); open_func_count = 0; close_func_count = 0; @@ -704,7 +704,7 @@ START_TEST(path_add_device_suspend_resume_remove_device) ck_assert_int_eq(nevents, 1); libevdev_uinput_destroy(uinput1); - libinput_destroy(li); + libinput_unref(li); open_func_count = 0; close_func_count = 0; @@ -790,7 +790,7 @@ START_TEST(path_seat_recycle) ck_assert(found == 1); - libinput_destroy(li); + libinput_unref(li); libevdev_uinput_destroy(uinput); } diff --git a/test/pointer.c b/test/pointer.c index 346e59b7..7d5668f8 100644 --- a/test/pointer.c +++ b/test/pointer.c @@ -292,7 +292,7 @@ START_TEST(pointer_seat_button_count) for (i = 0; i < num_devices; ++i) litest_delete_device(devices[i]); - libinput_destroy(libinput); + libinput_unref(libinput); } END_TEST diff --git a/test/udev.c b/test/udev.c index 6af2cb08..09c2a94f 100644 --- a/test/udev.c +++ b/test/udev.c @@ -97,7 +97,7 @@ START_TEST(udev_create_seat0) ck_assert(event != NULL); libinput_event_destroy(event); - libinput_destroy(li); + libinput_unref(li); udev_unref(udev); } END_TEST @@ -124,7 +124,7 @@ START_TEST(udev_create_empty_seat) ck_assert(event == NULL); libinput_event_destroy(event); - libinput_destroy(li); + libinput_unref(li); udev_unref(udev); } END_TEST @@ -169,7 +169,7 @@ START_TEST(udev_added_seat_default) ck_assert(default_seat_found); - libinput_destroy(li); + libinput_unref(li); udev_unref(udev); } END_TEST @@ -200,7 +200,7 @@ START_TEST(udev_double_suspend) libinput_resume(li); libinput_event_destroy(event); - libinput_destroy(li); + libinput_unref(li); udev_unref(udev); } END_TEST @@ -231,7 +231,7 @@ START_TEST(udev_double_resume) libinput_resume(li); libinput_event_destroy(event); - libinput_destroy(li); + libinput_unref(li); udev_unref(udev); } END_TEST @@ -289,7 +289,7 @@ START_TEST(udev_suspend_resume) process_events_count_devices(li, &num_devices); ck_assert_int_gt(num_devices, 0); - libinput_destroy(li); + libinput_unref(li); udev_unref(udev); } END_TEST @@ -322,7 +322,7 @@ START_TEST(udev_device_sysname) libinput_event_destroy(ev); } - libinput_destroy(li); + libinput_unref(li); udev_unref(udev); } END_TEST @@ -396,7 +396,7 @@ START_TEST(udev_seat_recycle) ck_assert(found == 1); - libinput_destroy(li); + libinput_unref(li); udev_unref(udev); } END_TEST diff --git a/tools/event-debug.c b/tools/event-debug.c index 34acfce2..95e76286 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -163,7 +163,7 @@ open_device(struct libinput **li, const char *path) device = libinput_path_add_device(*li, path); if (!device) { fprintf(stderr, "Failed to initialized device %s\n", path); - libinput_destroy(*li); + libinput_unref(*li); return 1; } @@ -478,7 +478,7 @@ main(int argc, char **argv) mainloop(li); - libinput_destroy(li); + libinput_unref(li); if (udev) udev_unref(udev); diff --git a/tools/event-gui.c b/tools/event-gui.c index 95540936..9c39c213 100644 --- a/tools/event-gui.c +++ b/tools/event-gui.c @@ -467,7 +467,7 @@ main(int argc, char *argv[]) gtk_main(); - libinput_destroy(li); + libinput_unref(li); udev_unref(udev); return 0; From 89aa3ca176130104f2fc5c034400cbb4c41cf479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 25 Jun 2014 00:06:59 +0200 Subject: [PATCH 10/22] test: Add context reference counting test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test relies on valgrind detecting the leak and use-after-free. Signed-off-by: Jonas Ådahl Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- test/misc.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/misc.c b/test/misc.c index ad2e1f66..bea7e889 100644 --- a/test/misc.c +++ b/test/misc.c @@ -371,12 +371,32 @@ START_TEST(event_conversion_touch) } END_TEST +START_TEST(context_ref_counting) +{ + struct libinput *li; + + /* These tests rely on valgrind to detect memory leak and use after + * free errors. */ + + li = libinput_path_create_context(&simple_interface, NULL); + ck_assert_notnull(li); + ck_assert_ptr_eq(libinput_unref(li), NULL); + + li = libinput_path_create_context(&simple_interface, NULL); + ck_assert_notnull(li); + ck_assert_ptr_eq(libinput_ref(li), li); + ck_assert_ptr_eq(libinput_unref(li), li); + ck_assert_ptr_eq(libinput_unref(li), NULL); +} +END_TEST + int main (int argc, char **argv) { litest_add_no_device("events:conversion", event_conversion_device_notify); litest_add_no_device("events:conversion", event_conversion_pointer); litest_add_no_device("events:conversion", event_conversion_pointer_abs); litest_add_no_device("events:conversion", event_conversion_key); litest_add_no_device("events:conversion", event_conversion_touch); + litest_add_no_device("context:refcount", context_ref_counting); return litest_run(argc, argv); } From 4441c9debe3e8ee6745385729dc8a5bb0cf9b0f0 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 20 Jun 2014 14:06:19 +1000 Subject: [PATCH 11/22] Add msleep() helper function For those whose eyes struggle to focus on 5 zeros in a row, or those just sick of forgetting one zero and wondering why things don't work. Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede --- src/libinput-util.h | 8 ++++++++ test/touchpad.c | 12 ++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/libinput-util.h b/src/libinput-util.h index 11c4f5c2..2558a3d9 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -23,6 +23,8 @@ #ifndef LIBINPUT_UTIL_H #define LIBINPUT_UTIL_H +#include + #include "libinput.h" void @@ -84,4 +86,10 @@ zalloc(size_t size) return calloc(1, size); } +static inline void +msleep(unsigned int ms) +{ + usleep(ms * 1000); +} + #endif /* LIBINPUT_UTIL_H */ diff --git a/test/touchpad.c b/test/touchpad.c index 35658338..690e105b 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -125,7 +125,7 @@ START_TEST(touchpad_1fg_tap) assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED); - usleep(300000); /* tap-n-drag timeout */ + msleep(300); /* tap-n-drag timeout */ assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED); @@ -177,7 +177,7 @@ START_TEST(touchpad_1fg_tap_n_drag) ck_assert_int_eq(libinput_next_event_type(li), LIBINPUT_EVENT_NONE); - usleep(300000); /* tap-n-drag timeout */ + msleep(300); /* tap-n-drag timeout */ assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED); @@ -202,7 +202,7 @@ START_TEST(touchpad_2fg_tap) assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED); - usleep(300000); /* tap-n-drag timeout */ + msleep(300); /* tap-n-drag timeout */ assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED); @@ -681,7 +681,7 @@ START_TEST(clickpad_softbutton_left_1st_fg_move) /* move out of the area, then wait for softbutton timer */ litest_touch_move_to(dev, 0, 20, 90, 90, 20, 10); libinput_dispatch(li); - usleep(400000); + msleep(400); libinput_dispatch(li); litest_drain_events(li); @@ -982,13 +982,13 @@ START_TEST(clickpad_topsoftbuttons_move_out_ignore) litest_touch_down(dev, 0, 50, 5); libinput_dispatch(li); - usleep(200000); + msleep(200); libinput_dispatch(li); litest_assert_empty_queue(li); litest_touch_move_to(dev, 0, 50, 5, 80, 90, 20); libinput_dispatch(li); - usleep(400000); + msleep(400); libinput_dispatch(li); litest_event(dev, EV_KEY, BTN_LEFT, 1); From cc3ede9d56fe4403ab35fd4f3c63568d3254521f Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 20 Jun 2014 14:24:57 +1000 Subject: [PATCH 12/22] test: add one more test for two-finger tapping Inverted order of release from the other test Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede --- test/touchpad.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/touchpad.c b/test/touchpad.c index 690e105b..ca0a7008 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -210,6 +210,30 @@ START_TEST(touchpad_2fg_tap) } END_TEST +START_TEST(touchpad_2fg_tap_inverted) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + + litest_drain_events(dev->libinput); + + litest_touch_down(dev, 0, 50, 50); + litest_touch_down(dev, 1, 70, 70); + litest_touch_up(dev, 1); + litest_touch_up(dev, 0); + + libinput_dispatch(li); + + assert_button_event(li, BTN_RIGHT, + LIBINPUT_BUTTON_STATE_PRESSED); + msleep(300); /* tap-n-drag timeout */ + assert_button_event(li, BTN_RIGHT, + LIBINPUT_BUTTON_STATE_RELEASED); + + litest_assert_empty_queue(li); +} +END_TEST + START_TEST(touchpad_1fg_tap_click) { struct litest_device *dev = litest_current_device(); @@ -1010,6 +1034,7 @@ int main(int argc, char **argv) { litest_add("touchpad:tap", touchpad_1fg_tap, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:tap", touchpad_1fg_tap_n_drag, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:tap", touchpad_2fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); + litest_add("touchpad:tap", touchpad_2fg_tap_inverted, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:tap", touchpad_1fg_tap_click, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:tap", touchpad_2fg_tap_click, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_APPLE_CLICKPAD); litest_add("touchpad:tap", touchpad_2fg_tap_click_apple, LITEST_APPLE_CLICKPAD, LITEST_ANY); From c9a01969d8e5ad527fede479be0b032a46a4f18d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 24 Jun 2014 16:23:09 +0200 Subject: [PATCH 13/22] test: Add touchpad 2 finger scroll test Signed-off-by: Hans de Goede Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- test/touchpad.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/test/touchpad.c b/test/touchpad.c index ca0a7008..fa777e4f 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -1026,6 +1026,82 @@ START_TEST(clickpad_topsoftbuttons_move_out_ignore) } END_TEST +static void +test_2fg_scroll(struct litest_device *dev, int dx, int dy) +{ + litest_touch_down(dev, 0, 47, 50); + litest_touch_down(dev, 1, 53, 50); + + litest_touch_move_to(dev, 0, 47, 50, 47 + dx, 50 + dy, 5); + litest_touch_move_to(dev, 1, 53, 50, 53 + dx, 50 + dy, 5); + + litest_touch_up(dev, 1); + litest_touch_up(dev, 0); +} + +static void +check_2fg_scroll(struct litest_device *dev, int axis, int dir) +{ + struct libinput *li = dev->libinput; + struct libinput_event *event, *next_event; + struct libinput_event_pointer *ptrev; + + libinput_dispatch(li); + + event = libinput_get_event(li); + next_event = libinput_get_event(li); + ck_assert(next_event != NULL); /* At least 1 scroll + stop scroll */ + + while (event) { + ck_assert_int_eq(libinput_event_get_type(event), + LIBINPUT_EVENT_POINTER_AXIS); + ptrev = libinput_event_get_pointer_event(event); + ck_assert(ptrev != NULL); + ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev), axis); + + if (next_event) { + /* Normal scroll event, check dir */ + if (dir > 0) { + ck_assert_int_ge( + libinput_event_pointer_get_axis_value(ptrev), + dir); + } else { + ck_assert_int_le( + libinput_event_pointer_get_axis_value(ptrev), + dir); + } + } else { + /* Last scroll event, must be 0 */ + ck_assert_int_eq( + libinput_event_pointer_get_axis_value(ptrev), + 0); + } + libinput_event_destroy(event); + event = next_event; + next_event = libinput_get_event(li); + } +} + +START_TEST(touchpad_2fg_scroll) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + + litest_drain_events(li); + + /* Note this mixes in a tiny amount of movement in the wrong direction, + which should be ignored */ + test_2fg_scroll(dev, 1, 40); + check_2fg_scroll(dev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 10); + test_2fg_scroll(dev, 1, -40); + check_2fg_scroll(dev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -10); + test_2fg_scroll(dev, 40, 1); + check_2fg_scroll(dev, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 10); + test_2fg_scroll(dev, -40, 1); + check_2fg_scroll(dev, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -10); +} +END_TEST + int main(int argc, char **argv) { litest_add("touchpad:motion", touchpad_1fg_motion, LITEST_TOUCHPAD, LITEST_ANY); @@ -1064,5 +1140,7 @@ int main(int argc, char **argv) { litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_middle, LITEST_TOPBUTTONPAD, LITEST_ANY); litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_move_out_ignore, LITEST_TOPBUTTONPAD, LITEST_ANY); + litest_add("touchpad:scroll", touchpad_2fg_scroll, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); + return litest_run(argc, argv); } From c0af1b57d4063f0894ade2ba2f57a149ad454f7f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 24 Jun 2014 16:23:10 +0200 Subject: [PATCH 14/22] touchpad: Avoid spurious motion event for scroll movement below threshold If the user puts down to fingers to scroll, then changes his mind and lifts them, without having them moved past the initial scroll threshold in either direction, then any movement which he has done will cause a spurious scroll event when the second finger down is lifted first. The problem is that t->is_pointer was not being set to false in this case, since that is done in tp_post_twofinger_scroll after checking scroll.state which never gets set in this scenario. Instead of changing the order, simply completely remove scroll.state completely it is a boolean, and everywhere we check for it we also check for the axis bits in state.direction, so it is not necessary. Also add a check to ensure there are no spurious motion events. Signed-off-by: Hans de Goede Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- src/evdev-mt-touchpad.c | 17 +++-------------- src/evdev-mt-touchpad.h | 6 ------ test/touchpad.c | 27 ++++++++++++++++++++------- 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 4811bf31..04ea93c6 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -464,17 +464,11 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time) tp_filter_motion(tp, &dx, &dy, time); /* Require at least three px scrolling to start */ - if (dy <= -3.0 || dy >= 3.0) { - tp->scroll.state = SCROLL_STATE_SCROLLING; + if (dy <= -3.0 || dy >= 3.0) tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); - } - if (dx <= -3.0 || dx >= 3.0) { - tp->scroll.state = SCROLL_STATE_SCROLLING; - tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); - } - if (tp->scroll.state == SCROLL_STATE_NONE) - return; + if (dx <= -3.0 || dx >= 3.0) + tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); /* Stop spurious MOTION events at the end of scrolling */ tp_for_each_touch(tp, t) @@ -500,9 +494,6 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time) static void tp_stop_scroll_events(struct tp_dispatch *tp, uint64_t time) { - if (tp->scroll.state == SCROLL_STATE_NONE) - return; - /* terminate scrolling with a zero scroll event */ if (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) pointer_notify_axis(&tp->device->base, @@ -515,7 +506,6 @@ tp_stop_scroll_events(struct tp_dispatch *tp, uint64_t time) LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 0); - tp->scroll.state = SCROLL_STATE_NONE; tp->scroll.direction = 0; } @@ -732,7 +722,6 @@ static int tp_init_scroll(struct tp_dispatch *tp) { tp->scroll.direction = 0; - tp->scroll.state = SCROLL_STATE_NONE; return 0; } diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index 0b1457db..7afb3c46 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -72,11 +72,6 @@ enum button_state { BUTTON_STATE_IGNORE, }; -enum scroll_state { - SCROLL_STATE_NONE, - SCROLL_STATE_SCROLLING -}; - enum tp_tap_state { TAP_STATE_IDLE = 4, TAP_STATE_TOUCH, @@ -192,7 +187,6 @@ struct tp_dispatch { } buttons; /* physical buttons */ struct { - enum scroll_state state; enum libinput_pointer_axis direction; } scroll; diff --git a/test/touchpad.c b/test/touchpad.c index fa777e4f..288805ef 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -1027,16 +1027,27 @@ START_TEST(clickpad_topsoftbuttons_move_out_ignore) END_TEST static void -test_2fg_scroll(struct litest_device *dev, int dx, int dy) +test_2fg_scroll(struct litest_device *dev, int dx, int dy, int sleep) { + struct libinput *li = dev->libinput; + litest_touch_down(dev, 0, 47, 50); litest_touch_down(dev, 1, 53, 50); litest_touch_move_to(dev, 0, 47, 50, 47 + dx, 50 + dy, 5); litest_touch_move_to(dev, 1, 53, 50, 53 + dx, 50 + dy, 5); + /* Avoid a small scroll being seen as a tap */ + if (sleep) { + libinput_dispatch(li); + msleep(sleep); + libinput_dispatch(li); + } + litest_touch_up(dev, 1); litest_touch_up(dev, 0); + + libinput_dispatch(li); } static void @@ -1046,8 +1057,6 @@ check_2fg_scroll(struct litest_device *dev, int axis, int dir) struct libinput_event *event, *next_event; struct libinput_event_pointer *ptrev; - libinput_dispatch(li); - event = libinput_get_event(li); next_event = libinput_get_event(li); ck_assert(next_event != NULL); /* At least 1 scroll + stop scroll */ @@ -1091,14 +1100,18 @@ START_TEST(touchpad_2fg_scroll) /* Note this mixes in a tiny amount of movement in the wrong direction, which should be ignored */ - test_2fg_scroll(dev, 1, 40); + test_2fg_scroll(dev, 1, 40, 0); check_2fg_scroll(dev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 10); - test_2fg_scroll(dev, 1, -40); + test_2fg_scroll(dev, 1, -40, 0); check_2fg_scroll(dev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -10); - test_2fg_scroll(dev, 40, 1); + test_2fg_scroll(dev, 40, 1, 0); check_2fg_scroll(dev, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 10); - test_2fg_scroll(dev, -40, 1); + test_2fg_scroll(dev, -40, 1, 0); check_2fg_scroll(dev, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -10); + + /* 2fg scroll smaller than the threshold should not generate events */ + test_2fg_scroll(dev, 1, 1, 200); + litest_assert_empty_queue(li); } END_TEST From 8d6356e668ef34f634ce99df9fca20abf2446be8 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 24 Jun 2014 16:23:11 +0200 Subject: [PATCH 15/22] tp_post_twofinger_scroll: Move setting of t->is_pointer = false up a bit There is no need to loop over the touch points twice. Signed-off-by: Hans de Goede Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- src/evdev-mt-touchpad.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 04ea93c6..ced92378 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -453,6 +453,8 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time) dx += tmpx; dy += tmpy; } + /* Stop spurious MOTION events at the end of scrolling */ + t->is_pointer = false; } if (nchanged == 0) @@ -470,10 +472,6 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time) if (dx <= -3.0 || dx >= 3.0) tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); - /* Stop spurious MOTION events at the end of scrolling */ - tp_for_each_touch(tp, t) - t->is_pointer = false; - if (dy != 0.0 && (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))) { pointer_notify_axis(&tp->device->base, From 6c4778f891a77e06c0fccbfad1a1bfd4f64f86f3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 24 Jun 2014 16:23:12 +0200 Subject: [PATCH 16/22] test: Prefix litest created device names with litest And add an example xorg.conf.d .conf file for ignoring these devices under xorg. Signed-off-by: Hans de Goede Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- test/50-litest.conf | 6 ++++++ test/litest.c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 test/50-litest.conf diff --git a/test/50-litest.conf b/test/50-litest.conf new file mode 100644 index 00000000..76579d77 --- /dev/null +++ b/test/50-litest.conf @@ -0,0 +1,6 @@ +# Ignore devices created by libinput's test suite (litest) +Section "InputClass" + Identifier "libinput test suite blacklist" + MatchProduct "litest" + Option "Ignore" "on" +EndSection diff --git a/test/litest.c b/test/litest.c index 320a26d6..02f3d77b 100644 --- a/test/litest.c +++ b/test/litest.c @@ -822,11 +822,13 @@ litest_create_uinput_device_from_description(const char *name, .flat = 0, .resolution = 100 }; + char buf[512]; dev = libevdev_new(); ck_assert(dev != NULL); - libevdev_set_name(dev, name); + snprintf(buf, sizeof(buf), "litest %s", name); + libevdev_set_name(dev, buf); if (id) { libevdev_set_id_bustype(dev, id->bustype); libevdev_set_id_vendor(dev, id->vendor); From 568004d4834535c81ffb627457dff3081ce67f46 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 24 Jun 2014 16:23:13 +0200 Subject: [PATCH 17/22] timer: Complain if a timer is set more than 5 seconds from now Signed-off-by: Hans de Goede Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- src/timer.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/timer.c b/src/timer.c index f5461858..3076bb7a 100644 --- a/src/timer.c +++ b/src/timer.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -65,6 +66,22 @@ libinput_timer_arm_timer_fd(struct libinput *libinput) void libinput_timer_set(struct libinput_timer *timer, uint64_t expire) { +#ifndef NDEBUG + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { + uint64_t now = ts.tv_sec * 1000ULL + ts.tv_nsec / 1000000; + if (abs(expire - now) > 5000) + log_bug_libinput(timer->libinput, + "timer offset more than 5s, now %" + PRIu64 " expire %" PRIu64 "\n", + now, expire); + } else { + log_error(timer->libinput, + "clock_gettime error: %s\n", strerror(errno)); + } +#endif + assert(expire); if (!timer->expire) From ac5fc23e49ffdb0a6f4ab45ef26048f3c414373d Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 25 Jun 2014 11:41:16 +1000 Subject: [PATCH 18/22] Drop the deprecated LIBINPUT_POINTER_*_SCROLL enums We have enough API breakage in this release that it's not worth keeping these around. Every caller must be fixed for all the other stuff anyway, so drop this too. Signed-off-by: Peter Hutterer --- src/libinput.h | 6 ------ tools/event-gui.c | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/libinput.h b/src/libinput.h index 96da0e0b..d765ced2 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -167,12 +167,6 @@ enum libinput_button_state { enum libinput_pointer_axis { LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL = 0, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL = 1, - - - /** @deprecated Use @ref LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL instead */ - LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, - /** @deprecated Use @ref LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL instead */ - LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL }; /** diff --git a/tools/event-gui.c b/tools/event-gui.c index 9475e778..234ece93 100644 --- a/tools/event-gui.c +++ b/tools/event-gui.c @@ -284,11 +284,11 @@ handle_event_axis(struct libinput_event *ev, struct window *w) double v = libinput_event_pointer_get_axis_value(p); switch (axis) { - case LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL: + case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: w->vy += (int)v; w->vy = clip(w->vy, 0, w->height); break; - case LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL: + case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: w->hx += (int)v; w->hx = clip(w->hx, 0, w->width); break; From dd9cd664bc04acbc29e6f5040845b834d630442a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 25 Jun 2014 11:42:35 +1000 Subject: [PATCH 19/22] Fix a few comments referring to udev_create_for_seat() Signed-off-by: Peter Hutterer --- src/libinput.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libinput.h b/src/libinput.h index d765ced2..47da8518 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -759,7 +759,7 @@ struct libinput_interface { * @param path The device path to open * @param flags Flags as defined by open(2) * @param user_data The user_data provided in - * libinput_udev_create_for_seat() + * libinput_udev_create_context() * * @return the file descriptor, or a negative errno on failure. */ @@ -769,7 +769,7 @@ struct libinput_interface { * * @param fd The file descriptor to close * @param user_data The user_data provided in - * libinput_udev_create_for_seat() + * libinput_udev_create_context() */ void (*close_restricted)(int fd, void *user_data); }; @@ -895,7 +895,7 @@ libinput_path_create_context(const struct libinput_interface *interface, * @return The newly initiated device on success, or NULL on failure. * * @note It is an application bug to call this function on a libinput - * context initialized with libinput_udev_create_for_seat(). + * context initialized with libinput_udev_create_context(). */ struct libinput_device * libinput_path_add_device(struct libinput *libinput, @@ -917,7 +917,7 @@ libinput_path_add_device(struct libinput *libinput, * @param device A libinput device * * @note It is an application bug to call this function on a libinput - * context initialized with libinput_udev_create_for_seat(). + * context initialized with libinput_udev_create_context(). */ void libinput_path_remove_device(struct libinput_device *device); @@ -1196,7 +1196,7 @@ libinput_seat_get_user_data(struct libinput_seat *seat); * * Return the physical name of the seat. For libinput contexts created from * udev, this is always the same value as passed into - * libinput_udev_create_for_seat() and all seats from that context will have + * libinput_udev_assign_seat() and all seats from that context will have * the same physical name. * * The physical name of the seat is one that is usually set by the system or From 186f6188147d520a417c4215f27b81eadec66c24 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 25 Jun 2014 11:41:16 +1000 Subject: [PATCH 20/22] Drop the deprecated libinput_udev_create_for_seat() We have enough API breakage in this release that it's not worth keeping this around. Every caller must be fixed for all the other stuff anyway, so drop this too. Signed-off-by: Peter Hutterer --- src/libinput.h | 37 ------------------------------------- src/udev-seat.c | 23 ----------------------- 2 files changed, 60 deletions(-) diff --git a/src/libinput.h b/src/libinput.h index 47da8518..efd071ec 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -817,43 +817,6 @@ int libinput_udev_assign_seat(struct libinput *libinput, const char *seat_id); -/** - * @ingroup base - * - * Create a new libinput context from udev, for input devices matching - * the given seat ID. New devices or devices removed will appear as events - * during libinput_dispatch. - * - * libinput_udev_create_for_seat() succeeds even if no input device is - * available in this seat, or if devices are available but fail to open in - * @ref libinput_interface::open_restricted. Devices that do not have the - * minimum capabilities to be recognized as pointer, keyboard or touch - * device are ignored. Such devices and those that failed to open - * ignored until the next call to libinput_resume(). - * - * The reference count of the context is initialized to 1. See @ref - * libinput_unref. - * - * @param interface The callback interface - * @param user_data Caller-specific data passed to the various callback - * interfaces. - * @param udev An already initialized udev context - * @param seat_id A seat identifier. This string must not be NULL. - * - * @return An initialized libinput context, ready to handle events or NULL on - * error. - * - * @deprecated This function was deprecated in 0.4.0 and will be removed - * soon. Use libinput_udev_create_context() and libinput_udev_assign_seat() - * instead. - */ -struct libinput * -libinput_udev_create_for_seat(const struct libinput_interface *interface, - void *user_data, - struct udev *udev, - const char *seat_id) - LIBINPUT_ATTRIBUTE_DEPRECATED; - /** * @ingroup base * diff --git a/src/udev-seat.c b/src/udev-seat.c index 17cb3cb0..635fabfd 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -384,26 +384,3 @@ libinput_udev_assign_seat(struct libinput *libinput, return 0; } - -LIBINPUT_EXPORT struct libinput * -libinput_udev_create_for_seat(const struct libinput_interface *interface, - void *user_data, - struct udev *udev, - const char *seat_id) -{ - struct libinput *libinput; - - if (!interface || !udev || !seat_id) - return NULL; - - libinput = libinput_udev_create_context(interface, user_data, udev); - if (!libinput) - return NULL; - - if (libinput_udev_assign_seat(libinput, seat_id) != 0) { - libinput_unref(libinput); - libinput = NULL; - } - - return libinput; -} From 72f5758f2adca6be752ff336d8cf77a23959e7fb Mon Sep 17 00:00:00 2001 From: Stephen Chandler Paul Date: Tue, 24 Jun 2014 18:55:25 -0400 Subject: [PATCH 21/22] touchpad: Fix typo in documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "a a left and…"->"a left and…" Signed-off-by: Stephen Chandler Paul Signed-off-by: Peter Hutterer --- src/libinput.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libinput.h b/src/libinput.h index efd071ec..99a3b2f5 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -50,7 +50,7 @@ extern "C" { * * Software button areas * ===================== - * On most touchpads, the bottom area of the touchpad is split into a a left + * On most touchpads, the bottom area of the touchpad is split into a left * and a right-button area. Pressing the touchpad down with a finger in * those areas will generate clicks as shown in the diagram below: * From d1f8a545e7710a400406a776d6f457a332671d8e Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 25 Jun 2014 12:55:58 +1000 Subject: [PATCH 22/22] configure.ac: libinput 0.4 Signed-off-by: Peter Hutterer --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 361eafe7..860324ac 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ AC_PREREQ([2.64]) m4_define([libinput_major_version], [0]) -m4_define([libinput_minor_version], [3]) +m4_define([libinput_minor_version], [4]) m4_define([libinput_micro_version], [0]) m4_define([libinput_version], [libinput_major_version.libinput_minor_version.libinput_micro_version]) @@ -30,7 +30,7 @@ AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz]) # - If binary compatibility has been broken (eg removed or changed interfaces) # change to C+1:0:0 # - If the interface is the same as the previous version, change to C:R+1:A -LIBINPUT_LT_VERSION=2:0:0 +LIBINPUT_LT_VERSION=3:0:0 AC_SUBST(LIBINPUT_LT_VERSION) AM_SILENT_RULES([yes])