evdev_pre_configure_model_quirks(struct evdev_device *device)
{
	struct quirks_context *quirks;
	struct quirks *q;
	const struct quirk_tuples *t;
	const uint32_t *props = NULL;
	size_t nprops = 0;
	char *prop;

	/* Touchpad claims to have 4 slots but only ever sends 2
	 * https://bugs.freedesktop.org/show_bug.cgi?id=98100 */
	if (evdev_device_has_model_quirk(device, QUIRK_MODEL_HP_ZBOOK_STUDIO_G3))
		libevdev_set_abs_maximum(device->evdev, ABS_MT_SLOT, 1);

	/* 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);
	if (!q ||
	    !quirks_get_string(q, QUIRK_ATTR_MSC_TIMESTAMP, &prop) ||
	    !streq(prop, "watch")) {
		libevdev_disable_event_code(device->evdev, EV_MSC, MSC_TIMESTAMP);
	}

	if (quirks_get_tuples(q, QUIRK_ATTR_EVENT_CODE_ENABLE, &t)) {
		for (size_t i = 0; i < t->ntuples; i++) {
			const struct input_absinfo absinfo = {
				.minimum = 0,
				.maximum = 1,
			};

			int type = t->tuples[i].first;
			int code = t->tuples[i].second;

			if (code == EVENT_CODE_UNDEFINED)
				libevdev_enable_event_type(device->evdev, type);
			else
				libevdev_enable_event_code(device->evdev,
							    type,
							    code,
							    type == EV_ABS ?  &absinfo : NULL);
			evdev_log_debug(device,
					"quirks: enabling %s %s (%#x %#x)\n",
					libevdev_event_type_get_name(type),
					libevdev_event_code_get_name(type, code),
					type,
					code);
		}
	}

	if (quirks_get_tuples(q, QUIRK_ATTR_EVENT_CODE_DISABLE, &t)) {
		for (size_t i = 0; i < t->ntuples; i++) {
			int type = t->tuples[i].first;
			int code = t->tuples[i].second;

			if (code == EVENT_CODE_UNDEFINED)
				libevdev_disable_event_type(device->evdev,
							    type);
			else
				libevdev_disable_event_code(device->evdev,
							    type,
							    code);
			evdev_log_debug(device,
					"quirks: disabling %s %s (%#x %#x)\n",
					libevdev_event_type_get_name(type),
					libevdev_event_code_get_name(type, code),
					type,
					code);
		}
	}

	if (quirks_get_uint32_array(q,
				    QUIRK_ATTR_INPUT_PROP_ENABLE,
				    &props,
				    &nprops)) {
		for (size_t idx = 0; idx < nprops; idx++) {
			unsigned int p = props[idx];
			libevdev_enable_property(device->evdev, p);
			evdev_log_debug(device,
					"quirks: enabling %s (%#x)\n",
					libevdev_property_get_name(p),
					p);
		}
	}

	if (quirks_get_uint32_array(q,
					 QUIRK_ATTR_INPUT_PROP_DISABLE,
					 &props,
					 &nprops)) {
#if HAVE_LIBEVDEV_DISABLE_PROPERTY
		for (size_t idx = 0; idx < nprops; idx++) {
			unsigned int p = props[idx];
			libevdev_disable_property(device->evdev, p);
			evdev_log_debug(device,
					"quirks: disabling %s (%#x)\n",
					libevdev_property_get_name(p),
					p);
		}
#else
		evdev_log_error(device,
				"quirks: a quirk for this device requires newer libevdev than installed\n");
#endif
	}

	quirks_unref(q);
}
evdev_pre_configure_model_quirks(struct evdev_device *device)
{
	struct quirks_context *quirks;
	struct quirks *q;
	const struct quirk_tuples *t;
	const uint32_t *props = NULL;
	size_t nprops = 0;
	char *prop;

	 
	if (evdev_device_has_model_quirk(device, QUIRK_MODEL_HP_ZBOOK_STUDIO_G3))
		libevdev_set_abs_maximum(device->evdev, ABS_MT_SLOT, 1);

	 
	quirks = evdev_libinput_context(device)->quirks;
	q = quirks_fetch_for_device(quirks, device->udev_device);
	if (!q ||
	    !quirks_get_string(q, QUIRK_ATTR_MSC_TIMESTAMP, &prop) ||
	    !streq(prop, "watch")) {
		libevdev_disable_event_code(device->evdev, EV_MSC, MSC_TIMESTAMP);
	}

	if (quirks_get_tuples(q, QUIRK_ATTR_EVENT_CODE_ENABLE, &t)) {
		for (size_t i = 0; i < t->ntuples; i++) {
			const struct input_absinfo absinfo = {
				.minimum = 0,
				.maximum = 1,
			};

			int type = t->tuples[i].first;
			int code = t->tuples[i].second;

			if (code == EVENT_CODE_UNDEFINED)
				libevdev_enable_event_type(device->evdev, type);
			else
				libevdev_enable_event_code(device->evdev,
							    type,
							    code,
							    type == EV_ABS ?  &absinfo : NULL);
			evdev_log_debug(device,
					"quirks: enabling %s %s (%#x %#x)\n",
					libevdev_event_type_get_name(type),
					libevdev_event_code_get_name(type, code),
					type,
					code);
		}
	}

	if (quirks_get_tuples(q, QUIRK_ATTR_EVENT_CODE_DISABLE, &t)) {
		for (size_t i = 0; i < t->ntuples; i++) {
			int type = t->tuples[i].first;
			int code = t->tuples[i].second;

			if (code == EVENT_CODE_UNDEFINED)
				libevdev_disable_event_type(device->evdev,
							    type);
			else
				libevdev_disable_event_code(device->evdev,
							    type,
							    code);
			evdev_log_debug(device,
					"quirks: disabling %s %s (%#x %#x)\n",
					libevdev_event_type_get_name(type),
					libevdev_event_code_get_name(type, code),
					type,
					code);
		}
	}

	if (quirks_get_uint32_array(q,
				    QUIRK_ATTR_INPUT_PROP_ENABLE,
				    &props,
				    &nprops)) {
		for (size_t idx = 0; idx < nprops; idx++) {
			unsigned int p = props[idx];
			libevdev_enable_property(device->evdev, p);
			evdev_log_debug(device,
					"quirks: enabling %s (%#x)\n",
					libevdev_property_get_name(p),
					p);
		}
	}

	if (quirks_get_uint32_array(q,
					 QUIRK_ATTR_INPUT_PROP_DISABLE,
					 &props,
					 &nprops)) {
#if HAVE_LIBEVDEV_DISABLE_PROPERTY
		for (size_t idx = 0; idx < nprops; idx++) {
			unsigned int p = props[idx];
			libevdev_disable_property(device->evdev, p);
			evdev_log_debug(device,
					"quirks: disabling %s (%#x)\n",
					libevdev_property_get_name(p),
					p);
		}
#else
		evdev_log_error(device,
				"quirks: a quirk for this device requires newer libevdev than installed\n");
#endif
	}

	quirks_unref(q);
}