Changes to XInput Proto Number of Events Cause Xlib WireToEvent Vector Mismatch
Julien Cristau
jcristau at debian.org
Thu Nov 26 01:53:53 PST 2009
On Thu, Nov 26, 2009 at 11:45:39 +1000, Peter Hutterer wrote:
> @@ -117,10 +118,51 @@ XExtDisplayInfo *XextAddDisplay (
> */
> if (dpyinfo->codes) {
> int i, j;
> + int idx = dpyinfo->codes->first_event & 0x3f;
> +
> +
> + /* Xlib extensions use compiled in event numbers. A new library
> + * against an older server may thus expect a different (higher)
> + * number of events than the server will send. We have no way of
> + * knowing the number of events for an extension, the server won't
> + * tell us.
> + *
> + * Depending on the extension initialization order, this smashes the
> + * event_vec[type] for anything after the extension with the
> + * different number of events.
> + *
> + * e.g. server with inputproto 1.3 expects 15 events, libXi with
> + * inputproto 2.0 expects 17 events.
> + * base code is 80, events [80,96] are handled by libXi. events [95,
> + * 96] belong to the next extension already though.
> + * This requires XI to be initialized after the extension occupying
> + * the next range of event codes.
> + *
> + * To avoid this, we have a zeroed out array of extension handlers.
> + * If an extension handler for an event type is already set, and the
> + * previous event code (before base_code) is the same extension, we
> + * have the nevents conflict. Unset all those handlers and allow
> + * overwriting them with the new handlers.
> + *
> + * If a handler for a (base + n) event is already set, stop
> + * registering this extension for the event codes.
there's some whitespace issues here...
> + *
> + * event_codes are subtracted by 64 since we don't need to worry
> + * about core.
> + */
> +
> + if (idx && ext_handlers[idx - 1] == ext_handlers[idx]) {
> + for (i = idx; i < idx + nevents; i++)
> + if (ext_handlers[idx - 1] == ext_handlers[i])
> + ext_handlers[i] = 0;
> + }
Shouldn't this loop actually look like:
for (i = idx; i < 64; i++)
if (ext_handlers[idx - 1] == ext_handlers[i])
ext_handlers[i] = 0;
else
break;
Otherwise if extension1 registers events base to base+10, then
extension2 comes and registers events base+5 to base+7, there'll still
be some wrong values for base+8 to base+10, and extension3 will leave
them alone.
>
> - for (i = 0, j = dpyinfo->codes->first_event; i < nevents; i++, j++) {
> + for (i = 0, j = dpyinfo->codes->first_event; i < nevents; i++, j++, idx++) {
> + if (ext_handlers[idx]) /* don't smash the following extension */
> + break;
> XESetWireToEvent (dpy, j, hooks->wire_to_event);
> XESetEventToWire (dpy, j, hooks->event_to_wire);
> + ext_handlers[idx] = dpyinfo->codes->first_event & 0x3f;
> }
>
> /* register extension for XGE */
Cheers,
Julien
More information about the xorg
mailing list