XQuartz tablet mouse events are at the wrong location and other Xinput headaches

Peter Hutterer peter.hutterer at who-t.net
Wed Mar 14 17:06:32 PDT 2012


On Tue, Mar 13, 2012 at 02:23:46AM -0700, Jeremy Huddleston wrote:
> Hey Peter,
> 
> I'm having an Xi week here in XQuartz.  I just received a bug report (http://xquartz.macosforge.org/trac/ticket/555) that tablet support has regressed in XQuartz in 1.12.0 from 1.11.4.  The DDX code in both versions is practically the same, so I think this might be a regression somewhere in DIX.  Does this sound related to anything you've heard about?
> 
> $ git diff origin/server-1.11-branch origin/server-1.12-branch hw/xquartz | diffstat
>  GL/indirect.c            |    3 
>  applewm.c                |    8 -
>  bundle/Info.plist.cpp    |    4 
>  mach-startup/Makefile.am |    7 +
>  pseudoramiX.c            |   65 ++++------
>  xpr/appledri.c           |   94 ++++++--------
>  xpr/appledristr.h        |  298 ++++++++++++++++++++++++-----------------------
>  xpr/dri.c                |    3 
>  8 files changed, 239 insertions(+), 243 deletions(-)
> 
> ---
> 
> In investigating http://bugs.winehq.org/show_bug.cgi?id=29844, I took a look at how our devices are initialized, and I am confused by Absolute vs Relative mode for a valuator axis and Absolute vs Relative axis label.  I know we discussed it in person back when this was made 2-3 years ago, but I've forgotten, and I need something in writing to job my memory. Our mouse pointer does:
> 
> axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
> ...
> InitValuatorAxisStruct(pPointer, 0, axes_labels[0], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Absolute);
> 
> whereas the tablet does:
> 
> axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
> ...
> InitValuatorAxisStruct(pPointer, 0, axes_labels[0], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
> 
> My understanding is that the mode (Absolute vs Relative) has to do with the data being presented as the current device state rather than the change in state from the previous input, but in looking at other code out there, it looks like AXIS_LABEL_PROP_ABS_X and AXIS_LABEL_PROP_REL_X are supposed to make that distinction.

rel/abs mode in X is a bit of a desaster, some of it caused by me. the main
thing: axes may be absolute but the actual mode of the axis can be relative.
e.g. touchpads have absolute axes but are used as relative devices, so we
allow the axes to go over the boundaries.

the labels themselves have no effect, they are purely for client-side
convenience ("what is this axis? pressure? distance? bananas?")
the mode field in XI1.x and XI2 represents how this axis is to be used.
a touchpad should have a relative mode field on x/y, despite the axis being
technically absolute.

the rules for relative vs absolute:
- relative axes (e.g. mouse) have no range and only submit relative
  events
- absolute axes (e.g. tablet or touchpad) must have a range and submit
  absolute events which are clipped to the range and/or submit relative
  events. Only absolute events are clipped.

events as submitted to the DIX must be either in absolute device coordinates
(e.g. 100/150) or in relative coordinates from the current position (-2/4).
The 10% case you mention below doesn't exist so ignore that.

> "Absolute" and "Relative" are overloaded here, so that's making it difficult for me to reason through.  Absolute could mean the absolute value given (100 pixels) whereas relative could mean the relative positioning along a range (10% of the way from the left edge to the right edge).  Alternatively, it could mean the absolute value of the current state (100 pixels), or the relative change from the previous state (-2 pixels).
> 
> Can you please untangle the knots in my brain (doc/Xinput.xml is dated here, btw)?  Is it just the case that the pointer is incorrect and we should be doing:
> 
> axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
> ...
> InitValuatorAxisStruct(pPointer, 0, axes_labels[0], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Absolute);
> 
> If so, can we overload that to also include relative change for the wine case:
> axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
> axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
> ...
> InitValuatorAxisStruct(pPointer, 0, axes_labels[0], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Absolute);

these should be invalid, absolute axes without axis limits will clip to 0. I
think so anyway, if not, they should :)

