xref: /third_party/libinput/src/quirks.c (revision a46c0ec8)
1/*
2 * Copyright © 2018 Red Hat, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#include "config.h"
25
26/* This has the hallmarks of a library to make it re-usable from the tests
27 * and from the list-quirks tool. It doesn't have all of the features from a
28 * library you'd expect though
29 */
30
31#undef NDEBUG /* You don't get to disable asserts here */
32#include <assert.h>
33#include <stdlib.h>
34#include <libudev.h>
35#include <dirent.h>
36#include <fnmatch.h>
37#include <libgen.h>
38#ifdef __FreeBSD__
39#include <kenv.h>
40#endif
41
42#include "libinput-versionsort.h"
43#include "libinput-util.h"
44
45#include "quirks.h"
46
47/* Custom logging so we can have detailed output for the tool but minimal
48 * logging for libinput itself. */
49#define qlog_debug(ctx_, ...) quirk_log_msg((ctx_), QLOG_NOISE, __VA_ARGS__)
50#define qlog_info(ctx_, ...) quirk_log_msg((ctx_),  QLOG_INFO, __VA_ARGS__)
51#define qlog_error(ctx_, ...) quirk_log_msg((ctx_), QLOG_ERROR, __VA_ARGS__)
52#define qlog_parser(ctx_, ...) quirk_log_msg((ctx_), QLOG_PARSER_ERROR, __VA_ARGS__)
53
54enum property_type {
55	PT_UINT,
56	PT_INT,
57	PT_STRING,
58	PT_BOOL,
59	PT_DIMENSION,
60	PT_RANGE,
61	PT_DOUBLE,
62	PT_TUPLES,
63	PT_UINT_ARRAY,
64};
65
66struct quirk_array {
67	union {
68		uint32_t u[32];
69	} data;
70	size_t nelements;
71};
72
73/**
74 * Generic value holder for the property types we support. The type
75 * identifies which value in the union is defined and we expect callers to
76 * already know which type yields which value.
77 */
78struct property {
79	size_t refcount;
80	struct list link; /* struct sections.properties */
81
82	enum quirk id;
83	enum property_type type;
84	union {
85		bool b;
86		uint32_t u;
87		int32_t i;
88		char *s;
89		double d;
90		struct quirk_dimensions dim;
91		struct quirk_range range;
92		struct quirk_tuples tuples;
93		struct quirk_array array;
94	} value;
95};
96
97enum match_flags {
98	M_NAME		= bit(0),
99	M_BUS		= bit(1),
100	M_VID		= bit(2),
101	M_PID		= bit(3),
102	M_DMI		= bit(4),
103	M_UDEV_TYPE	= bit(5),
104	M_DT		= bit(6),
105	M_VERSION	= bit(7),
106
107	M_LAST		= M_VERSION,
108};
109
110enum bustype {
111	BT_UNKNOWN,
112	BT_USB,
113	BT_BLUETOOTH,
114	BT_PS2,
115	BT_RMI,
116	BT_I2C,
117	BT_SPI,
118};
119
120enum udev_type {
121	UDEV_MOUSE		= bit(1),
122	UDEV_POINTINGSTICK	= bit(2),
123	UDEV_TOUCHPAD		= bit(3),
124	UDEV_TABLET		= bit(4),
125	UDEV_TABLET_PAD		= bit(5),
126	UDEV_JOYSTICK		= bit(6),
127	UDEV_KEYBOARD		= bit(7),
128};
129
130/**
131 * Contains the combined set of matches for one section or the values for
132 * one device.
133 *
134 * bits defines which fields are set, the rest is zero.
135 */
136struct match {
137	uint32_t bits;
138
139	char *name;
140	enum bustype bus;
141	uint32_t vendor;
142	uint32_t product;
143	uint32_t version;
144
145	char *dmi;	/* dmi modalias with preceding "dmi:" */
146
147	/* We can have more than one type set, so this is a bitfield */
148	uint32_t udev_type;
149
150	char *dt;	/* device tree compatible (first) string */
151};
152
153/**
154 * Represents one section in the .quirks file.
155 */
156struct section {
157	struct list link;
158
159	bool has_match;		/* to check for empty sections */
160	bool has_property;	/* to check for empty sections */
161
162	char *name;		/* the [Section Name] */
163	struct match match;
164	struct list properties;
165};
166
167/**
168 * The struct returned to the caller. It contains the
169 * properties for a given device.
170 */
171struct quirks {
172	size_t refcount;
173	struct list link; /* struct quirks_context.quirks */
174
175	/* These are not ref'd, just a collection of pointers */
176	struct property **properties;
177	size_t nproperties;
178
179	/* Special properties for AttrEventCode and AttrInputCode, these are
180	 * owned by us, not the section */
181	struct list floating_properties;
182};
183
184/**
185 * Quirk matching context, initialized once with quirks_init_subsystem()
186 */
187struct quirks_context {
188	size_t refcount;
189
190	libinput_log_handler log_handler;
191	enum quirks_log_type log_type;
192	struct libinput *libinput; /* for logging */
193
194	char *dmi;
195	char *dt;
196
197	struct list sections;
198
199	/* list of quirks handed to libinput, just for bookkeeping */
200	struct list quirks;
201};
202
203LIBINPUT_ATTRIBUTE_PRINTF(3, 0)
204static inline void
205quirk_log_msg_va(struct quirks_context *ctx,
206		 enum quirks_log_priorities priority,
207		 const char *format,
208		 va_list args)
209{
210	switch (priority) {
211	/* We don't use this if we're logging through libinput */
212	default:
213	case QLOG_NOISE:
214	case QLOG_PARSER_ERROR:
215		if (ctx->log_type == QLOG_LIBINPUT_LOGGING)
216			return;
217		break;
218	case QLOG_DEBUG: /* These map straight to libinput priorities */
219	case QLOG_INFO:
220	case QLOG_ERROR:
221		break;
222	}
223
224	ctx->log_handler(ctx->libinput,
225			 (enum libinput_log_priority)priority,
226			 format,
227			 args);
228}
229
230LIBINPUT_ATTRIBUTE_PRINTF(3, 4)
231static inline void
232quirk_log_msg(struct quirks_context *ctx,
233	      enum quirks_log_priorities priority,
234	      const char *format,
235	      ...)
236{
237	va_list args;
238
239	va_start(args, format);
240	quirk_log_msg_va(ctx, priority, format, args);
241	va_end(args);
242
243}
244
245const char *
246quirk_get_name(enum quirk q)
247{
248	switch(q) {
249	case QUIRK_MODEL_ALPS_SERIAL_TOUCHPAD:		return "ModelALPSSerialTouchpad";
250	case QUIRK_MODEL_APPLE_TOUCHPAD:		return "ModelAppleTouchpad";
251	case QUIRK_MODEL_APPLE_TOUCHPAD_ONEBUTTON:	return "ModelAppleTouchpadOneButton";
252	case QUIRK_MODEL_BOUNCING_KEYS:			return "ModelBouncingKeys";
253	case QUIRK_MODEL_CHROMEBOOK:			return "ModelChromebook";
254	case QUIRK_MODEL_CLEVO_W740SU:			return "ModelClevoW740SU";
255	case QUIRK_MODEL_DELL_CANVAS_TOTEM:		return "ModelDellCanvasTotem";
256	case QUIRK_MODEL_HP_PAVILION_DM4_TOUCHPAD:	return "ModelHPPavilionDM4Touchpad";
257	case QUIRK_MODEL_HP_ZBOOK_STUDIO_G3:		return "ModelHPZBookStudioG3";
258	case QUIRK_MODEL_INVERT_HORIZONTAL_SCROLLING:	return "ModelInvertHorizontalScrolling";
259	case QUIRK_MODEL_LENOVO_SCROLLPOINT:		return "ModelLenovoScrollPoint";
260	case QUIRK_MODEL_LENOVO_T450_TOUCHPAD:		return "ModelLenovoT450Touchpad";
261	case QUIRK_MODEL_LENOVO_X1GEN6_TOUCHPAD:	return "ModelLenovoX1Gen6Touchpad";
262	case QUIRK_MODEL_LENOVO_X230:			return "ModelLenovoX230";
263	case QUIRK_MODEL_SYNAPTICS_SERIAL_TOUCHPAD:	return "ModelSynapticsSerialTouchpad";
264	case QUIRK_MODEL_SYSTEM76_BONOBO:		return "ModelSystem76Bonobo";
265	case QUIRK_MODEL_SYSTEM76_GALAGO:		return "ModelSystem76Galago";
266	case QUIRK_MODEL_SYSTEM76_KUDU:			return "ModelSystem76Kudu";
267	case QUIRK_MODEL_TABLET_MODE_NO_SUSPEND:	return "ModelTabletModeNoSuspend";
268	case QUIRK_MODEL_TABLET_MODE_SWITCH_UNRELIABLE:	return "ModelTabletModeSwitchUnreliable";
269	case QUIRK_MODEL_TOUCHPAD_VISIBLE_MARKER:	return "ModelTouchpadVisibleMarker";
270	case QUIRK_MODEL_TOUCHPAD_PHANTOM_CLICKS:	return "ModelTouchpadPhantomClicks";
271	case QUIRK_MODEL_TRACKBALL:			return "ModelTrackball";
272	case QUIRK_MODEL_WACOM_TOUCHPAD:		return "ModelWacomTouchpad";
273	case QUIRK_MODEL_PRESSURE_PAD:			return "ModelPressurePad";
274
275	case QUIRK_ATTR_SIZE_HINT:			return "AttrSizeHint";
276	case QUIRK_ATTR_TOUCH_SIZE_RANGE:		return "AttrTouchSizeRange";
277	case QUIRK_ATTR_PALM_SIZE_THRESHOLD:		return "AttrPalmSizeThreshold";
278	case QUIRK_ATTR_LID_SWITCH_RELIABILITY:		return "AttrLidSwitchReliability";
279	case QUIRK_ATTR_KEYBOARD_INTEGRATION:		return "AttrKeyboardIntegration";
280	case QUIRK_ATTR_TRACKPOINT_INTEGRATION:		return "AttrPointingStickIntegration";
281	case QUIRK_ATTR_TPKBCOMBO_LAYOUT:		return "AttrTPKComboLayout";
282	case QUIRK_ATTR_PRESSURE_RANGE:			return "AttrPressureRange";
283	case QUIRK_ATTR_PALM_PRESSURE_THRESHOLD:	return "AttrPalmPressureThreshold";
284	case QUIRK_ATTR_RESOLUTION_HINT:		return "AttrResolutionHint";
285	case QUIRK_ATTR_TRACKPOINT_MULTIPLIER:		return "AttrTrackpointMultiplier";
286	case QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD:	return "AttrThumbPressureThreshold";
287	case QUIRK_ATTR_USE_VELOCITY_AVERAGING:		return "AttrUseVelocityAveraging";
288	case QUIRK_ATTR_TABLET_SMOOTHING:               return "AttrTabletSmoothing";
289	case QUIRK_ATTR_THUMB_SIZE_THRESHOLD:		return "AttrThumbSizeThreshold";
290	case QUIRK_ATTR_MSC_TIMESTAMP:			return "AttrMscTimestamp";
291	case QUIRK_ATTR_EVENT_CODE:			return "AttrEventCode";
292	case QUIRK_ATTR_INPUT_PROP:			return "AttrInputProp";
293	default:
294		abort();
295	}
296}
297
298static inline const char *
299matchflagname(enum match_flags f)
300{
301	switch(f) {
302	case M_NAME:		return "MatchName";		break;
303	case M_BUS:		return "MatchBus";		break;
304	case M_VID:		return "MatchVendor";		break;
305	case M_PID:		return "MatchProduct";		break;
306	case M_VERSION:		return "MatchVersion";		break;
307	case M_DMI:		return "MatchDMIModalias";	break;
308	case M_UDEV_TYPE:	return "MatchUdevType";		break;
309	case M_DT:		return "MatchDeviceTree";	break;
310	default:
311		abort();
312	}
313}
314
315static inline struct property *
316property_new(void)
317{
318	struct property *p;
319
320	p = zalloc(sizeof *p);
321	p->refcount = 1;
322	list_init(&p->link);
323
324	return p;
325}
326
327static inline struct property *
328property_ref(struct property *p)
329{
330	assert(p->refcount > 0);
331	p->refcount++;
332	return p;
333}
334
335static inline struct property *
336property_unref(struct property *p)
337{
338	/* Note: we don't cleanup here, that is a separate call so we
339	   can abort if we haven't cleaned up correctly.  */
340	assert(p->refcount > 0);
341	p->refcount--;
342
343	return NULL;
344}
345
346/* Separate call so we can verify that the caller unrefs the property
347 * before shutting down the subsystem.
348 */
349static inline void
350property_cleanup(struct property *p)
351{
352	/* If we get here, the quirks must've been removed already */
353	property_unref(p);
354	assert(p->refcount == 0);
355
356	list_remove(&p->link);
357	if (p->type == PT_STRING)
358		free(p->value.s);
359	free(p);
360}
361
362/**
363 * Return the system DMI info in modalias format.
364 */
365#ifdef __linux__
366static inline char *
367init_dmi_linux(void)
368{
369	struct udev *udev;
370	struct udev_device *udev_device;
371	const char *modalias = NULL;
372	char *copy = NULL;
373	const char *syspath = "/sys/devices/virtual/dmi/id";
374
375	udev = udev_new();
376	if (!udev)
377		return NULL;
378
379	udev_device = udev_device_new_from_syspath(udev, syspath);
380	if (udev_device)
381		modalias = udev_device_get_property_value(udev_device,
382							  "MODALIAS");
383
384	/* Not sure whether this could ever really fail, if so we should
385	 * open the sysfs file directly. But then udev wouldn't have failed,
386	 * so... */
387	if (!modalias)
388		modalias = "dmi:*";
389
390	copy = safe_strdup(modalias);
391
392	udev_device_unref(udev_device);
393	udev_unref(udev);
394
395	return copy;
396}
397#endif
398
399#ifdef __FreeBSD__
400static inline char *
401init_dmi_freebsd(void)
402{
403#define LEN (KENV_MVALLEN + 1)
404	char *modalias;
405	char bios_vendor[LEN], bios_version[LEN], bios_date[LEN];
406	char sys_vendor[LEN], product_name[LEN], product_version[LEN];
407	char board_vendor[LEN], board_name[LEN], board_version[LEN];
408	char chassis_vendor[LEN], chassis_type[LEN], chassis_version[LEN];
409	int chassis_type_num = 0x2;
410
411	kenv(KENV_GET, "smbios.bios.vendor", bios_vendor, LEN);
412	kenv(KENV_GET, "smbios.bios.version", bios_version, LEN);
413	kenv(KENV_GET, "smbios.bios.reldate", bios_date, LEN);
414	kenv(KENV_GET, "smbios.system.maker", sys_vendor, LEN);
415	kenv(KENV_GET, "smbios.system.product", product_name, LEN);
416	kenv(KENV_GET, "smbios.system.version", product_version, LEN);
417	kenv(KENV_GET, "smbios.planar.maker", board_vendor, LEN);
418	kenv(KENV_GET, "smbios.planar.product", board_name, LEN);
419	kenv(KENV_GET, "smbios.planar.version", board_version, LEN);
420	kenv(KENV_GET, "smbios.chassis.vendor", chassis_vendor, LEN);
421	kenv(KENV_GET, "smbios.chassis.type", chassis_type, LEN);
422	kenv(KENV_GET, "smbios.chassis.version", chassis_version, LEN);
423#undef LEN
424
425	if (strcmp(chassis_type, "Desktop") == 0)
426		chassis_type_num = 0x3;
427	else if (strcmp(chassis_type, "Portable") == 0)
428		chassis_type_num = 0x8;
429	else if (strcmp(chassis_type, "Laptop") == 0)
430		chassis_type_num = 0x9;
431	else if (strcmp(chassis_type, "Notebook") == 0)
432		chassis_type_num = 0xA;
433	else if (strcmp(chassis_type, "Tablet") == 0)
434		chassis_type_num = 0x1E;
435	else if (strcmp(chassis_type, "Convertible") == 0)
436		chassis_type_num = 0x1F;
437	else if (strcmp(chassis_type, "Detachable") == 0)
438		chassis_type_num = 0x20;
439
440	xasprintf(&modalias,
441		"dmi:bvn%s:bvr%s:bd%s:svn%s:pn%s:pvr%s:rvn%s:rn%s:rvr%s:cvn%s:ct%d:cvr%s:",
442		bios_vendor, bios_version, bios_date, sys_vendor, product_name,
443		product_version, board_vendor, board_name, board_version, chassis_vendor,
444		chassis_type_num, chassis_version);
445
446	return modalias;
447}
448#endif
449
450static inline char *
451init_dmi(void)
452{
453	if (getenv("LIBINPUT_RUNNING_TEST_SUITE"))
454		return safe_strdup("dmi:");
455
456#if defined(__linux__)
457	return init_dmi_linux();
458#elif defined(__FreeBSD__)
459	return init_dmi_freebsd();
460#else
461	return NULL;
462#endif
463}
464
465/**
466 * Return the dt compatible string
467 */
468static inline char *
469init_dt(void)
470{
471	char compatible[1024];
472	char *copy = NULL;
473	const char *syspath = "/sys/firmware/devicetree/base/compatible";
474	FILE *fp;
475
476	if (getenv("LIBINPUT_RUNNING_TEST_SUITE"))
477		return safe_strdup("");
478
479	fp = fopen(syspath, "r");
480	if (!fp)
481		return NULL;
482
483	/* devicetree/base/compatible has multiple null-terminated entries
484	   but we only care about the first one here, so strdup is enough */
485	if (fgets(compatible, sizeof(compatible), fp)) {
486		copy = safe_strdup(compatible);
487	}
488
489	fclose(fp);
490
491	return copy;
492}
493
494static inline struct section *
495section_new(const char *path, const char *name)
496{
497	struct section *s = zalloc(sizeof(*s));
498
499	char *path_dup = safe_strdup(path);
500	xasprintf(&s->name, "%s (%s)", name, basename(path_dup));
501	free(path_dup);
502	list_init(&s->link);
503	list_init(&s->properties);
504
505	return s;
506}
507
508static inline void
509section_destroy(struct section *s)
510{
511	struct property *p;
512
513	free(s->name);
514	free(s->match.name);
515	free(s->match.dmi);
516	free(s->match.dt);
517
518	list_for_each_safe(p, &s->properties, link)
519		property_cleanup(p);
520
521	assert(list_empty(&s->properties));
522
523	list_remove(&s->link);
524	free(s);
525}
526
527static inline bool
528parse_hex(const char *value, unsigned int *parsed)
529{
530	return strneq(value, "0x", 2) &&
531	       safe_atou_base(value, parsed, 16) &&
532	       strspn(value, "0123456789xABCDEF") == strlen(value) &&
533	       *parsed <= 0xFFFF;
534}
535
536/**
537 * Parse a MatchFooBar=banana line.
538 *
539 * @param section The section struct to be filled in
540 * @param key The MatchFooBar part of the line
541 * @param value The banana part of the line.
542 *
543 * @return true on success, false otherwise.
544 */
545static bool
546parse_match(struct quirks_context *ctx,
547	    struct section *s,
548	    const char *key,
549	    const char *value)
550{
551	int rc = false;
552
553#define check_set_bit(s_, bit_) { \
554		if ((s_)->match.bits & (bit_)) goto out; \
555		(s_)->match.bits |= (bit_); \
556	}
557
558	assert(strlen(value) >= 1);
559
560	if (streq(key, "MatchName")) {
561		check_set_bit(s, M_NAME);
562		s->match.name = safe_strdup(value);
563	} else if (streq(key, "MatchBus")) {
564		check_set_bit(s, M_BUS);
565		if (streq(value, "usb"))
566			s->match.bus = BT_USB;
567		else if (streq(value, "bluetooth"))
568			s->match.bus = BT_BLUETOOTH;
569		else if (streq(value, "ps2"))
570			s->match.bus = BT_PS2;
571		else if (streq(value, "rmi"))
572			s->match.bus = BT_RMI;
573		else if (streq(value, "i2c"))
574			s->match.bus = BT_I2C;
575		else if (streq(value, "spi"))
576			s->match.bus = BT_SPI;
577		else
578			goto out;
579	} else if (streq(key, "MatchVendor")) {
580		unsigned int vendor;
581
582		check_set_bit(s, M_VID);
583		if (!parse_hex(value, &vendor))
584			goto out;
585
586		s->match.vendor = vendor;
587	} else if (streq(key, "MatchProduct")) {
588		unsigned int product;
589
590		check_set_bit(s, M_PID);
591		if (!parse_hex(value, &product))
592			goto out;
593
594		s->match.product = product;
595	} else if (streq(key, "MatchVersion")) {
596		unsigned int version;
597
598		check_set_bit(s, M_VERSION);
599		if (!parse_hex(value, &version))
600			goto out;
601
602		s->match.version = version;
603	} else if (streq(key, "MatchDMIModalias")) {
604		check_set_bit(s, M_DMI);
605		if (!strneq(value, "dmi:", 4)) {
606			qlog_parser(ctx,
607				    "%s: MatchDMIModalias must start with 'dmi:'\n",
608				    s->name);
609			goto out;
610		}
611		s->match.dmi = safe_strdup(value);
612	} else if (streq(key, "MatchUdevType")) {
613		check_set_bit(s, M_UDEV_TYPE);
614		if (streq(value, "touchpad"))
615			s->match.udev_type = UDEV_TOUCHPAD;
616		else if (streq(value, "mouse"))
617			s->match.udev_type = UDEV_MOUSE;
618		else if (streq(value, "pointingstick"))
619			s->match.udev_type = UDEV_POINTINGSTICK;
620		else if (streq(value, "keyboard"))
621			s->match.udev_type = UDEV_KEYBOARD;
622		else if (streq(value, "joystick"))
623			s->match.udev_type = UDEV_JOYSTICK;
624		else if (streq(value, "tablet"))
625			s->match.udev_type = UDEV_TABLET;
626		else if (streq(value, "tablet-pad"))
627			s->match.udev_type = UDEV_TABLET_PAD;
628		else
629			goto out;
630	} else if (streq(key, "MatchDeviceTree")) {
631		check_set_bit(s, M_DT);
632		s->match.dt = safe_strdup(value);
633	} else {
634		qlog_error(ctx, "Unknown match key '%s'\n", key);
635		goto out;
636	}
637
638#undef check_set_bit
639	s->has_match = true;
640	rc = true;
641out:
642	return rc;
643}
644
645/**
646 * Parse a ModelFooBar=1 line.
647 *
648 * @param section The section struct to be filled in
649 * @param key The ModelFooBar part of the line
650 * @param value The value after the =, must be 1 or 0.
651 *
652 * @return true on success, false otherwise.
653 */
654static bool
655parse_model(struct quirks_context *ctx,
656	    struct section *s,
657	    const char *key,
658	    const char *value)
659{
660	bool b;
661	enum quirk q = QUIRK_MODEL_ALPS_SERIAL_TOUCHPAD;
662
663	assert(strneq(key, "Model", 5));
664
665	if (!parse_boolean_property(value, &b))
666		return false;
667
668	do {
669		if (streq(key, quirk_get_name(q))) {
670			struct property *p = property_new();
671			p->id = q,
672			p->type = PT_BOOL;
673			p->value.b = b;
674			list_append(&s->properties, &p->link);
675			s->has_property = true;
676			return true;
677		}
678	} while (++q < _QUIRK_LAST_MODEL_QUIRK_);
679
680	qlog_error(ctx, "Unknown key %s in %s\n", key, s->name);
681
682	return false;
683}
684
685/**
686 * Parse a AttrFooBar=banana line.
687 *
688 * @param section The section struct to be filled in
689 * @param key The AttrFooBar part of the line
690 * @param value The banana part of the line.
691 *
692 * Value parsing depends on the attribute type.
693 *
694 * @return true on success, false otherwise.
695 */
696static inline bool
697parse_attr(struct quirks_context *ctx,
698	   struct section *s,
699	   const char *key,
700	   const char *value)
701{
702	struct property *p = property_new();
703	bool rc = false;
704	struct quirk_dimensions dim;
705	struct quirk_range range;
706	unsigned int v;
707	bool b;
708	double d;
709
710	if (streq(key, quirk_get_name(QUIRK_ATTR_SIZE_HINT))) {
711		p->id = QUIRK_ATTR_SIZE_HINT;
712		if (!parse_dimension_property(value, &dim.x, &dim.y))
713			goto out;
714		p->type = PT_DIMENSION;
715		p->value.dim = dim;
716		rc = true;
717	} else if (streq(key, quirk_get_name(QUIRK_ATTR_TOUCH_SIZE_RANGE))) {
718		p->id = QUIRK_ATTR_TOUCH_SIZE_RANGE;
719		if (!parse_range_property(value, &range.upper, &range.lower))
720			goto out;
721		p->type = PT_RANGE;
722		p->value.range = range;
723		rc = true;
724	} else if (streq(key, quirk_get_name(QUIRK_ATTR_PALM_SIZE_THRESHOLD))) {
725		p->id = QUIRK_ATTR_PALM_SIZE_THRESHOLD;
726		if (!safe_atou(value, &v))
727			goto out;
728		p->type = PT_UINT;
729		p->value.u = v;
730		rc = true;
731	} else if (streq(key, quirk_get_name(QUIRK_ATTR_LID_SWITCH_RELIABILITY))) {
732		p->id = QUIRK_ATTR_LID_SWITCH_RELIABILITY;
733		if (!streq(value, "reliable") &&
734		    !streq(value, "write_open") &&
735		    !streq(value, "unreliable"))
736			goto out;
737		p->type = PT_STRING;
738		p->value.s = safe_strdup(value);
739		rc = true;
740	} else if (streq(key, quirk_get_name(QUIRK_ATTR_KEYBOARD_INTEGRATION))) {
741		p->id = QUIRK_ATTR_KEYBOARD_INTEGRATION;
742		if (!streq(value, "internal") && !streq(value, "external"))
743			goto out;
744		p->type = PT_STRING;
745		p->value.s = safe_strdup(value);
746		rc = true;
747	} else if (streq(key, quirk_get_name(QUIRK_ATTR_TRACKPOINT_INTEGRATION))) {
748		p->id = QUIRK_ATTR_TRACKPOINT_INTEGRATION;
749		if (!streq(value, "internal") && !streq(value, "external"))
750			goto out;
751		p->type = PT_STRING;
752		p->value.s = safe_strdup(value);
753		rc = true;
754	} else if (streq(key, quirk_get_name(QUIRK_ATTR_TPKBCOMBO_LAYOUT))) {
755		p->id = QUIRK_ATTR_TPKBCOMBO_LAYOUT;
756		if (!streq(value, "below"))
757			goto out;
758		p->type = PT_STRING;
759		p->value.s = safe_strdup(value);
760		rc = true;
761	} else if (streq(key, quirk_get_name(QUIRK_ATTR_PRESSURE_RANGE))) {
762		p->id = QUIRK_ATTR_PRESSURE_RANGE;
763		if (!parse_range_property(value, &range.upper, &range.lower))
764			goto out;
765		p->type = PT_RANGE;
766		p->value.range = range;
767		rc = true;
768	} else if (streq(key, quirk_get_name(QUIRK_ATTR_PALM_PRESSURE_THRESHOLD))) {
769		p->id = QUIRK_ATTR_PALM_PRESSURE_THRESHOLD;
770		if (!safe_atou(value, &v))
771			goto out;
772		p->type = PT_UINT;
773		p->value.u = v;
774		rc = true;
775	} else if (streq(key, quirk_get_name(QUIRK_ATTR_RESOLUTION_HINT))) {
776		p->id = QUIRK_ATTR_RESOLUTION_HINT;
777		if (!parse_dimension_property(value, &dim.x, &dim.y))
778			goto out;
779		p->type = PT_DIMENSION;
780		p->value.dim = dim;
781		rc = true;
782	} else if (streq(key, quirk_get_name(QUIRK_ATTR_TRACKPOINT_MULTIPLIER))) {
783		p->id = QUIRK_ATTR_TRACKPOINT_MULTIPLIER;
784		if (!safe_atod(value, &d))
785			goto out;
786		p->type = PT_DOUBLE;
787		p->value.d = d;
788		rc = true;
789	} else if (streq(key, quirk_get_name(QUIRK_ATTR_USE_VELOCITY_AVERAGING))) {
790		p->id = QUIRK_ATTR_USE_VELOCITY_AVERAGING;
791		if (!parse_boolean_property(value, &b))
792			goto out;
793		p->type = PT_BOOL;
794		p->value.b = b;
795		rc = true;
796	} else if (streq(key, quirk_get_name(QUIRK_ATTR_TABLET_SMOOTHING))) {
797		p->id = QUIRK_ATTR_TABLET_SMOOTHING;
798		if (!parse_boolean_property(value, &b))
799			goto out;
800		p->type = PT_BOOL;
801		p->value.b = b;
802		rc = true;
803	} else if (streq(key, quirk_get_name(QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD))) {
804		p->id = QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD;
805		if (!safe_atou(value, &v))
806			goto out;
807		p->type = PT_UINT;
808		p->value.u = v;
809		rc = true;
810	} else if (streq(key, quirk_get_name(QUIRK_ATTR_THUMB_SIZE_THRESHOLD))) {
811		p->id = QUIRK_ATTR_THUMB_SIZE_THRESHOLD;
812		if (!safe_atou(value, &v))
813			goto out;
814		p->type = PT_UINT;
815		p->value.u = v;
816		rc = true;
817	} else if (streq(key, quirk_get_name(QUIRK_ATTR_MSC_TIMESTAMP))) {
818		p->id = QUIRK_ATTR_MSC_TIMESTAMP;
819		if (!streq(value, "watch"))
820			goto out;
821		p->type = PT_STRING;
822		p->value.s = safe_strdup(value);
823		rc = true;
824	} else if (streq(key, quirk_get_name(QUIRK_ATTR_EVENT_CODE))) {
825		struct input_event events[32];
826		size_t nevents = ARRAY_LENGTH(events);
827
828		p->id = QUIRK_ATTR_EVENT_CODE;
829
830		if (!parse_evcode_property(value, events, &nevents) ||
831		    nevents == 0)
832			goto out;
833
834		for (size_t i = 0; i < nevents; i++) {
835			p->value.tuples.tuples[i].first = events[i].type;
836			p->value.tuples.tuples[i].second = events[i].code;
837			p->value.tuples.tuples[i].third = events[i].value;
838		}
839		p->value.tuples.ntuples = nevents;
840		p->type = PT_TUPLES;
841
842		rc = true;
843	} else if (streq(key, quirk_get_name(QUIRK_ATTR_INPUT_PROP))) {
844		struct input_prop props[INPUT_PROP_CNT];
845		size_t nprops = ARRAY_LENGTH(props);
846
847		p->id = QUIRK_ATTR_INPUT_PROP;
848
849		if (!parse_input_prop_property(value, props, &nprops) ||
850		    nprops == 0)
851			goto out;
852
853		for (size_t i = 0; i < nprops; i++) {
854			p->value.tuples.tuples[i].first = props[i].prop;
855			p->value.tuples.tuples[i].second = props[i].enabled;
856		}
857
858		p->value.tuples.ntuples = nprops;
859		p->type = PT_TUPLES;
860
861		rc = true;
862	} else {
863		qlog_error(ctx, "Unknown key %s in %s\n", key, s->name);
864	}
865out:
866	if (rc) {
867		list_append(&s->properties, &p->link);
868		s->has_property = true;
869	} else {
870		property_cleanup(p);
871	}
872	return rc;
873}
874
875/**
876 * Parse a single line, expected to be in the format Key=value. Anything
877 * else will be rejected with a failure.
878 *
879 * Our data files can only have Match, Model and Attr, so let's check for
880 * those too.
881 */
882static bool
883parse_value_line(struct quirks_context *ctx, struct section *s, const char *line)
884{
885	bool rc = false;
886
887	size_t nelem;
888	char **strv = strv_from_string(line, "=", &nelem);
889	if (!strv || nelem != 2)
890		goto out;
891
892	const char *key = strv[0];
893	const char *value = strv[1];
894	if (strlen(key) == 0 || strlen(value) == 0)
895		goto out;
896
897	/* Whatever the value is, it's not supposed to be in quotes */
898	if (value[0] == '"' || value[0] == '\'')
899		goto out;
900
901	if (strneq(key, "Match", 5))
902		rc = parse_match(ctx, s, key, value);
903	else if (strneq(key, "Model", 5))
904		rc = parse_model(ctx, s, key, value);
905	else if (strneq(key, "Attr", 4))
906		rc = parse_attr(ctx, s, key, value);
907	else
908		qlog_error(ctx, "Unknown value prefix %s\n", line);
909out:
910	strv_free(strv);
911	return rc;
912}
913
914static inline bool
915parse_file(struct quirks_context *ctx, const char *path)
916{
917	enum state {
918		STATE_SECTION,
919		STATE_MATCH,
920		STATE_MATCH_OR_VALUE,
921		STATE_VALUE_OR_SECTION,
922		STATE_ANY,
923	};
924	FILE *fp;
925	char line[512];
926	bool rc = false;
927	enum state state = STATE_SECTION;
928	struct section *section = NULL;
929	int lineno = -1;
930
931	qlog_debug(ctx, "%s\n", path);
932
933	/* Not using open_restricted here, if we can't access
934	 * our own data files, our installation is screwed up.
935	 */
936	fp = fopen(path, "r");
937	if (!fp) {
938		/* If the file doesn't exist that's fine. Only way this can
939		 * happen is for the custom override file, all others are
940		 * provided by scandir so they do exist. Short of races we
941		 * don't care about. */
942		if (errno == ENOENT)
943			return true;
944
945		qlog_error(ctx, "%s: failed to open file\n", path);
946		goto out;
947	}
948
949	while (fgets(line, sizeof(line), fp)) {
950		char *comment;
951
952		lineno++;
953
954		comment = strstr(line, "#");
955		if (comment) {
956			/* comment points to # but we need to remove the
957			 * preceding whitespaces too */
958			comment--;
959			while (comment >= line) {
960				if (*comment != ' ' && *comment != '\t')
961					break;
962				comment--;
963			}
964			*(comment + 1) = '\0';
965		} else { /* strip the trailing newline */
966			comment = strstr(line, "\n");
967			if (comment)
968				*comment = '\0';
969		}
970		if (strlen(line) == 0)
971			continue;
972
973		/* We don't use quotes for strings, so we really don't want
974		 * erroneous trailing whitespaces */
975		switch (line[strlen(line) - 1]) {
976		case ' ':
977		case '\t':
978			qlog_parser(ctx,
979				    "%s:%d: Trailing whitespace '%s'\n",
980				    path, lineno, line);
981			goto out;
982		}
983
984		switch (line[0]) {
985		case '\0':
986		case '\n':
987		case '#':
988			break;
989		/* white space not allowed */
990		case ' ':
991		case '\t':
992			qlog_parser(ctx, "%s:%d: Preceding whitespace '%s'\n",
993					 path, lineno, line);
994			goto out;
995		/* section title */
996		case '[':
997			if (line[strlen(line) - 1] != ']') {
998				qlog_parser(ctx, "%s:%d: Closing ] missing '%s'\n",
999					    path, lineno, line);
1000				goto out;
1001			}
1002
1003			if (state != STATE_SECTION &&
1004			    state != STATE_VALUE_OR_SECTION) {
1005				qlog_parser(ctx, "%s:%d: expected section before %s\n",
1006					  path, lineno, line);
1007				goto out;
1008			}
1009			if (section &&
1010			    (!section->has_match || !section->has_property)) {
1011				qlog_parser(ctx, "%s:%d: previous section %s was empty\n",
1012					  path, lineno, section->name);
1013				goto out; /* Previous section was empty */
1014			}
1015
1016			state = STATE_MATCH;
1017			section = section_new(path, line);
1018			list_append(&ctx->sections, &section->link);
1019			break;
1020		default:
1021			/* entries must start with A-Z */
1022			if (line[0] < 'A' || line[0] > 'Z') {
1023				qlog_parser(ctx, "%s:%d: Unexpected line %s\n",
1024						 path, lineno, line);
1025				goto out;
1026			}
1027			switch (state) {
1028			case STATE_SECTION:
1029				qlog_parser(ctx, "%s:%d: expected [Section], got %s\n",
1030					  path, lineno, line);
1031				goto out;
1032			case STATE_MATCH:
1033				if (!strneq(line, "Match", 5)) {
1034					qlog_parser(ctx, "%s:%d: expected MatchFoo=bar, have %s\n",
1035							 path, lineno, line);
1036					goto out;
1037				}
1038				state = STATE_MATCH_OR_VALUE;
1039				break;
1040			case STATE_MATCH_OR_VALUE:
1041				if (!strneq(line, "Match", 5))
1042					state = STATE_VALUE_OR_SECTION;
1043				break;
1044			case STATE_VALUE_OR_SECTION:
1045				if (strneq(line, "Match", 5)) {
1046					qlog_parser(ctx, "%s:%d: expected value or [Section], have %s\n",
1047							 path, lineno, line);
1048					goto out;
1049				}
1050				break;
1051			case STATE_ANY:
1052				break;
1053			}
1054
1055			if (!parse_value_line(ctx, section, line)) {
1056				qlog_parser(ctx, "%s:%d: failed to parse %s\n",
1057						 path, lineno, line);
1058				goto out;
1059			}
1060			break;
1061		}
1062	}
1063
1064	if (!section) {
1065		qlog_parser(ctx, "%s: is an empty file\n", path);
1066		goto out;
1067	}
1068
1069	if ((!section->has_match || !section->has_property)) {
1070		qlog_parser(ctx, "%s:%d: previous section %s was empty\n",
1071				 path, lineno, section->name);
1072		goto out; /* Previous section was empty */
1073	}
1074
1075	rc = true;
1076out:
1077	if (fp)
1078		fclose(fp);
1079
1080	return rc;
1081}
1082
1083static int
1084is_data_file(const struct dirent *dir) {
1085	return strendswith(dir->d_name, ".quirks");
1086}
1087
1088static inline bool
1089parse_files(struct quirks_context *ctx, const char *data_path)
1090{
1091	struct dirent **namelist;
1092	int ndev = -1;
1093	int idx = 0;
1094
1095	ndev = scandir(data_path, &namelist, is_data_file, versionsort);
1096	if (ndev <= 0) {
1097		qlog_error(ctx,
1098			   "%s: failed to find data files\n",
1099			   data_path);
1100		return false;
1101	}
1102
1103	for (idx = 0; idx < ndev; idx++) {
1104		char path[PATH_MAX];
1105
1106		snprintf(path,
1107			 sizeof(path),
1108			 "%s/%s",
1109			 data_path,
1110			 namelist[idx]->d_name);
1111
1112		if (!parse_file(ctx, path))
1113			break;
1114	}
1115
1116	for (int i = 0; i < ndev; i++)
1117		free(namelist[i]);
1118	free(namelist);
1119
1120	return idx == ndev;
1121}
1122
1123struct quirks_context *
1124quirks_init_subsystem(const char *data_path,
1125		      const char *override_file,
1126		      libinput_log_handler log_handler,
1127		      struct libinput *libinput,
1128		      enum quirks_log_type log_type)
1129{
1130	struct quirks_context *ctx = zalloc(sizeof *ctx);
1131
1132	assert(data_path);
1133
1134	ctx->refcount = 1;
1135	ctx->log_handler = log_handler;
1136	ctx->log_type = log_type;
1137	ctx->libinput = libinput;
1138	list_init(&ctx->quirks);
1139	list_init(&ctx->sections);
1140
1141	qlog_debug(ctx, "%s is data root\n", data_path);
1142
1143	ctx->dmi = init_dmi();
1144	ctx->dt = init_dt();
1145	if (!ctx->dmi && !ctx->dt)
1146		goto error;
1147
1148	if (!parse_files(ctx, data_path))
1149		goto error;
1150
1151	if (override_file && !parse_file(ctx, override_file))
1152		goto error;
1153
1154	return ctx;
1155
1156error:
1157	quirks_context_unref(ctx);
1158	return NULL;
1159}
1160
1161struct quirks_context *
1162quirks_context_ref(struct quirks_context *ctx)
1163{
1164	assert(ctx->refcount > 0);
1165	ctx->refcount++;
1166
1167	return ctx;
1168}
1169
1170struct quirks_context *
1171quirks_context_unref(struct quirks_context *ctx)
1172{
1173	struct section *s;
1174
1175	if (!ctx)
1176		return NULL;
1177
1178	assert(ctx->refcount >= 1);
1179	ctx->refcount--;
1180
1181	if (ctx->refcount > 0)
1182		return NULL;
1183
1184	/* Caller needs to clean up before calling this */
1185	assert(list_empty(&ctx->quirks));
1186
1187	list_for_each_safe(s, &ctx->sections, link) {
1188		section_destroy(s);
1189	}
1190
1191	free(ctx->dmi);
1192	free(ctx->dt);
1193	free(ctx);
1194
1195	return NULL;
1196}
1197
1198static struct quirks *
1199quirks_new(void)
1200{
1201	struct quirks *q;
1202
1203	q = zalloc(sizeof *q);
1204	q->refcount = 1;
1205	q->nproperties = 0;
1206	list_init(&q->link);
1207	list_init(&q->floating_properties);
1208
1209	return q;
1210}
1211
1212struct quirks *
1213quirks_unref(struct quirks *q)
1214{
1215	if (!q)
1216		return NULL;
1217
1218	/* We don't really refcount, but might
1219	 * as well have the API in place */
1220	assert(q->refcount == 1);
1221
1222	for (size_t i = 0; i < q->nproperties; i++) {
1223		property_unref(q->properties[i]);
1224	}
1225
1226	/* Floating properties are owned by our quirks context, need to be
1227	 * cleaned up here */
1228	struct property *p;
1229	list_for_each_safe(p, &q->floating_properties, link) {
1230		property_cleanup(p);
1231	}
1232
1233	list_remove(&q->link);
1234	free(q->properties);
1235	free(q);
1236
1237	return NULL;
1238}
1239
1240/**
1241 * Searches for the udev property on this device and its parent devices.
1242 *
1243 * @return the value of the property or NULL
1244 */
1245static const char *
1246udev_prop(struct udev_device *device, const char *prop)
1247{
1248	struct udev_device *d = device;
1249	const char *value = NULL;
1250
1251	do {
1252		value = udev_device_get_property_value(d, prop);
1253		d = udev_device_get_parent(d);
1254	} while (value == NULL && d != NULL);
1255
1256	return value;
1257}
1258
1259static inline void
1260match_fill_name(struct match *m,
1261		struct udev_device *device)
1262{
1263	const char *str = udev_prop(device, "NAME");
1264	size_t slen;
1265
1266	if (!str)
1267		return;
1268
1269	/* udev NAME is in quotes, strip them */
1270	if (str[0] == '"')
1271		str++;
1272
1273	m->name = safe_strdup(str);
1274	slen = strlen(m->name);
1275	if (slen > 1 &&
1276	    m->name[slen - 1] == '"')
1277		m->name[slen - 1] = '\0';
1278
1279	m->bits |= M_NAME;
1280}
1281
1282static inline void
1283match_fill_bus_vid_pid(struct match *m,
1284		       struct udev_device *device)
1285{
1286	const char *str;
1287	unsigned int product, vendor, bus, version;
1288
1289	str = udev_prop(device, "PRODUCT");
1290	if (!str)
1291		return;
1292
1293	/* ID_VENDOR_ID/ID_PRODUCT_ID/ID_BUS aren't filled in for virtual
1294	 * devices so we have to resort to PRODUCT  */
1295	if (sscanf(str, "%x/%x/%x/%x", &bus, &vendor, &product, &version) != 4)
1296		return;
1297
1298	m->product = product;
1299	m->vendor = vendor;
1300	m->version = version;
1301	m->bits |= M_PID|M_VID|M_VERSION;
1302	switch (bus) {
1303	case BUS_USB:
1304		m->bus = BT_USB;
1305		m->bits |= M_BUS;
1306		break;
1307	case BUS_BLUETOOTH:
1308		m->bus = BT_BLUETOOTH;
1309		m->bits |= M_BUS;
1310		break;
1311	case BUS_I8042:
1312		m->bus = BT_PS2;
1313		m->bits |= M_BUS;
1314		break;
1315	case BUS_RMI:
1316		m->bus = BT_RMI;
1317		m->bits |= M_BUS;
1318		break;
1319	case BUS_I2C:
1320		m->bus = BT_I2C;
1321		m->bits |= M_BUS;
1322		break;
1323	case BUS_SPI:
1324		m->bus = BT_SPI;
1325		m->bits |= M_BUS;
1326		break;
1327	default:
1328		break;
1329	}
1330}
1331
1332static inline void
1333match_fill_udev_type(struct match *m,
1334		     struct udev_device *device)
1335{
1336	struct ut_map {
1337		const char *prop;
1338		enum udev_type flag;
1339	} mappings[] = {
1340		{ "ID_INPUT_MOUSE", UDEV_MOUSE },
1341		{ "ID_INPUT_POINTINGSTICK", UDEV_POINTINGSTICK },
1342		{ "ID_INPUT_TOUCHPAD", UDEV_TOUCHPAD },
1343		{ "ID_INPUT_TABLET", UDEV_TABLET },
1344		{ "ID_INPUT_TABLET_PAD", UDEV_TABLET_PAD },
1345		{ "ID_INPUT_JOYSTICK", UDEV_JOYSTICK },
1346		{ "ID_INPUT_KEYBOARD", UDEV_KEYBOARD },
1347		{ "ID_INPUT_KEY", UDEV_KEYBOARD },
1348	};
1349
1350	ARRAY_FOR_EACH(mappings, map) {
1351		if (udev_prop(device, map->prop))
1352			m->udev_type |= map->flag;
1353	}
1354	m->bits |= M_UDEV_TYPE;
1355}
1356
1357static inline void
1358match_fill_dmi_dt(struct match *m, char *dmi, char *dt)
1359{
1360	if (dmi) {
1361		m->dmi = dmi;
1362		m->bits |= M_DMI;
1363	}
1364
1365	if (dt) {
1366		m->dt = dt;
1367		m->bits |= M_DT;
1368	}
1369}
1370
1371static struct match *
1372match_new(struct udev_device *device,
1373	  char *dmi, char *dt)
1374{
1375	struct match *m = zalloc(sizeof *m);
1376
1377	match_fill_name(m, device);
1378	match_fill_bus_vid_pid(m, device);
1379	match_fill_dmi_dt(m, dmi, dt);
1380	match_fill_udev_type(m, device);
1381	return m;
1382}
1383
1384static void
1385match_free(struct match *m)
1386{
1387	/* dmi and dt are global */
1388	free(m->name);
1389	free(m);
1390}
1391
1392static void
1393quirk_merge_event_codes(struct quirks_context *ctx,
1394			struct quirks *q,
1395			const struct property *property)
1396{
1397	for (size_t i = 0; i < q->nproperties; i++) {
1398		struct property *p = q->properties[i];
1399
1400		if (p->id != property->id)
1401			continue;
1402
1403		/* We have a duplicated property, merge in with ours */
1404		size_t offset = p->value.tuples.ntuples;
1405		size_t max = ARRAY_LENGTH(p->value.tuples.tuples);
1406		for (size_t j = 0; j < property->value.tuples.ntuples; j++) {
1407			if (offset + j >= max)
1408				break;
1409			p->value.tuples.tuples[offset + j] = property->value.tuples.tuples[j];
1410			p->value.tuples.ntuples++;
1411		}
1412		return;
1413	}
1414
1415	/* First time we add AttrEventCode: create a new property.
1416	 * Unlike the other properties, this one isn't part of a section, it belongs
1417	 * to the quirks */
1418	struct property *newprop = property_new();
1419	newprop->id = property->id;
1420	newprop->type = property->type;
1421	newprop->value.tuples = property->value.tuples;
1422	/* Caller responsible for pre-allocating space */
1423	q->properties[q->nproperties++] = property_ref(newprop);
1424	list_append(&q->floating_properties, &newprop->link);
1425}
1426
1427static void
1428quirk_apply_section(struct quirks_context *ctx,
1429		    struct quirks *q,
1430		    const struct section *s)
1431{
1432	struct property *p;
1433	size_t nprops = 0;
1434	void *tmp;
1435
1436	list_for_each(p, &s->properties, link) {
1437		nprops++;
1438	}
1439
1440	nprops += q->nproperties;
1441	tmp = realloc(q->properties, nprops * sizeof(p));
1442	if (!tmp)
1443		return;
1444
1445	q->properties = tmp;
1446	list_for_each(p, &s->properties, link) {
1447		qlog_debug(ctx, "property added: %s from %s\n",
1448			   quirk_get_name(p->id), s->name);
1449
1450		/* All quirks but AttrEventCode and AttrInputProp
1451		 * simply overwrite each other, so we can just append the
1452		 * matching property and, later when checking the quirk, pick
1453		 * the last one in the array.
1454		 *
1455		 * The event codes/input props are special because they're lists
1456		 * that may *partially* override each other, e.g. a section may
1457		 * enable BTN_LEFT and BTN_RIGHT but a later section may disable
1458		 * only BTN_RIGHT. This should result in BTN_LEFT force-enabled
1459		 * and BTN_RIGHT force-disabled.
1460		 *
1461		 * To hack around this, those are the only ones where only ever
1462		 * have one struct property in the list (not owned by a section)
1463		 * and we simply merge any extra sections onto that.
1464		 */
1465		if (p->id == QUIRK_ATTR_EVENT_CODE ||
1466		    p->id == QUIRK_ATTR_INPUT_PROP)
1467			quirk_merge_event_codes(ctx, q, p);
1468		else
1469			q->properties[q->nproperties++] = property_ref(p);
1470	}
1471}
1472
1473static bool
1474quirk_match_section(struct quirks_context *ctx,
1475		    struct quirks *q,
1476		    struct section *s,
1477		    struct match *m,
1478		    struct udev_device *device)
1479{
1480	uint32_t matched_flags = 0x0;
1481
1482	for (uint32_t flag = 0x1; flag <= M_LAST; flag <<= 1) {
1483		uint32_t prev_matched_flags = matched_flags;
1484		/* section doesn't have this bit set, continue */
1485		if ((s->match.bits & flag) == 0)
1486			continue;
1487
1488		/* Couldn't fill in this bit for the match, so we
1489		 * do not match on it */
1490		if ((m->bits & flag) == 0) {
1491			qlog_debug(ctx,
1492				   "%s wants %s but we don't have that\n",
1493				   s->name, matchflagname(flag));
1494			continue;
1495		}
1496
1497		/* now check the actual matching bit */
1498		switch (flag) {
1499		case M_NAME:
1500			if (fnmatch(s->match.name, m->name, 0) == 0)
1501				matched_flags |= flag;
1502			break;
1503		case M_BUS:
1504			if (m->bus == s->match.bus)
1505				matched_flags |= flag;
1506			break;
1507		case M_VID:
1508			if (m->vendor == s->match.vendor)
1509				matched_flags |= flag;
1510			break;
1511		case M_PID:
1512			if (m->product == s->match.product)
1513				matched_flags |= flag;
1514			break;
1515		case M_VERSION:
1516			if (m->version == s->match.version)
1517				matched_flags |= flag;
1518			break;
1519		case M_DMI:
1520			if (fnmatch(s->match.dmi, m->dmi, 0) == 0)
1521				matched_flags |= flag;
1522			break;
1523		case M_DT:
1524			if (fnmatch(s->match.dt, m->dt, 0) == 0)
1525				matched_flags |= flag;
1526			break;
1527		case M_UDEV_TYPE:
1528			if (s->match.udev_type & m->udev_type)
1529				matched_flags |= flag;
1530			break;
1531		default:
1532			abort();
1533		}
1534
1535		if (prev_matched_flags != matched_flags) {
1536			qlog_debug(ctx,
1537				   "%s matches for %s\n",
1538				   s->name,
1539				   matchflagname(flag));
1540		}
1541	}
1542
1543	if (s->match.bits == matched_flags) {
1544		qlog_debug(ctx, "%s is full match\n", s->name);
1545		quirk_apply_section(ctx, q, s);
1546	}
1547
1548	return true;
1549}
1550
1551struct quirks *
1552quirks_fetch_for_device(struct quirks_context *ctx,
1553			struct udev_device *udev_device)
1554{
1555	struct quirks *q = NULL;
1556	struct section *s;
1557	struct match *m;
1558
1559	if (!ctx)
1560		return NULL;
1561
1562	qlog_debug(ctx, "%s: fetching quirks\n",
1563		   udev_device_get_devnode(udev_device));
1564
1565	q = quirks_new();
1566
1567	m = match_new(udev_device, ctx->dmi, ctx->dt);
1568
1569	list_for_each(s, &ctx->sections, link) {
1570		quirk_match_section(ctx, q, s, m, udev_device);
1571	}
1572
1573	match_free(m);
1574
1575	if (q->nproperties == 0) {
1576		quirks_unref(q);
1577		return NULL;
1578	}
1579
1580	list_insert(&ctx->quirks, &q->link);
1581
1582	return q;
1583}
1584
1585static inline struct property *
1586quirk_find_prop(struct quirks *q, enum quirk which)
1587{
1588	/* Run backwards to only handle the last one assigned */
1589	for (ssize_t i = q->nproperties - 1; i >= 0; i--) {
1590		struct property *p = q->properties[i];
1591		if (p->id == which)
1592			return p;
1593	}
1594
1595	return NULL;
1596}
1597
1598bool
1599quirks_has_quirk(struct quirks *q, enum quirk which)
1600{
1601	return quirk_find_prop(q, which) != NULL;
1602}
1603
1604bool
1605quirks_get_int32(struct quirks *q, enum quirk which, int32_t *val)
1606{
1607	struct property *p;
1608
1609	if (!q)
1610		return false;
1611
1612	p = quirk_find_prop(q, which);
1613	if (!p)
1614		return false;
1615
1616	assert(p->type == PT_INT);
1617	*val = p->value.i;
1618
1619	return true;
1620}
1621
1622bool
1623quirks_get_uint32(struct quirks *q, enum quirk which, uint32_t *val)
1624{
1625	struct property *p;
1626
1627	if (!q)
1628		return false;
1629
1630	p = quirk_find_prop(q, which);
1631	if (!p)
1632		return false;
1633
1634	assert(p->type == PT_UINT);
1635	*val = p->value.u;
1636
1637	return true;
1638}
1639
1640bool
1641quirks_get_double(struct quirks *q, enum quirk which, double *val)
1642{
1643	struct property *p;
1644
1645	if (!q)
1646		return false;
1647
1648	p = quirk_find_prop(q, which);
1649	if (!p)
1650		return false;
1651
1652	assert(p->type == PT_DOUBLE);
1653	*val = p->value.d;
1654
1655	return true;
1656}
1657
1658bool
1659quirks_get_string(struct quirks *q, enum quirk which, char **val)
1660{
1661	struct property *p;
1662
1663	if (!q)
1664		return false;
1665
1666	p = quirk_find_prop(q, which);
1667	if (!p)
1668		return false;
1669
1670	assert(p->type == PT_STRING);
1671	*val = p->value.s;
1672
1673	return true;
1674}
1675
1676bool
1677quirks_get_bool(struct quirks *q, enum quirk which, bool *val)
1678{
1679	struct property *p;
1680
1681	if (!q)
1682		return false;
1683
1684	p = quirk_find_prop(q, which);
1685	if (!p)
1686		return false;
1687
1688	assert(p->type == PT_BOOL);
1689	*val = p->value.b;
1690
1691	return true;
1692}
1693
1694bool
1695quirks_get_dimensions(struct quirks *q,
1696		      enum quirk which,
1697		      struct quirk_dimensions *val)
1698{
1699	struct property *p;
1700
1701	if (!q)
1702		return false;
1703
1704	p = quirk_find_prop(q, which);
1705	if (!p)
1706		return false;
1707
1708	assert(p->type == PT_DIMENSION);
1709	*val = p->value.dim;
1710
1711	return true;
1712}
1713
1714bool
1715quirks_get_range(struct quirks *q,
1716		 enum quirk which,
1717		 struct quirk_range *val)
1718{
1719	struct property *p;
1720
1721	if (!q)
1722		return false;
1723
1724	p = quirk_find_prop(q, which);
1725	if (!p)
1726		return false;
1727
1728	assert(p->type == PT_RANGE);
1729	*val = p->value.range;
1730
1731	return true;
1732}
1733
1734bool
1735quirks_get_tuples(struct quirks *q,
1736		  enum quirk which,
1737		  const struct quirk_tuples **tuples)
1738{
1739	struct property *p;
1740
1741	if (!q)
1742		return false;
1743
1744	p = quirk_find_prop(q, which);
1745	if (!p)
1746		return false;
1747
1748	assert(p->type == PT_TUPLES);
1749	*tuples = &p->value.tuples;
1750
1751	return true;
1752}
1753
1754bool
1755quirks_get_uint32_array(struct quirks *q,
1756			enum quirk which,
1757			const uint32_t **array,
1758			size_t *nelements)
1759{
1760	struct property *p;
1761
1762	if (!q)
1763		return false;
1764
1765	p = quirk_find_prop(q, which);
1766	if (!p)
1767		return false;
1768
1769	assert(p->type == PT_UINT_ARRAY);
1770	*array = p->value.array.data.u;
1771	*nelements = p->value.array.nelements;
1772
1773	return true;
1774}
1775