On 12/14/2011 07:02 PM, Peter Hutterer wrote: > Includes a hack for implicit grab activation, because integrating this > requires a larger rewrite and I'm not sleeping enough as it is. > Right now, we deliver the event and check before/after if there is an > implicit grab on. If one activated, then store the event in the grab and > switch the listener type to a grab listener. > > Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> > --- > Xi/exevents.c | 172 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- > 1 files changed, 171 insertions(+), 1 deletions(-) > > diff --git a/Xi/exevents.c b/Xi/exevents.c > index d199493..ee8c828 100644 > --- a/Xi/exevents.c > +++ b/Xi/exevents.c > @@ -1188,6 +1188,148 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, > TouchPointInfoPtr ti, > return TRUE; > } > > +static int > +DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, > InternalEvent *ev, > + TouchListener *listener, ClientPtr client, > + WindowPtr win, GrabPtr grab, XI2Mask *xi2mask) > +{ > + InternalEvent motion, button; > + InternalEvent *ptrev = &motion; > + int nevents; > + DeviceIntPtr kbd; > + > + /* We don't deliver pointer events to non-owners */ > + if (!TouchResourceIsOwner(ti, listener->listener)) > + return Success; > + > + nevents = TouchConvertToPointerEvent(ev, &motion, &button); > + BUG_WARN(nevents == 0); > + if (nevents == 0) > + return BadValue; > + > + if (nevents > 1) > + ptrev = &button; > + > + kbd = GetMaster(dev, KEYBOARD_OR_FLOAT); > + event_set_state(dev, kbd, &ptrev->device_event); > + ptrev->device_event.corestate = event_get_corestate(dev, kbd); > + > + if (grab) > + { > + /* this side-steps the usual activation mechansims, but... */ > + if (ev->any.type == ET_TouchBegin) > + ActivatePassiveGrab(dev, grab, ptrev, ev); /* also delivers the > event */ > + else { > + int deliveries = 0; > + /* 'grab' is the passive grab, but if the grab isn't active, > + * don't deliver */ > + if (!dev->deviceGrab.grab) > + return Success; > + > + if (grab->ownerEvents) > + { > + WindowPtr focus = NullWindow; > + WindowPtr win = dev->spriteInfo->sprite->win; > + deliveries = DeliverDeviceEvents(win, ptrev, grab, focus, > dev); > + } > + > + if (!deliveries) > + DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype); > + > + if (ev->any.type == ET_TouchEnd && > + !dev->button->buttonsDown && > + dev->deviceGrab.fromPassiveGrab && > + GrabIsPointerGrab(grab)) > + (*dev->deviceGrab.DeactivateGrab)(dev); > + } > + } else > + { > + GrabPtr devgrab = dev->deviceGrab.grab; > + > + DeliverDeviceEvents(win, ptrev, grab, win, dev); > + /* FIXME: bad hack > + * Implicit passive grab activated in response to this event. Store > + * the event. > + */ > + if (!devgrab && dev->deviceGrab.grab && dev->deviceGrab.implicitGrab) > + { > + TouchListener *listener; > + > + devgrab = dev->deviceGrab.grab; > + > + *dev->deviceGrab.sync.event = ev->device_event;
It took me a bit to realize that an implicit grab means the listener must be a pointer selection, which would be the last listener because all the preceding listeners represent grabs. Maybe a comment would be in order, like: The listener array has a sequence of grabs and then one event selection. Implicit grab activation occurs through delivering an event selection. Thus, we update the last listener in the array. > + listener = &ti->listeners[ti->num_listeners - 1]; > + listener->listener = devgrab->resource; Otherwise, Reviewed-by: Chase Douglas <chase.doug...@canonical.com> _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel