mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-26 18:00:07 +01:00
tablet: centralize the libwacom handling
Instead of re-creating the the libwacom device from the database every time we need it let's create it once during tablet|pad_init and pass it down to the functions. This allows us to have one point per tablet/pad where we can log an error if the device is not supported by libwacom - previously this was printed during the left-handed setup. Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1073>
This commit is contained in:
parent
d3bc0c79ff
commit
2b2959fc8b
7 changed files with 154 additions and 165 deletions
|
|
@ -404,23 +404,13 @@ pad_find_button_group(struct pad_dispatch *pad,
|
|||
|
||||
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;
|
||||
|
|
@ -523,11 +513,6 @@ pad_init_leds_from_libwacom(struct pad_dispatch *pad,
|
|||
|
||||
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,
|
||||
|
|
@ -567,7 +552,8 @@ pad_init_fallback_group(struct pad_dispatch *pad)
|
|||
|
||||
int
|
||||
pad_init_leds(struct pad_dispatch *pad,
|
||||
struct evdev_device *device)
|
||||
struct evdev_device *device,
|
||||
WacomDevice *wacom)
|
||||
{
|
||||
int rc = 1;
|
||||
|
||||
|
|
@ -582,7 +568,7 @@ pad_init_leds(struct pad_dispatch *pad,
|
|||
|
||||
/* 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);
|
||||
|
|
|
|||
|
|
@ -642,58 +642,28 @@ static struct evdev_dispatch_interface pad_interface = {
|
|||
|
||||
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;
|
||||
if (tablet) {
|
||||
int num_buttons = libwacom_get_num_buttons(tablet);
|
||||
int map = 0;
|
||||
for (int i = 0; i < num_buttons; i++) {
|
||||
unsigned int code;
|
||||
|
||||
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);
|
||||
code = libwacom_get_button_evdev_code(tablet, 'A' + i);
|
||||
if (code == 0)
|
||||
continue;
|
||||
|
||||
map_set_button_map(pad->button_map[code], map++);
|
||||
}
|
||||
|
||||
pad->nbuttons = map;
|
||||
rc = true;
|
||||
}
|
||||
|
||||
if (!tablet)
|
||||
goto out;
|
||||
|
||||
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;
|
||||
|
||||
map_set_button_map(pad->button_map[code], map++);
|
||||
}
|
||||
|
||||
pad->nbuttons = map;
|
||||
|
||||
rc = true;
|
||||
out:
|
||||
if (tablet)
|
||||
libwacom_destroy(tablet);
|
||||
if (db)
|
||||
libinput_libwacom_unref(li);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -750,23 +720,30 @@ pad_init_keys(struct pad_dispatch *pad, struct evdev_device *device)
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
@ -774,6 +751,34 @@ pad_init_left_handed(struct evdev_device *device)
|
|||
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;
|
||||
|
|
@ -787,15 +792,21 @@ pad_init(struct pad_dispatch *pad, struct evdev_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);
|
||||
|
||||
return 0;
|
||||
rc = pad_init_leds(pad, device, wacom);
|
||||
|
||||
#if HAVE_LIBWACOM
|
||||
if (wacom)
|
||||
libwacom_destroy(wacom);
|
||||
if (db)
|
||||
libinput_libwacom_unref(li);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@
|
|||
|
||||
#include "evdev.h"
|
||||
|
||||
#if !HAVE_LIBWACOM
|
||||
typedef void * WacomDevice;
|
||||
#endif
|
||||
|
||||
#define LIBINPUT_BUTTONSET_AXIS_NONE 0
|
||||
|
||||
enum pad_status {
|
||||
|
|
@ -106,9 +110,13 @@ pad_libinput_context(const struct pad_dispatch *pad)
|
|||
}
|
||||
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -2577,56 +2577,53 @@ tablet_init_accel(struct tablet_dispatch *tablet, struct evdev_device *device)
|
|||
}
|
||||
|
||||
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
|
||||
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
|
||||
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));
|
||||
|
||||
/* 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
|
||||
|
|
@ -2737,9 +2734,35 @@ static int
|
|||
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;
|
||||
|
|
@ -2749,11 +2772,10 @@ tablet_init(struct tablet_dispatch *tablet,
|
|||
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);
|
||||
|
|
@ -2772,10 +2794,10 @@ tablet_init(struct tablet_dispatch *tablet,
|
|||
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;
|
||||
|
|
@ -2792,12 +2814,20 @@ tablet_init(struct tablet_dispatch *tablet,
|
|||
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 *
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@
|
|||
|
||||
#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
|
||||
|
|
|
|||
47
src/evdev.c
47
src/evdev.c
|
|
@ -3128,50 +3128,3 @@ evdev_device_destroy(struct evdev_device *device)
|
|||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -671,9 +671,6 @@ void
|
|||
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)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue