diff options
author | Chase Douglas <chase.douglas@canonical.com> | 2011-11-18 09:42:58 -0800 |
---|---|---|
committer | Chase Douglas <chase.douglas@canonical.com> | 2011-11-28 17:33:42 -0800 |
commit | 209f8d27a896eaee0d44ed351ae612a5a3a77e14 (patch) | |
tree | d155a95d2953a1dc4e5743e47bc86defe977f353 | |
parent | 0746298aa19cb661a8687711eb951c8a0aaa1465 (diff) |
Update passive grab check routines for pointer emulation
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
-rw-r--r-- | dix/events.c | 178 |
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; |