<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 17, 2015 at 10:08 PM, Peter Hutterer <span dir="ltr"><<a href="mailto:peter.hutterer@who-t.net" target="_blank">peter.hutterer@who-t.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">A device with REL_X/Y and keys gets marked only as ID_INPUT_KEY, initializes<br>
as keyboard and then segfaults when we send x/y coordinates - pointer<br>
acceleration never initializes.<br>
<br>
Ignore the events and log a bug instead. This intentionally only papers over<br>
the underlying issue, let's wait for a real device to trigger this and then<br>
look at the correct solution.<br>
<br>
+static inline bool<br>
+evdev_reject_relative(struct evdev_device *device,<br>
+ const struct input_event *e,<br>
+ uint64_t time)<br>
+{<br>
+ struct libinput *libinput = device->base.seat->libinput;<br>
+<br>
+ if ((e->code == REL_X || e->code == REL_Y) &&<br>
+ (device->seat_caps & EVDEV_DEVICE_POINTER) == 0) {<br>
+ switch (ratelimit_test(&device->nonpointer_rel_limit)) {<br>
+ case RATELIMIT_PASS:<br>
+ log_bug_libinput(libinput,<br>
+ "REL_X/Y from device '%s', but this device is not a pointer\n",<br>
+ device->devname);<br>
+ break;<br>
+ case RATELIMIT_THRESHOLD:<br>
+ log_bug_libinput(libinput,<br>
+ "REL_X/Y event flood from '%s'\n",<br>
+ device->devname);<br>
+ break;<br>
+ case RATELIMIT_EXCEEDED:<br>
+ break;<br>
+ }<br>
+<br>
+ return true;<br>
+ }<br>
+<br>
+ return false;<br>
+}<br></blockquote><div><br></div><div>It seems like some kind of ratelimit_log(&limit, "format", ...) function might be useful so this is not copied everywhere.<br><br></div><div>Also wondering if there is a direct test for "pointer acceleration never initializes" and perhaps you should do that test instead.<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
static inline void<br>
evdev_process_relative(struct evdev_device *device,<br>
struct input_event *e, uint64_t time)<br>
@@ -645,6 +675,9 @@ evdev_process_relative(struct evdev_device *device,<br>
struct normalized_coords wheel_degrees = { 0.0, 0.0 };<br>
struct discrete_coords discrete = { 0.0, 0.0 };<br>
<br>
+ if (evdev_reject_relative(device, e, time))<br>
+ return;<br>
+<br>
switch (e->code) {<br>
case REL_X:<br>
if (device->pending_event != EVDEV_RELATIVE_MOTION)<br></blockquote><div><br></div><div>I think it would look better and be clearer if you put the evdev_reject_relative call in the REL_X and REL_Y cases of the switch (you could also remove the test for REL_X/Y from the function itself).<br><br><br><br></div></div></div></div>