diff --git a/src/libinput-private.h b/src/libinput-private.h index d50154ef8..6faf9e561 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -140,6 +140,9 @@ struct libinput { struct list device_group_list; uint64_t last_event_time; + + bool quirks_initialized; + struct quirks_context *quirks; }; typedef void (*libinput_seat_destroy_func) (struct libinput_seat *seat); @@ -427,6 +430,9 @@ libinput_init(struct libinput *libinput, const struct libinput_interface_backend *interface_backend, void *user_data); +void +libinput_init_quirks(struct libinput *libinput); + struct libinput_source * libinput_add_fd(struct libinput *libinput, int fd, diff --git a/src/libinput.c b/src/libinput.c index 78b547587..846c5bf78 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -38,6 +38,7 @@ #include "libinput-private.h" #include "evdev.h" #include "timer.h" +#include "quirks.h" #define require_event_type(li_, type_, retval_, ...) \ if (type_ == LIBINPUT_EVENT_NONE) abort(); \ @@ -1720,6 +1721,46 @@ libinput_init(struct libinput *libinput, return 0; } +void +libinput_init_quirks(struct libinput *libinput) +{ + const char *data_path, + *override_file = NULL; + struct quirks_context *quirks; + + if (libinput->quirks_initialized) + return; + + /* If we fail, we'll fail next time too */ + libinput->quirks_initialized = true; + + data_path = getenv("LIBINPUT_DATA_DIR"); + if (!data_path) { + data_path = LIBINPUT_DATA_DIR; + override_file = LIBINPUT_DATA_OVERRIDE_FILE; + } + + quirks = quirks_init_subsystem(data_path, + override_file, + log_msg_va, + libinput, + QLOG_LIBINPUT_LOGGING); + if (!quirks) { + log_error(libinput, + "Failed to load the device quirks from %s%s%s. " + "This will negatively affect device behavior. " + "See %sdevice-quirks.html for details.\n", + data_path, + override_file ? " and " : "", + override_file ? override_file : "", + HTTP_DOC_LINK + ); + return; + } + + libinput->quirks = quirks; +} + static void libinput_device_destroy(struct libinput_device *device); @@ -1791,6 +1832,7 @@ libinput_unref(struct libinput *libinput) libinput_timer_subsys_destroy(libinput); libinput_drop_destroyed_sources(libinput); + quirks_context_unref(libinput->quirks); close(libinput->epoll_fd); free(libinput); diff --git a/src/path-seat.c b/src/path-seat.c index 4322b9208..6cc7b3e42 100644 --- a/src/path-seat.c +++ b/src/path-seat.c @@ -337,6 +337,13 @@ libinput_path_add_device(struct libinput *libinput, return NULL; } + /* We cannot do this during path_create_context because the log + * handler isn't set up there but we really want to log to the right + * place if the quirks run into parser errors. So we have to do it + * on the first call to add_device. + */ + libinput_init_quirks(libinput); + udev_device = udev_device_from_devnode(libinput, udev, path); if (!udev_device) { log_bug_client(libinput, "Invalid path %s\n", path); diff --git a/src/udev-seat.c b/src/udev-seat.c index 37d3dccec..aeae198cb 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -382,6 +382,13 @@ libinput_udev_assign_seat(struct libinput *libinput, { struct udev_input *input = (struct udev_input*)libinput; + /* We cannot do this during udev_create_context because the log + * handler isn't set up there but we really want to log to the right + * place if the quirks run into parser errors. So we have to do it + * here since we can expect the log handler to be set up by now. + */ + libinput_init_quirks(libinput); + if (!seat_id) return -1;