> InitValuatorAxisStruct(pPointer, 2, axes_labels[2], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
> ---
> 
> And lastly, 'xinput list pointer' seems to be running into issues getting the atoms for the button labels here.  Are you seeing this?  I can't imagine that this is XQuartz-specific:
> 
> $ xinput list pointer
> pointer                                 	id=7	[slave  pointer  (2)]
> 	Reporting 3 classes:
> 		Class originated from: 7. Type: XIButtonClass
> 		Buttons supported: 7
> X Error of failed request:  BadAtom (invalid Atom parameter)
>   Major opcode of failed request:  17 (X_GetAtomName)
>   Atom id in failed request:  0xb0002
>   Serial number of failed request:  23
>   Current serial number in output stream:  23
> 		Button labels: "Button Middle" "Button Right" "Button Wheel Up" "Button Wheel Down" "Button Horiz Wheel Left" "Button Horiz Wheel Right"
> 
> Breaking on _XError in gdb:
> Breakpoint 1, 0x000000010003636f in _XError ()(gdb) bt
> #0  0x000000010003636f in _XError ()
> #1  0x0000000100034300 in handle_error ()
> #2  0x0000000100033e06 in _XReply ()
> #3  0x000000010001ba5c in XGetAtomName ()
> #4  0x0000000100001ba4 in print_classes_xi2 (display=0x100803200, classes=0x100204720, num_classes=3) at list.c:161
> #5  0x000000010000252f in print_info_xi2 (display=0x100803200, dev=0x1002043e8, format=FORMAT_LONG) at list.c:284
> #6  0x00000001000022c7 in list (display=0x100803200, argc=1, argv=0x7fff5fbff9d8, name=0x10000b556 "list", desc=0x10000b77b "[--short || --long || --name-only || --id-only] [<device name>...]") at list.c:380
> #7  0x000000010000711d in main (argc=3, argv=0x7fff5fbff9c8) at xinput.c:386
> (gdb) frame 4
> #4  0x0000000100001ba4 in print_classes_xi2 (display=0x100803200, classes=0x100204720, num_classes=3) at list.c:161
> 161	                        name = (b->labels[j]) ? XGetAtomName(display, b->labels[j]) : NULL;
> (gdb) list
> 156	                    printf("XIButtonClass\n");
> 157	                    printf("\t\tButtons supported: %d\n", b->num_buttons);
> 158	                    printf("\t\tButton labels:");
> 159	                    for (j = 0; j < b->num_buttons; j++)
> 160	                    {
> 161	                        name = (b->labels[j]) ? XGetAtomName(display, b->labels[j]) : NULL;
> 162	                        if (name)
> 163	                            printf(" \"%s\"", name);
> 164	                        else
> 165	                            printf(" None");
> (gdb) print b->labels[0]
> $17 = 117
> (gdb) print b->labels[1]
> $18 = 118
> (gdb) print b->labels[2]
> $19 = 119
> (gdb) print b->labels[3]
> $20 = 120
> (gdb) print b->labels[4]
> $21 = 121
> (gdb) print b->labels[5]
> $22 = 122
> (gdb) print b->labels[6]
> $23 = 720898

yeah, looks like the labels are off by one. 

> (gdb) print b->num_buttons
> $24 = 7
> (gdb) print b->labels[-1]
> $25 = 498216206336
> 
> Based on xlsatoms, I'd expect 116-122 as the button atoms:
> 116	Button Left
> 117	Button Middle
> 118	Button Right
> 119	Button Wheel Up
> 120	Button Wheel Down
> 121	Button Horiz Wheel Left
> 122	Button Horiz Wheel Right
> 
> It works when the client is i386/Linux or i386/darwin and fails when x86_64/darwin, ppc/Linux, or ppc64/Linux ... is this possibly an inputproto issue?

libXi or xinput, I suspect. curious though, since it works fine here in
x86_64. Can you bisect libXi from 1.5.99.2 to 1.6.0, I wonder if we
introduced a bug here with the alignments.

2d638fc37b0dbf28e5c826f74f68ada83a8c3e2b is another possible candidate to
revert and test.

put a breakpoint in libXi's copy_classes on the XIButtonClass case and see
what comes down the wire and where the offset is introduced. if it's already
wrong on the wire, then the server has a bug here.

Cheers,
  Peter
 
> $ arch -i386 /opt/X11/bin/xinput list pointer
> pointer                                 	id=7	[slave  pointer  (2)]
> 	Reporting 3 classes:
> 		Class originated from: 7. Type: XIButtonClass
> 		Buttons supported: 7
> 		Button labels: "Button Left" "Button Middle" "Button Right" "Button Wheel Up" "Button Wheel Down" "Button Horiz Wheel Left" "Button Horiz Wheel Right"
> 		Button state:
> 		Class originated from: 7. Type: XIValuatorClass
> 		Detail for Valuator 0:
> 		  Label: Rel X
> 		  Range: -1.000000 - -1.000000
> 		  Resolution: 0 units/m
> 		  Mode: absolute
> 		  Current value: 665.000000
> 		Class originated from: 7. Type: XIValuatorClass
> 		Detail for Valuator 1:
> 		  Label: Rel Y
> 		  Range: -1.000000 - -1.000000
> 		  Resolution: 0 units/m
> 		  Mode: absolute
> 		  Current value: 12.000000
> 
> 
> $ arch -x86_64 /opt/X11/bin/xinput list pointer
> pointer                                 	id=7	[slave  pointer  (2)]
> 	Reporting 3 classes:
> 		Class originated from: 7. Type: XIButtonClass
> 		Buttons supported: 7
> X Error of failed request:  BadAtom (invalid Atom parameter)
>   Major opcode of failed request:  17 (X_GetAtomName)
>   Atom id in failed request:  0xb0002
>   Serial number of failed request:  23
>   Current serial number in output stream:  23
> 		Button labels: "Button Middle" "Button Right" "Button Wheel Up" "Button Wheel Down" "Button Horiz Wheel Left" "Button Horiz Wheel Right"
> 


More information about the xorg-devel mailing list