summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChase Douglas <chase.douglas@canonical.com>2011-11-18 09:42:58 -0800
committerChase Douglas <chase.douglas@canonical.com>2011-11-28 17:33:42 -0800
commit209f8d27a896eaee0d44ed351ae612a5a3a77e14 (patch)
treed155a95d2953a1dc4e5743e47bc86defe977f353
parent0746298aa19cb661a8687711eb951c8a0aaa1465 (diff)
Update passive grab check routines for pointer emulation
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
-rw-r--r--dix/events.c178
1 files changed, 155 insertions, 23 deletions
diff --git a/dix/events.c b/dix/events.c
index 67c2184e5..3d36077c5 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3783,13 +3783,18 @@ ActivatePassiveGrab(DeviceIntPtr device, GrabPtr grab, InternalEvent *event)
SpritePtr pSprite = device->spriteInfo->sprite;
GrabInfoPtr grabinfo = &device->deviceGrab;
xEvent *xE = NULL;
+ xEvent *motion = NULL;
+ xEvent *button = NULL;
+ Bool emulate_pointer = FALSE;
int count;
+ int motion_count;
+ int button_count;
int rc;
- if (!GetXIType(event) && !GetCoreType(event))
+ if (!GetXIType(event) && !GetCoreType(event) && !IsTouchEvent(event))
{
ErrorF("Event type %d in CheckPassiveGrabsOnWindow is neither"
- " XI 1.x nor core\n", event->any.type);
+ " XI 1.x, core, nor touch\n", event->any.type);
return FALSE;
}
@@ -3811,36 +3816,112 @@ ActivatePassiveGrab(DeviceIntPtr device, GrabPtr grab, InternalEvent *event)
gdev->key->xkbInfo->state.grab_mods & (~0x1f00);
}
+ if (IsTouchEvent(event) &&
+ (grab->grabtype != GRABTYPE_XI2 || grab->type != XI_TouchBegin))
+ emulate_pointer = TRUE;
+
if (grab->grabtype == GRABTYPE_CORE)
{
- rc = EventToCore(event, &xE, &count);
- if (rc != Success)
+ if (emulate_pointer)
{
- if (rc != BadMatch)
- ErrorF("[dix] %s: core conversion failed in CPGFW "
- "(%d, %d).\n", device->name, event->any.type, rc);
- return FALSE;
+ rc = TouchToMotion(device, event, CORE, &motion, &motion_count);
+ if (rc != Success)
+ {
+ if (rc != BadMatch)
+ ErrorF("[dix] %s: core pointer emulation conversion failed "
+ "in CPGFW (%d, %d).\n", device->name,
+ event->any.type, rc);
+ return FALSE;
+ }
+
+ rc = TouchToButton(device, event, CORE, &button, &button_count);
+ if (rc != Success)
+ {
+ if (rc != BadMatch)
+ ErrorF("[dix] %s: core pointer emulation conversion failed "
+ "in CPGFW (%d, %d).\n", device->name,
+ event->any.type, rc);
+ free(motion);
+ return FALSE;
+ }
+ } else {
+ rc = EventToCore(event, &xE, &count);
+ if (rc != Success)
+ {
+ if (rc != BadMatch)
+ ErrorF("[dix] %s: core conversion failed in CPGFW "
+ "(%d, %d).\n", device->name, event->any.type, rc);
+ return FALSE;
+ }
}
} else if (grab->grabtype == GRABTYPE_XI2)
{
- rc = EventToXI2(event, &xE);
- if (rc != Success)
+ if (emulate_pointer)
{
- if (rc != BadMatch)
- ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
- "(%d, %d).\n", device->name, event->any.type, rc);
- return FALSE;
+ rc = TouchToMotion(device, event, XI2, &motion, &motion_count);
+ if (rc != Success)
+ {
+ if (rc != BadMatch)
+ ErrorF("[dix] %s: XI2 pointer emulation conversion failed "
+ "in CPGFW (%d, %d).\n", device->name,
+ event->any.type, rc);
+ return FALSE;
+ }
+
+ rc = TouchToButton(device, event, XI2, &button, &button_count);
+ if (rc != Success)
+ {
+ if (rc != BadMatch)
+ ErrorF("[dix] %s: XI2 pointer emulation conversion failed "
+ "in CPGFW (%d, %d).\n", device->name,
+ event->any.type, rc);
+ free(motion);
+ return FALSE;
+ }
+ } else {
+ rc = EventToXI2(event, &xE);
+ if (rc != Success)
+ {
+ if (rc != BadMatch)
+ ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
+ "(%d, %d).\n", device->name, event->any.type, rc);
+ return FALSE;
+ }
+ count = 1;
}
- count = 1;
} else
{
- rc = EventToXI(event, &xE, &count);
- if (rc != Success)
+ if (emulate_pointer)
{
- if (rc != BadMatch)
- ErrorF("[dix] %s: XI conversion failed in CPGFW "
- "(%d, %d).\n", device->name, event->any.type, rc);
- return FALSE;
+ rc = TouchToMotion(device, event, XI, &motion, &motion_count);
+ if (rc != Success)
+ {
+ if (rc != BadMatch)
+ ErrorF("[dix] %s: XI pointer emulation conversion failed "
+ "in CPGFW (%d, %d).\n", device->name,
+ event->any.type, rc);
+ return FALSE;
+ }
+
+ rc = TouchToButton(device, event, XI, &button, &button_count);
+ if (rc != Success)
+ {
+ if (rc != BadMatch)
+ ErrorF("[dix] %s: XI pointer emulation conversion failed "
+ "in CPGFW (%d, %d).\n", device->name,
+ event->any.type, rc);
+ free(motion);
+ return FALSE;
+ }
+ } else {
+ rc = EventToXI(event, &xE, &count);
+ if (rc != Success)
+ {
+ if (rc != BadMatch)
+ ErrorF("[dix] %s: XI conversion failed in CPGFW "
+ "(%d, %d).\n", device->name, event->any.type, rc);
+ return FALSE;
+ }
}
}
@@ -3854,6 +3935,25 @@ ActivatePassiveGrab(DeviceIntPtr device, GrabPtr grab, InternalEvent *event)
TryClientEvents(rClient(grab), device, xE, count,
GetEventFilter(device, xE),
GetEventFilter(device, xE), grab);
+ } else {
+ if (motion)
+ {
+ FixUpEventFromWindow(pSprite, motion, grab->window, None, TRUE);
+
+ /* XXX: XACE? */
+ TryClientEvents(rClient(grab), device, motion, motion_count,
+ GetEventFilter(device, motion),
+ GetEventFilter(device, motion), grab);
+ }
+ if (button)
+ {
+ FixUpEventFromWindow(pSprite, button, grab->window, None, TRUE);
+
+ /* XXX: XACE? */
+ TryClientEvents(rClient(grab), device, button, button_count,
+ GetEventFilter(device, button),
+ GetEventFilter(device, button), grab);
+ }
}
if (grabinfo->sync.state == FROZEN_NO_EVENT)
@@ -4025,6 +4125,11 @@ CheckPassiveGrabsOnWindow(
case ET_ButtonRelease:
tempGrab->detail.exact = event->device_event.detail.button;
break;
+ case ET_TouchBegin:
+ case ET_TouchEnd:
+ /* Emulated pointer events use button 1 */
+ tempGrab->detail.exact = 1;
+ break;
default:
tempGrab->detail.exact = 0;
break;
@@ -4046,6 +4151,28 @@ CheckPassiveGrabsOnWindow(
break;
}
+ if (!grab && IsTouchEvent(event) &&
+ (event->device_event.flags & TOUCH_POINTER_EMULATED))
+ {
+ InternalEvent pointer_event;
+
+ memcpy(&pointer_event, event, sizeof(pointer_event));
+ pointer_event.any.type = GetPointerEmulatedInternalType(event);
+ pointer_event.device_event.detail.button = 1;
+
+ for (grab = wPassiveGrabs(pWin); grab; grab = grab->next)
+ {
+ if (!CheckPassiveGrab(device, grab, &pointer_event, checkCore,
+ tempGrab))
+ continue;
+
+ if (activate && !ActivatePassiveGrab(device, grab, event))
+ continue;
+
+ break;
+ }
+ }
+
FreeGrab(tempGrab);
return grab;
}
@@ -4071,7 +4198,7 @@ CheckPassiveGrabsOnWindow(
* the core event and then check for grabs.
*
* @param device The device that caused the event.
- * @param xE The event to handle (Device{Button|Key}Press).
+ * @param xE The event to handle (Device{Button|Key}Press or TouchBegin).
* @param count Number of events in list.
* @return TRUE if a grab has been activated or false otherwise.
*/
@@ -4086,13 +4213,18 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor)
Bool ret = FALSE;
if (event->type != ET_ButtonPress &&
- event->type != ET_KeyPress)
+ event->type != ET_KeyPress &&
+ event->type != ET_TouchBegin)
return FALSE;
if (event->type == ET_ButtonPress
&& (device->button->buttonsDown != 1))
return FALSE;
+ if (event->type == ET_TouchBegin &&
+ !(event->flags & TOUCH_POINTER_EMULATED))
+ return FALSE;
+
if (device->deviceGrab.grab)
return FALSE;