quirks: add a helper function for returning quirks for a device

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1230>
This commit is contained in:
Peter Hutterer 2025-06-16 15:58:11 +10:00
parent 6f403a0cc9
commit 7d8fac2868
7 changed files with 41 additions and 115 deletions

View file

@ -388,8 +388,6 @@ tp_init_thumb(struct tp_dispatch *tp)
struct device_coords edges;
struct phys_coords mm = { 0.0, 0.0 };
uint32_t threshold;
struct quirks_context *quirks;
struct quirks *q;
tp->thumb.detect_thumbs = false;
@ -418,9 +416,7 @@ tp_init_thumb(struct tp_dispatch *tp)
edges = evdev_device_mm_to_units(device, &mm);
tp->thumb.lower_thumb_line = edges.y;
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_MT_PRESSURE)) {
if (quirks_get_uint32(q,
QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD,
@ -441,8 +437,6 @@ tp_init_thumb(struct tp_dispatch *tp)
tp_thumb_reset(tp);
quirks_unref(q);
evdev_log_debug(device,
"thumb: enabled thumb detection (area%s%s)\n",
tp->thumb.use_pressure ? ", pressure" : "",

View file

@ -3284,14 +3284,11 @@ tp_dwtp_config_get_default(struct libinput_device *device)
static inline bool
tp_is_tpkb_combo_below(struct evdev_device *device)
{
struct quirks_context *quirks;
struct quirks *q;
char *prop;
enum tpkbcombo_layout layout = TPKBCOMBO_LAYOUT_UNKNOWN;
int rc = false;
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (!q)
return false;
@ -3300,8 +3297,6 @@ tp_is_tpkb_combo_below(struct evdev_device *device)
layout == TPKBCOMBO_LAYOUT_BELOW;
}
quirks_unref(q);
return rc;
}
@ -3389,16 +3384,12 @@ tp_read_palm_pressure_prop(struct tp_dispatch *tp,
{
const int default_palm_threshold = 130;
uint32_t threshold = default_palm_threshold;
struct quirks_context *quirks;
struct quirks *q;
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
_unref_(quirks) *q = libinput_device_get_quirks(&tp->device->base);
if (!q)
return threshold;
quirks_get_uint32(q, QUIRK_ATTR_PALM_PRESSURE_THRESHOLD, &threshold);
quirks_unref(q);
return threshold;
}
@ -3426,12 +3417,9 @@ static inline void
tp_init_palmdetect_size(struct tp_dispatch *tp,
struct evdev_device *device)
{
struct quirks_context *quirks;
struct quirks *q;
uint32_t threshold;
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (!q)
return;
@ -3441,7 +3429,6 @@ tp_init_palmdetect_size(struct tp_dispatch *tp,
tp->palm.size_threshold = threshold;
}
}
quirks_unref(q);
}
static inline void
@ -3606,8 +3593,6 @@ tp_init_pressure(struct tp_dispatch *tp,
{
const struct input_absinfo *abs;
unsigned int code;
struct quirks_context *quirks;
struct quirks *q;
struct quirk_range r;
int hi, lo;
@ -3620,8 +3605,7 @@ tp_init_pressure(struct tp_dispatch *tp,
abs = libevdev_get_abs_info(device->evdev, code);
assert(abs);
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (q && quirks_get_range(q, QUIRK_ATTR_PRESSURE_RANGE, &r)) {
hi = r.upper;
lo = r.lower;
@ -3629,7 +3613,7 @@ tp_init_pressure(struct tp_dispatch *tp,
if (hi == 0 && lo == 0) {
evdev_log_info(device,
"pressure-based touch detection disabled\n");
goto out;
return;
}
} else {
double range = absinfo_range(abs);
@ -3644,7 +3628,7 @@ tp_init_pressure(struct tp_dispatch *tp,
evdev_log_bug_libinput(device,
"discarding out-of-bounds pressure range %d:%d\n",
hi, lo);
goto out;
return;
}
tp->pressure.use_pressure = true;
@ -3655,19 +3639,14 @@ tp_init_pressure(struct tp_dispatch *tp,
"using pressure-based touch detection (%d:%d)\n",
lo,
hi);
out:
quirks_unref(q);
}
static bool
tp_init_touch_size(struct tp_dispatch *tp,
struct evdev_device *device)
{
struct quirks_context *quirks;
struct quirks *q;
struct quirk_range r;
int lo, hi;
int rc = false;
if (!libevdev_has_event_code(device->evdev,
EV_ABS,
@ -3675,25 +3654,24 @@ tp_init_touch_size(struct tp_dispatch *tp,
return false;
}
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (q && quirks_get_range(q, QUIRK_ATTR_TOUCH_SIZE_RANGE, &r)) {
hi = r.upper;
lo = r.lower;
} else {
goto out;
return false;
}
if (libevdev_get_num_slots(device->evdev) < 5) {
evdev_log_bug_libinput(device,
"Expected 5+ slots for touch size detection\n");
goto out;
return false;
}
if (hi == 0 && lo == 0) {
evdev_log_info(device,
"touch size based touch detection disabled\n");
goto out;
return false;
}
/* Thresholds apply for both major or minor */
@ -3704,11 +3682,7 @@ tp_init_touch_size(struct tp_dispatch *tp,
evdev_log_debug(device,
"using size-based touch detection (%d:%d)\n",
hi, lo);
rc = true;
out:
quirks_unref(q);
return rc;
return true;
}
static void

View file

@ -1157,13 +1157,12 @@ tablet_get_quirked_pressure_thresholds(struct tablet_dispatch *tablet,
int *lo)
{
struct evdev_device *device = tablet->device;
struct quirks_context *quirks = evdev_libinput_context(device)->quirks;
struct quirks *q = quirks_fetch_for_device(quirks, device->udev_device);
struct quirk_range r;
bool status = false;
/* Note: the quirk term "range" refers to the hi/lo settings, not the
* full available range for the pressure axis */
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (q && quirks_get_range(q, QUIRK_ATTR_PRESSURE_RANGE, &r)) {
if (r.lower < r.upper) {
*hi = r.lower;
@ -1174,7 +1173,6 @@ tablet_get_quirked_pressure_thresholds(struct tablet_dispatch *tablet,
}
}
quirks_unref(q);
return status;
}
@ -2873,16 +2871,12 @@ tablet_init_smoothing(struct evdev_device *device,
bool is_virtual)
{
size_t history_size = ARRAY_LENGTH(tablet->history.samples);
struct quirks_context *quirks = NULL;
struct quirks *q = NULL;
bool use_smoothing = true;
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
/* By default, always enable smoothing except on AES or uinput devices.
* AttrTabletSmoothing can override this, if necessary.
*/
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (!q || !quirks_get_bool(q, QUIRK_ATTR_TABLET_SMOOTHING, &use_smoothing))
use_smoothing = !is_aes && !is_virtual;
@ -2890,7 +2884,6 @@ tablet_init_smoothing(struct evdev_device *device,
if (!use_smoothing)
history_size = 1;
quirks_unref(q);
tablet->history.size = history_size;
}

View file

@ -521,8 +521,6 @@ static void
evdev_tag_trackpoint(struct evdev_device *device,
struct udev_device *udev_device)
{
struct quirks_context *quirks;
struct quirks *q;
char *prop;
if (!libevdev_has_property(device->evdev,
@ -532,8 +530,7 @@ evdev_tag_trackpoint(struct evdev_device *device,
device->tags |= EVDEV_TAG_TRACKPOINT;
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (q && quirks_get_string(q, QUIRK_ATTR_TRACKPOINT_INTEGRATION, &prop)) {
if (streq(prop, "internal")) {
/* noop, this is the default anyway */
@ -547,8 +544,6 @@ evdev_tag_trackpoint(struct evdev_device *device,
prop);
}
}
quirks_unref(q);
}
static inline void
@ -569,8 +564,6 @@ static void
evdev_tag_keyboard(struct evdev_device *device,
struct udev_device *udev_device)
{
struct quirks_context *quirks;
struct quirks *q;
char *prop;
int code;
@ -584,8 +577,7 @@ evdev_tag_keyboard(struct evdev_device *device,
return;
}
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (q && quirks_get_string(q, QUIRK_ATTR_KEYBOARD_INTEGRATION, &prop)) {
if (streq(prop, "internal")) {
evdev_tag_keyboard_internal(device);
@ -598,8 +590,6 @@ evdev_tag_keyboard(struct evdev_device *device,
}
}
quirks_unref(q);
device->tags |= EVDEV_TAG_KEYBOARD;
}
@ -1010,12 +1000,9 @@ enum switch_reliability
evdev_read_switch_reliability_prop(struct evdev_device *device)
{
enum switch_reliability r;
struct quirks_context *quirks;
struct quirks *q;
char *prop;
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (!q || !quirks_get_string(q, QUIRK_ATTR_LID_SWITCH_RELIABILITY, &prop)) {
r = RELIABILITY_RELIABLE;
} else if (!parse_switch_reliability_property(prop, &r)) {
@ -1028,8 +1015,6 @@ evdev_read_switch_reliability_prop(struct evdev_device *device)
evdev_log_info(device, "will write switch open events\n");
}
quirks_unref(q);
return r;
}
@ -1418,18 +1403,14 @@ evdev_read_wheel_click_props(struct evdev_device *device)
static inline double
evdev_get_trackpoint_multiplier(struct evdev_device *device)
{
struct quirks_context *quirks;
struct quirks *q;
double multiplier = 1.0;
if (!(device->tags & EVDEV_TAG_TRACKPOINT))
return 1.0;
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (q) {
quirks_get_double(q, QUIRK_ATTR_TRACKPOINT_MULTIPLIER, &multiplier);
quirks_unref(q);
}
if (multiplier <= 0.0) {
@ -1450,17 +1431,12 @@ evdev_get_trackpoint_multiplier(struct evdev_device *device)
static inline bool
evdev_need_velocity_averaging(struct evdev_device *device)
{
struct quirks_context *quirks;
struct quirks *q;
bool use_velocity_averaging = false; /* default off unless we have quirk */
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (q) {
quirks_get_bool(q,
QUIRK_ATTR_USE_VELOCITY_AVERAGING,
&use_velocity_averaging);
quirks_unref(q);
}
if (use_velocity_averaging)
@ -1519,12 +1495,8 @@ evdev_read_model_flags(struct evdev_device *device)
const struct model_map *m = model_map;
uint32_t model_flags = 0;
uint32_t all_model_flags = 0;
struct quirks_context *quirks;
struct quirks *q;
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
while (q && m->quirk) {
bool is_set;
@ -1549,8 +1521,6 @@ evdev_read_model_flags(struct evdev_device *device)
m++;
}
quirks_unref(q);
if (parse_udev_flag(device,
device->udev_device,
"ID_INPUT_TRACKBALL")) {
@ -1584,13 +1554,10 @@ evdev_read_attr_res_prop(struct evdev_device *device,
size_t *xres,
size_t *yres)
{
struct quirks_context *quirks;
struct quirks *q;
struct quirk_dimensions dim;
bool rc = false;
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (!q)
return false;
@ -1600,8 +1567,6 @@ evdev_read_attr_res_prop(struct evdev_device *device,
*yres = dim.y;
}
quirks_unref(q);
return rc;
}
@ -1610,13 +1575,10 @@ evdev_read_attr_size_prop(struct evdev_device *device,
size_t *size_x,
size_t *size_y)
{
struct quirks_context *quirks;
struct quirks *q;
struct quirk_dimensions dim;
bool rc = false;
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (!q)
return false;
@ -1626,8 +1588,6 @@ evdev_read_attr_size_prop(struct evdev_device *device,
*size_y = dim.y;
}
quirks_unref(q);
return rc;
}
@ -2212,8 +2172,6 @@ evdev_drain_fd(int fd)
static inline void
evdev_pre_configure_model_quirks(struct evdev_device *device)
{
struct quirks_context *quirks;
struct quirks *q;
const struct quirk_tuples *t;
char *prop;
bool is_virtual;
@ -2226,8 +2184,7 @@ evdev_pre_configure_model_quirks(struct evdev_device *device)
/* Generally we don't care about MSC_TIMESTAMP and it can cause
* unnecessary wakeups but on some devices we need to watch it for
* pointer jumps */
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
if (!q ||
!quirks_get_string(q, QUIRK_ATTR_MSC_TIMESTAMP, &prop) ||
!streq(prop, "watch")) {
@ -2301,8 +2258,6 @@ evdev_pre_configure_model_quirks(struct evdev_device *device)
}
if (is_virtual)
device->tags |= EVDEV_TAG_VIRTUAL;
quirks_unref(q);
}
static void

View file

@ -393,16 +393,13 @@ static inline bool
evdev_device_has_model_quirk(struct evdev_device *device,
enum quirk model_quirk)
{
struct quirks_context *quirks;
struct quirks *q;
bool result = false;
assert(quirk_get_name(model_quirk) != NULL);
quirks = evdev_libinput_context(device)->quirks;
q = quirks_fetch_for_device(quirks, device->udev_device);
quirks_get_bool(q, model_quirk, &result);
quirks_unref(q);
_unref_(quirks) *q = libinput_device_get_quirks(&device->base);
bool result = false;
if (q)
quirks_get_bool(q, model_quirk, &result);
return result;
}

View file

@ -2011,6 +2011,16 @@ libinput_unref(struct libinput *libinput)
return NULL;
}
struct quirks *
libinput_device_get_quirks(struct libinput_device *device)
{
struct libinput *libinput = libinput_device_get_context(device);
_unref_(udev_device) *udev_device = libinput_device_get_udev_device(device);
if (udev_device)
return quirks_fetch_for_device(libinput->quirks, udev_device);
return NULL;
}
static void
libinput_event_tablet_tool_destroy(struct libinput_event_tablet_tool *event)
{

View file

@ -43,6 +43,9 @@ struct quirks_context;
*/
struct quirks;
struct quirks *
libinput_device_get_quirks(struct libinput_device *device);
struct quirk_dimensions {
size_t x, y;
};