Reviewed-by: Chris Bagwell <[email protected]> Hmmm, guess xf86-input-wacom would need similar logic to handle same non-wacom tablets.
But then again with this series of changes xf86-input-evdev may be better choice for 1 tool tablets. Chris On Sun, Oct 10, 2010 at 6:33 PM, Peter Hutterer <[email protected]> wrote: > Some tablets send axis values, then EV_SYN, and in the next event the > BTN_TOOL_PEN/BTN_TOUCH, etc. For these tablets, the cursor doesn't move as > coordinates while not in proximity are ignored. > > Buffer coordinates received while out-of-proximity and if we get a proximity > event without other coordinates, re-use the last ones received. > > X.Org Bug 29645 <http://bugs.freedesktop.org/show_bug.cgi?id=29645> > > Signed-off-by: Peter Hutterer <[email protected]> > --- > src/evdev.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > src/evdev.h | 1 + > 2 files changed, 57 insertions(+), 0 deletions(-) > > diff --git a/src/evdev.c b/src/evdev.c > index 634c174..0ef7170 100644 > --- a/src/evdev.c > +++ b/src/evdev.c > @@ -481,6 +481,60 @@ EvdevProcessProximityEvent(InputInfoPtr pInfo, struct > input_event *ev) > } > > /** > + * Proximity handling is rather weird because of tablet-specific issues. > + * Some tablets, notably Wacoms, send a 0/0 coordinate in the same EV_SYN as > + * the out-of-proximity notify. We need to ignore those, hence we only > + * actually post valuator events when we're in proximity. > + * > + * Other tablets send the x/y coordinates, then EV_SYN, then the proximity > + * event. For those, we need to remember x/y to post it when the proximity > + * comes. > + * > + * If we're not in proximity and we get valuator events, remember that, they > + * won't be posted though. If we move into proximity without valuators, use > + * the last ones we got and let the rest of the code post them. > + */ > +static int > +EvdevProcessProximityState(InputInfoPtr pInfo) > +{ > + EvdevPtr pEvdev = pInfo->private; > + int prox_state = 0; > + int i; > + > + /* no proximity change in the queue */ > + if (!pEvdev->prox) > + { > + if (pEvdev->abs && !pEvdev->proximity) > + pEvdev->abs_prox = pEvdev->abs; > + return 0; > + } > + > + for (i = 0; pEvdev->prox && i < pEvdev->num_queue; i++) > + { > + if (pEvdev->queue[i].type == EV_QUEUE_PROXIMITY) > + { > + prox_state = pEvdev->queue[i].val; > + break; > + } > + } > + > + if ((prox_state && !pEvdev->proximity) || > + (!prox_state && pEvdev->proximity)) > + { > + /* We're about to go into/out of proximity but have no abs events > + * within the EV_SYN. Use the last coordinates we have. */ > + if (!pEvdev->abs && pEvdev->abs_prox) > + { > + pEvdev->abs = pEvdev->abs_prox; > + pEvdev->abs_prox = 0; > + } > + } > + > + pEvdev->proximity = prox_state; > + return 1; > +} > + > +/** > * Take a button input event and process it accordingly. > */ > static void > @@ -732,6 +786,8 @@ EvdevProcessSyncEvent(InputInfoPtr pInfo, struct > input_event *ev) > int v[MAX_VALUATORS] = {}; > EvdevPtr pEvdev = pInfo->private; > > + EvdevProcessProximityState(pInfo); > + > EvdevProcessValuators(pInfo, v, &num_v, &first_v); > > EvdevPostProximityEvents(pInfo, TRUE, num_v, first_v, v); > diff --git a/src/evdev.h b/src/evdev.h > index 08f3c13..af93d41 100644 > --- a/src/evdev.h > +++ b/src/evdev.h > @@ -133,6 +133,7 @@ typedef struct { > > int delta[REL_CNT]; > unsigned int abs, rel, prox; > + unsigned int abs_prox; /* valuators posted while out of prox? */ > > /* XKB stuff has to be per-device rather than per-driver */ > #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 5 > -- > 1.7.2.3 > > _______________________________________________ > [email protected]: X.Org development > Archives: http://lists.x.org/archives/xorg-devel > Info: http://lists.x.org/mailman/listinfo/xorg-devel > _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
