<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>