1a46c0ec8Sopenharmony_ci/* 2a46c0ec8Sopenharmony_ci * Copyright © 2015 Red Hat, Inc. 3a46c0ec8Sopenharmony_ci * 4a46c0ec8Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5a46c0ec8Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6a46c0ec8Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7a46c0ec8Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8a46c0ec8Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9a46c0ec8Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10a46c0ec8Sopenharmony_ci * 11a46c0ec8Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12a46c0ec8Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13a46c0ec8Sopenharmony_ci * Software. 14a46c0ec8Sopenharmony_ci * 15a46c0ec8Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16a46c0ec8Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17a46c0ec8Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18a46c0ec8Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19a46c0ec8Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20a46c0ec8Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21a46c0ec8Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 22a46c0ec8Sopenharmony_ci */ 23a46c0ec8Sopenharmony_ci 24a46c0ec8Sopenharmony_ci#include "config.h" 25a46c0ec8Sopenharmony_ci 26a46c0ec8Sopenharmony_ci#include <fcntl.h> 27a46c0ec8Sopenharmony_ci#include <stdio.h> 28a46c0ec8Sopenharmony_ci#include <stdint.h> 29a46c0ec8Sopenharmony_ci#include <unistd.h> 30a46c0ec8Sopenharmony_ci#include <libudev.h> 31a46c0ec8Sopenharmony_ci#include <linux/input.h> 32a46c0ec8Sopenharmony_ci#include <libevdev/libevdev.h> 33a46c0ec8Sopenharmony_ci 34a46c0ec8Sopenharmony_ci#include "util-prop-parsers.h" 35a46c0ec8Sopenharmony_ci#include "util-macros.h" 36a46c0ec8Sopenharmony_ci 37a46c0ec8Sopenharmony_ci/** 38a46c0ec8Sopenharmony_ci * For a non-zero fuzz on the x/y axes, print that fuzz as property and 39a46c0ec8Sopenharmony_ci * reset the kernel's fuzz to 0. 40a46c0ec8Sopenharmony_ci * https://bugs.freedesktop.org/show_bug.cgi?id=105202 41a46c0ec8Sopenharmony_ci */ 42a46c0ec8Sopenharmony_cistatic void 43a46c0ec8Sopenharmony_cihandle_absfuzz(struct udev_device *device) 44a46c0ec8Sopenharmony_ci{ 45a46c0ec8Sopenharmony_ci const char *devnode; 46a46c0ec8Sopenharmony_ci struct libevdev *evdev = NULL; 47a46c0ec8Sopenharmony_ci int fd = -1; 48a46c0ec8Sopenharmony_ci int rc; 49a46c0ec8Sopenharmony_ci unsigned int axes[] = {ABS_X, 50a46c0ec8Sopenharmony_ci ABS_Y, 51a46c0ec8Sopenharmony_ci ABS_MT_POSITION_X, 52a46c0ec8Sopenharmony_ci ABS_MT_POSITION_Y}; 53a46c0ec8Sopenharmony_ci 54a46c0ec8Sopenharmony_ci devnode = udev_device_get_devnode(device); 55a46c0ec8Sopenharmony_ci if (!devnode) 56a46c0ec8Sopenharmony_ci goto out; 57a46c0ec8Sopenharmony_ci 58a46c0ec8Sopenharmony_ci fd = open(devnode, O_RDONLY); 59a46c0ec8Sopenharmony_ci if (fd < 0) 60a46c0ec8Sopenharmony_ci goto out; 61a46c0ec8Sopenharmony_ci 62a46c0ec8Sopenharmony_ci rc = libevdev_new_from_fd(fd, &evdev); 63a46c0ec8Sopenharmony_ci if (rc != 0) 64a46c0ec8Sopenharmony_ci goto out; 65a46c0ec8Sopenharmony_ci 66a46c0ec8Sopenharmony_ci if (!libevdev_has_event_type(evdev, EV_ABS)) 67a46c0ec8Sopenharmony_ci goto out; 68a46c0ec8Sopenharmony_ci 69a46c0ec8Sopenharmony_ci ARRAY_FOR_EACH(axes, code) { 70a46c0ec8Sopenharmony_ci int fuzz; 71a46c0ec8Sopenharmony_ci 72a46c0ec8Sopenharmony_ci fuzz = libevdev_get_abs_fuzz(evdev, *code); 73a46c0ec8Sopenharmony_ci if (fuzz) 74a46c0ec8Sopenharmony_ci printf("LIBINPUT_FUZZ_%02x=%d\n", *code, fuzz); 75a46c0ec8Sopenharmony_ci } 76a46c0ec8Sopenharmony_ci 77a46c0ec8Sopenharmony_ciout: 78a46c0ec8Sopenharmony_ci close(fd); 79a46c0ec8Sopenharmony_ci libevdev_free(evdev); 80a46c0ec8Sopenharmony_ci} 81a46c0ec8Sopenharmony_ci 82a46c0ec8Sopenharmony_ci/** 83a46c0ec8Sopenharmony_ci * Where a device has EVDEV_ABS_... set with a fuzz, that fuzz hasn't been 84a46c0ec8Sopenharmony_ci * applied to the kernel yet. So we need to extract it ourselves **and** 85a46c0ec8Sopenharmony_ci * update the property so the kernel won't actually set it later. 86a46c0ec8Sopenharmony_ci */ 87a46c0ec8Sopenharmony_cistatic void 88a46c0ec8Sopenharmony_cihandle_evdev_abs(struct udev_device *device) 89a46c0ec8Sopenharmony_ci{ 90a46c0ec8Sopenharmony_ci unsigned int axes[] = {ABS_X, 91a46c0ec8Sopenharmony_ci ABS_Y, 92a46c0ec8Sopenharmony_ci ABS_MT_POSITION_X, 93a46c0ec8Sopenharmony_ci ABS_MT_POSITION_Y}; 94a46c0ec8Sopenharmony_ci 95a46c0ec8Sopenharmony_ci ARRAY_FOR_EACH(axes, code) { 96a46c0ec8Sopenharmony_ci const char *prop; 97a46c0ec8Sopenharmony_ci char name[64]; 98a46c0ec8Sopenharmony_ci uint32_t mask; 99a46c0ec8Sopenharmony_ci struct input_absinfo abs; 100a46c0ec8Sopenharmony_ci 101a46c0ec8Sopenharmony_ci snprintf(name, sizeof(name), "EVDEV_ABS_%02X", *code); 102a46c0ec8Sopenharmony_ci prop = udev_device_get_property_value(device, name); 103a46c0ec8Sopenharmony_ci if (!prop) 104a46c0ec8Sopenharmony_ci continue; 105a46c0ec8Sopenharmony_ci 106a46c0ec8Sopenharmony_ci mask = parse_evdev_abs_prop(prop, &abs); 107a46c0ec8Sopenharmony_ci if (mask & ABS_MASK_FUZZ) 108a46c0ec8Sopenharmony_ci printf("LIBINPUT_FUZZ_%02x=%d\n", *code, abs.fuzz); 109a46c0ec8Sopenharmony_ci } 110a46c0ec8Sopenharmony_ci} 111a46c0ec8Sopenharmony_ci 112a46c0ec8Sopenharmony_ciint main(int argc, char **argv) 113a46c0ec8Sopenharmony_ci{ 114a46c0ec8Sopenharmony_ci int rc = 1; 115a46c0ec8Sopenharmony_ci struct udev *udev = NULL; 116a46c0ec8Sopenharmony_ci struct udev_device *device = NULL; 117a46c0ec8Sopenharmony_ci const char *syspath; 118a46c0ec8Sopenharmony_ci 119a46c0ec8Sopenharmony_ci if (argc != 2) 120a46c0ec8Sopenharmony_ci return 1; 121a46c0ec8Sopenharmony_ci 122a46c0ec8Sopenharmony_ci syspath = argv[1]; 123a46c0ec8Sopenharmony_ci 124a46c0ec8Sopenharmony_ci udev = udev_new(); 125a46c0ec8Sopenharmony_ci if (!udev) 126a46c0ec8Sopenharmony_ci goto out; 127a46c0ec8Sopenharmony_ci 128a46c0ec8Sopenharmony_ci device = udev_device_new_from_syspath(udev, syspath); 129a46c0ec8Sopenharmony_ci if (!device) 130a46c0ec8Sopenharmony_ci goto out; 131a46c0ec8Sopenharmony_ci 132a46c0ec8Sopenharmony_ci handle_absfuzz(device); 133a46c0ec8Sopenharmony_ci handle_evdev_abs(device); 134a46c0ec8Sopenharmony_ci 135a46c0ec8Sopenharmony_ci rc = 0; 136a46c0ec8Sopenharmony_ci 137a46c0ec8Sopenharmony_ciout: 138a46c0ec8Sopenharmony_ci if (device) 139a46c0ec8Sopenharmony_ci udev_device_unref(device); 140a46c0ec8Sopenharmony_ci if (udev) 141a46c0ec8Sopenharmony_ci udev_unref(udev); 142a46c0ec8Sopenharmony_ci 143a46c0ec8Sopenharmony_ci return rc; 144a46c0ec8Sopenharmony_ci} 145