• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2015 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 #include <fcntl.h>
27 #include <stdio.h>
28 #include <stdint.h>
29 #include <unistd.h>
30 #include <libudev.h>
31 #include <linux/input.h>
32 #include <libevdev/libevdev.h>
33 
34 #include "util-prop-parsers.h"
35 #include "util-macros.h"
36 
37 /**
38  * For a non-zero fuzz on the x/y axes, print that fuzz as property and
39  * reset the kernel's fuzz to 0.
40  * https://bugs.freedesktop.org/show_bug.cgi?id=105202
41  */
42 static void
handle_absfuzz(struct udev_device * device)43 handle_absfuzz(struct udev_device *device)
44 {
45 	const char *devnode;
46 	struct libevdev *evdev = NULL;
47 	int fd = -1;
48 	int rc;
49 	unsigned int axes[] = {ABS_X,
50 			       ABS_Y,
51 			       ABS_MT_POSITION_X,
52 			       ABS_MT_POSITION_Y};
53 
54 	devnode = udev_device_get_devnode(device);
55 	if (!devnode)
56 		goto out;
57 
58 	fd = open(devnode, O_RDONLY);
59 	if (fd < 0)
60 		goto out;
61 
62 	rc = libevdev_new_from_fd(fd, &evdev);
63 	if (rc != 0)
64 		goto out;
65 
66 	if (!libevdev_has_event_type(evdev, EV_ABS))
67 		goto out;
68 
69 	ARRAY_FOR_EACH(axes, code) {
70 		int fuzz;
71 
72 		fuzz = libevdev_get_abs_fuzz(evdev, *code);
73 		if (fuzz)
74 			printf("LIBINPUT_FUZZ_%02x=%d\n", *code, fuzz);
75 	}
76 
77 out:
78 	close(fd);
79 	libevdev_free(evdev);
80 }
81 
82 /**
83  * Where a device has EVDEV_ABS_... set with a fuzz, that fuzz hasn't been
84  * applied to the kernel yet. So we need to extract it ourselves **and**
85  * update the property so the kernel won't actually set it later.
86  */
87 static void
handle_evdev_abs(struct udev_device * device)88 handle_evdev_abs(struct udev_device *device)
89 {
90 	unsigned int axes[] = {ABS_X,
91 			       ABS_Y,
92 			       ABS_MT_POSITION_X,
93 			       ABS_MT_POSITION_Y};
94 
95 	ARRAY_FOR_EACH(axes, code) {
96 		const char *prop;
97 		char name[64];
98 		uint32_t mask;
99 		struct input_absinfo abs;
100 
101 		snprintf(name, sizeof(name), "EVDEV_ABS_%02X", *code);
102 		prop = udev_device_get_property_value(device, name);
103 		if (!prop)
104 			continue;
105 
106 		mask = parse_evdev_abs_prop(prop, &abs);
107 		if (mask & ABS_MASK_FUZZ)
108 			printf("LIBINPUT_FUZZ_%02x=%d\n", *code, abs.fuzz);
109 	}
110 }
111 
main(int argc,char ** argv)112 int main(int argc, char **argv)
113 {
114 	int rc = 1;
115 	struct udev *udev = NULL;
116 	struct udev_device *device = NULL;
117 	const char *syspath;
118 
119 	if (argc != 2)
120 		return 1;
121 
122 	syspath = argv[1];
123 
124 	udev = udev_new();
125 	if (!udev)
126 		goto out;
127 
128 	device = udev_device_new_from_syspath(udev, syspath);
129 	if (!device)
130 		goto out;
131 
132 	handle_absfuzz(device);
133 	handle_evdev_abs(device);
134 
135 	rc = 0;
136 
137 out:
138 	if (device)
139 		udev_device_unref(device);
140 	if (udev)
141 		udev_unref(udev);
142 
143 	return rc;
144 }
145