• 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 *code;
50  	unsigned int axes[] = {ABS_X,
51  			       ABS_Y,
52  			       ABS_MT_POSITION_X,
53  			       ABS_MT_POSITION_Y};
54  
55  	devnode = udev_device_get_devnode(device);
56  	if (!devnode)
57  		goto out;
58  
59  	fd = open(devnode, O_RDONLY);
60  	if (fd < 0)
61  		goto out;
62  
63  	rc = libevdev_new_from_fd(fd, &evdev);
64  	if (rc != 0)
65  		goto out;
66  
67  	if (!libevdev_has_event_type(evdev, EV_ABS))
68  		goto out;
69  
70  	ARRAY_FOR_EACH(axes, code) {
71  		int fuzz;
72  
73  		fuzz = libevdev_get_abs_fuzz(evdev, *code);
74  		if (fuzz)
75  			printf("LIBINPUT_FUZZ_%02x=%d\n", *code, fuzz);
76  	}
77  
78  out:
79  	close(fd);
80  	libevdev_free(evdev);
81  }
82  
83  /**
84   * Where a device has EVDEV_ABS_... set with a fuzz, that fuzz hasn't been
85   * applied to the kernel yet. So we need to extract it ourselves **and**
86   * update the property so the kernel won't actually set it later.
87   */
88  static void
handle_evdev_abs(struct udev_device * device)89  handle_evdev_abs(struct udev_device *device)
90  {
91  	unsigned int *code;
92  	unsigned int axes[] = {ABS_X,
93  			       ABS_Y,
94  			       ABS_MT_POSITION_X,
95  			       ABS_MT_POSITION_Y};
96  
97  	ARRAY_FOR_EACH(axes, code) {
98  		const char *prop;
99  		char name[64];
100  		uint32_t mask;
101  		struct input_absinfo abs;
102  
103  		snprintf(name, sizeof(name), "EVDEV_ABS_%02X", *code);
104  		prop = udev_device_get_property_value(device, name);
105  		if (!prop)
106  			continue;
107  
108  		mask = parse_evdev_abs_prop(prop, &abs);
109  		if (mask & ABS_MASK_FUZZ)
110  			printf("LIBINPUT_FUZZ_%02x=%d\n", *code, abs.fuzz);
111  	}
112  }
113  
main(int argc,char ** argv)114  int main(int argc, char **argv)
115  {
116  	int rc = 1;
117  	struct udev *udev = NULL;
118  	struct udev_device *device = NULL;
119  	const char *syspath;
120  
121  	if (argc != 2)
122  		return 1;
123  
124  	syspath = argv[1];
125  
126  	udev = udev_new();
127  	if (!udev)
128  		goto out;
129  
130  	device = udev_device_new_from_syspath(udev, syspath);
131  	if (!device)
132  		goto out;
133  
134  	handle_absfuzz(device);
135  	handle_evdev_abs(device);
136  
137  	rc = 0;
138  
139  out:
140  	if (device)
141  		udev_device_unref(device);
142  	if (udev)
143  		udev_unref(udev);
144  
145  	return rc;
146  }
147