static int
pad_init_leds_from_libwacom(struct pad_dispatch *pad,
- struct evdev_device *device)
+ struct evdev_device *device,
+ WacomDevice *wacom)
{
- struct libinput *li = pad_libinput_context(pad);
- WacomDeviceDatabase *db = NULL;
- WacomDevice *wacom = NULL;
int rc = -EINVAL;
- db = libinput_libwacom_ref(li);
- if (!db)
- goto out;
-
- wacom = libwacom_new_from_path(db,
- udev_device_get_devnode(device->udev_device),
- WFALLBACK_NONE,
- NULL);
if (!wacom)
- goto out;
+ return -ENOENT;
for (int b = 0; b < libwacom_get_num_buttons(wacom); b++) {
char btn = 'A' + b;
rc = 0;
out:
- if (wacom)
- libwacom_destroy(wacom);
- if (db)
- libinput_libwacom_unref(li);
-
if (rc != 0) {
if (rc == -ENOENT && is_litest_device(pad->device)) {
evdev_log_error(pad->device,
int
pad_init_leds(struct pad_dispatch *pad,
- struct evdev_device *device)
+ struct evdev_device *device,
+ WacomDevice *wacom)
{
int rc = 1;
/* If libwacom fails, we init one fallback group anyway */
#if HAVE_LIBWACOM
- rc = pad_init_leds_from_libwacom(pad, device);
+ rc = pad_init_leds_from_libwacom(pad, device, wacom);
#endif
if (rc != 0)
rc = pad_init_fallback_group(pad);
static bool
pad_init_buttons_from_libwacom(struct pad_dispatch *pad,
- struct evdev_device *device)
+ struct evdev_device *device,
+ WacomDevice *tablet)
{
bool rc = false;
#if HAVE_LIBWACOM
- struct libinput *li = pad_libinput_context(pad);
- WacomDeviceDatabase *db = NULL;
- WacomDevice *tablet = NULL;
- int num_buttons;
- int map = 0;
- char event_path[64];
-
- db = libinput_libwacom_ref(li);
- if (!db)
- goto out;
-
- snprintf(event_path,
- sizeof(event_path),
- "/dev/input/%s",
- evdev_device_get_sysname(device));
- tablet = libwacom_new_from_path(db,
- event_path,
- WFALLBACK_NONE,
- NULL);
- if (!tablet) {
- tablet = libwacom_new_from_usbid(db,
- evdev_device_get_id_vendor(device),
- evdev_device_get_id_product(device),
- NULL);
- }
- if (!tablet)
- goto out;
+ if (tablet) {
+ int num_buttons = libwacom_get_num_buttons(tablet);
+ int map = 0;
+ for (int i = 0; i < num_buttons; i++) {
+ unsigned int code;
- num_buttons = libwacom_get_num_buttons(tablet);
- for (int i = 0; i < num_buttons; i++) {
- unsigned int code;
+ code = libwacom_get_button_evdev_code(tablet, 'A' + i);
+ if (code == 0)
+ continue;
- code = libwacom_get_button_evdev_code(tablet, 'A' + i);
- if (code == 0)
- continue;
+ map_set_button_map(pad->button_map[code], map++);
+ }
- map_set_button_map(pad->button_map[code], map++);
+ pad->nbuttons = map;
+ rc = true;
}
-
- pad->nbuttons = map;
-
- rc = true;
-out:
- if (tablet)
- libwacom_destroy(tablet);
- if (db)
- libinput_libwacom_unref(li);
#endif
return rc;
}
static void
pad_init_buttons(struct pad_dispatch *pad,
- struct evdev_device *device)
+ struct evdev_device *device,
+ WacomDevice *wacom)
{
size_t i;
for (i = 0; i < ARRAY_LENGTH(pad->button_map); i++)
map_init(pad->button_map[i]);
- if (!pad_init_buttons_from_libwacom(pad, device))
+ if (!pad_init_buttons_from_libwacom(pad, device, wacom))
pad_init_buttons_from_kernel(pad, device);
pad_init_keys(pad, device);
}
static void
-pad_init_left_handed(struct evdev_device *device)
+pad_init_left_handed(struct evdev_device *device,
+ WacomDevice *wacom)
{
- if (evdev_tablet_has_left_handed(device))
+ bool has_left_handed = true;
+
+#if HAVE_LIBWACOM
+ has_left_handed = !wacom || libwacom_is_reversible(wacom);
+#endif
+ if (has_left_handed)
evdev_init_left_handed(device,
pad_change_to_left_handed);
}
static int
pad_init(struct pad_dispatch *pad, struct evdev_device *device)
{
+ int rc = 1;
+ struct libinput *li = evdev_libinput_context(device);
+ WacomDevice *wacom = NULL;
+#if HAVE_LIBWACOM
+ WacomDeviceDatabase *db = libinput_libwacom_ref(li);
+ if (db) {
+ char event_path[64];
+ snprintf(event_path,
+ sizeof(event_path),
+ "/dev/input/%s",
+ evdev_device_get_sysname(device));
+ wacom = libwacom_new_from_path(db, event_path, WFALLBACK_NONE, NULL);
+ if (!wacom) {
+ wacom = libwacom_new_from_usbid(db,
+ evdev_device_get_id_vendor(device),
+ evdev_device_get_id_product(device),
+ NULL);
+ }
+ if (!wacom) {
+ evdev_log_info(device,
+ "device \"%s\" (%04x:%04x) is not known to libwacom\n",
+ evdev_device_get_name(device),
+ evdev_device_get_id_vendor(device),
+ evdev_device_get_id_product(device));
+ }
+ }
+#endif
+
pad->base.dispatch_type = DISPATCH_TABLET_PAD;
pad->base.interface = &pad_interface;
pad->device = device;
if (libevdev_has_event_code(device->evdev, EV_REL, REL_WHEEL) &&
libevdev_has_event_code(device->evdev, EV_REL, REL_DIAL)) {
- log_bug_libinput(pad_libinput_context(pad), "Unsupported combination REL_DIAL and REL_WHEEL\n");
+ log_bug_libinput(li, "Unsupported combination REL_DIAL and REL_WHEEL\n");
}
- pad_init_buttons(pad, device);
- pad_init_left_handed(device);
- if (pad_init_leds(pad, device) != 0)
- return 1;
+ pad_init_buttons(pad, device, wacom);
+ pad_init_left_handed(device, wacom);
+
+ rc = pad_init_leds(pad, device, wacom);
- return 0;
+#if HAVE_LIBWACOM
+ if (wacom)
+ libwacom_destroy(wacom);
+ if (db)
+ libinput_libwacom_unref(li);
+#endif
+ return rc;
}
static uint32_t
#include "evdev.h"
+#if !HAVE_LIBWACOM
+typedef void * WacomDevice;
+#endif
+
#define LIBINPUT_BUTTONSET_AXIS_NONE 0
enum pad_status {
}
int
-pad_init_leds(struct pad_dispatch *pad, struct evdev_device *device);
+pad_init_leds(struct pad_dispatch *pad,
+ struct evdev_device *device,
+ WacomDevice *wacom);
+
void
pad_destroy_leds(struct pad_dispatch *pad);
+
void
pad_button_update_mode(struct libinput_tablet_pad_mode_group *g,
unsigned int button_index,
}
static void
-tablet_init_left_handed(struct evdev_device *device)
+tablet_init_left_handed(struct evdev_device *device,
+ WacomDevice *wacom)
{
- if (evdev_tablet_has_left_handed(device))
+ bool has_left_handed = true;
+
+#if HAVE_LIBWACOM
+ has_left_handed = !wacom || libwacom_is_reversible(wacom);
+#endif
+ if (has_left_handed)
evdev_init_left_handed(device,
tablet_change_to_left_handed);
}
-static void
-tablet_lookup_libwacom(struct evdev_device *device,
- struct tablet_dispatch *tablet,
- bool *is_aes,
- bool *is_display_tablet)
+static inline bool
+tablet_is_display_tablet(WacomDevice *wacom)
{
#if HAVE_LIBWACOM
- const char *devnode;
- WacomDeviceDatabase *db;
- WacomDevice *libwacom_device = NULL;
- int vid = evdev_device_get_id_vendor(device);
-
- db = tablet_libinput_context(tablet)->libwacom.db;
- if (!db)
- return;
-
- devnode = udev_device_get_devnode(device->udev_device);
- libwacom_device = libwacom_new_from_path(db, devnode, WFALLBACK_NONE, NULL);
- if (!libwacom_device)
- return;
-
- *is_display_tablet = !!(libwacom_get_integration_flags(libwacom_device)
- & (WACOM_DEVICE_INTEGRATED_SYSTEM|WACOM_DEVICE_INTEGRATED_DISPLAY));
+ return wacom &&
+ !!(libwacom_get_integration_flags(wacom) & (WACOM_DEVICE_INTEGRATED_SYSTEM|WACOM_DEVICE_INTEGRATED_DISPLAY));
+#else
+ return false;
+#endif
+}
+static inline bool
+tablet_is_aes(struct evdev_device *device, WacomDevice *wacom)
+{
+#if HAVE_LIBWACOM
+ int vid = evdev_device_get_id_vendor(device);
/* Wacom-specific check for whether smoothing is required:
* libwacom keeps all the AES pens in a single group, so any device
* that supports AES pens will list all AES pens. 0x11 is one of the
* lenovo pens so we use that as the flag of whether the tablet
* is an AES tablet
*/
- if (vid == VENDOR_ID_WACOM) {
+ if (wacom && vid == VENDOR_ID_WACOM) {
int nstyli;
- const int *stylus_ids = libwacom_get_supported_styli(libwacom_device, &nstyli);
+ const int *stylus_ids = libwacom_get_supported_styli(wacom, &nstyli);
for (int i = 0; i < nstyli; i++) {
if (stylus_ids[i] == 0x11) {
- *is_aes = true;
- break;
+ return true;
}
}
}
-
- libwacom_destroy(libwacom_device);
#endif
+
+ return false;
}
static void
tablet_init(struct tablet_dispatch *tablet,
struct evdev_device *device)
{
+ struct libinput *li = evdev_libinput_context(device);
struct libevdev *evdev = device->evdev;
enum libinput_tablet_tool_axis axis;
- int rc;
+ int rc = -1;
+ WacomDevice *wacom = NULL;
+#if HAVE_LIBWACOM
+ WacomDeviceDatabase *db = libinput_libwacom_ref(li);
+ if (db) {
+ char event_path[64];
+ snprintf(event_path,
+ sizeof(event_path),
+ "/dev/input/%s",
+ evdev_device_get_sysname(device));
+ wacom = libwacom_new_from_path(db, event_path, WFALLBACK_NONE, NULL);
+ if (!wacom) {
+ wacom = libwacom_new_from_usbid(db,
+ evdev_device_get_id_vendor(device),
+ evdev_device_get_id_product(device),
+ NULL);
+ }
+ if (!wacom) {
+ evdev_log_info(device,
+ "device \"%s\" (%04x:%04x) is not known to libwacom\n",
+ evdev_device_get_name(device),
+ evdev_device_get_id_vendor(device),
+ evdev_device_get_id_product(device));
+ }
+ }
+#endif
tablet->base.dispatch_type = DISPATCH_TABLET;
tablet->base.interface = &tablet_interface;
list_init(&tablet->tool_list);
if (tablet_reject_device(device))
- return -1;
+ goto out;
- bool is_aes = false;
- bool is_display_tablet = false;
- tablet_lookup_libwacom(device, tablet, &is_aes, &is_display_tablet);
+ bool is_aes = tablet_is_aes(device, wacom);
+ bool is_display_tablet = tablet_is_display_tablet(wacom);
if (!libevdev_has_event_code(evdev, EV_KEY, BTN_TOOL_PEN)) {
libevdev_enable_event_code(evdev, EV_KEY, BTN_TOOL_PEN, NULL);
tablet_init_proximity_threshold(tablet, device);
rc = tablet_init_accel(tablet, device);
if (rc != 0)
- return rc;
+ goto out;
evdev_init_sendevents(device, &tablet->base);
- tablet_init_left_handed(device);
+ tablet_init_left_handed(device, wacom);
tablet_init_smoothing(device, tablet, is_aes);
for (axis = LIBINPUT_TABLET_TOOL_AXIS_X;
tablet->quirks.need_to_force_prox_out = true;
libinput_timer_init(&tablet->quirks.prox_out_timer,
- tablet_libinput_context(tablet),
+ li,
"proxout",
tablet_proximity_out_quirk_timer_func,
tablet);
- return 0;
+ rc = 0;
+out:
+#if HAVE_LIBWACOM
+ if (wacom)
+ libwacom_destroy(wacom);
+ if (db)
+ libinput_libwacom_unref(li);
+#endif
+ return rc;
}
struct evdev_dispatch *
#include "evdev.h"
+#if !HAVE_LIBWACOM
+typedef void * WacomDevice;
+#endif
+
#define LIBINPUT_TABLET_TOOL_AXIS_NONE 0
#define LIBINPUT_TOOL_NONE 0
#define LIBINPUT_TABLET_TOOL_TYPE_MAX LIBINPUT_TABLET_TOOL_TYPE_LENS
udev_device_unref(device->udev_device);
free(device);
}
-
-bool
-evdev_tablet_has_left_handed(struct evdev_device *device)
-{
- bool has_left_handed = true;
-#if HAVE_LIBWACOM
- struct libinput *li = evdev_libinput_context(device);
- WacomDeviceDatabase *db = NULL;
- WacomDevice *d = NULL;
- WacomError *error;
- const char *devnode;
-
- db = libinput_libwacom_ref(li);
- if (!db)
- goto out;
-
- error = libwacom_error_new();
- devnode = udev_device_get_devnode(device->udev_device);
-
- d = libwacom_new_from_path(db,
- devnode,
- WFALLBACK_NONE,
- error);
-
- if (d) {
- has_left_handed = !!libwacom_is_reversible(d);
- } else if (libwacom_error_get_code(error) == WERROR_UNKNOWN_MODEL) {
- evdev_log_info(device,
- "tablet '%s' unknown to libwacom\n",
- device->devname);
- } else {
- evdev_log_error(device,
- "libwacom error: %s\n",
- libwacom_error_get_message(error));
- }
-
- if (error)
- libwacom_error_free(&error);
- if (d)
- libwacom_destroy(d);
- if (db)
- libinput_libwacom_unref(li);
-
-out:
-#endif
- return has_left_handed;
-}
evdev_init_left_handed(struct evdev_device *device,
void (*change_to_left_handed)(struct evdev_device *));
-bool
-evdev_tablet_has_left_handed(struct evdev_device *device);
-
static inline uint32_t
evdev_to_left_handed(struct evdev_device *device,
uint32_t button)