libinput-fuzz-extract.c 3.4 KB

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