diff options
author | Chase Douglas <chase.douglas@canonical.com> | 2011-02-13 16:22:26 -0500 |
---|---|---|
committer | Chase Douglas <chase.douglas@canonical.com> | 2011-02-13 22:57:53 -0500 |
commit | 347a7149a682f337f87f46853d1b1104ce3d1bb7 (patch) | |
tree | d515bc2bcdce48351e8e20669f378914e3b1fd18 | |
parent | 8d71400633abb6de7570991b90034cfcf95f120d (diff) |
a
-rw-r--r-- | Xi/exevents.c | 373 | ||||
-rw-r--r-- | Xi/xiallowev.c | 18 | ||||
-rw-r--r-- | dix/devices.c | 2 | ||||
-rw-r--r-- | dix/events.c | 4 | ||||
-rw-r--r-- | dix/grabs.c | 4 | ||||
-rw-r--r-- | dix/inpututils.c | 12 | ||||
-rw-r--r-- | include/exevents.h | 3 | ||||
-rw-r--r-- | include/inputstr.h | 13 |
8 files changed, 250 insertions, 179 deletions
diff --git a/Xi/exevents.c b/Xi/exevents.c index a9ba99f8e..5b425168e 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -961,15 +961,17 @@ AddTouchClient(TouchPointInfoPtr ti, int client_id, WindowPtr window, TouchClientPtr client; ti->active_clients++; - if (ti->active_clients >= ti->num_clients) + if (ti->active_clients > ti->num_clients) { + int num_clients = ti->num_clients ? ti->num_clients * 2 : 2; + TouchClientPtr tmp; - tmp = realloc(ti->clients, - ti->num_clients * 2 * sizeof(TouchClientRec)); + tmp = realloc(ti->clients, num_clients * sizeof(TouchClientRec)); + if (tmp) { ti->clients = tmp; - ti->num_clients *= 2; + ti->num_clients = num_clients; } else { LogMessage(X_ERROR, "failed to reallocate touch clients\n"); return TRUE; @@ -984,7 +986,7 @@ AddTouchClient(TouchPointInfoPtr ti, int client_id, WindowPtr window, client->source = sourcedev; client->grab = grab; - return (type == POINTER_GRAB_ASYNC); + return FALSE; } /** @@ -1003,7 +1005,7 @@ EnsureTouchClients(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, int i; if (ev->any.type != ET_TouchBegin) - return (ti->num_clients > 0) + return (ti->num_clients > 0); if (t->mode == XIDirectTouch) { @@ -1037,6 +1039,7 @@ EnsureTouchClients(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, if (!tmp) { ti->active_clients = 0; + ti->owner = -1; return FALSE; } ti->clients = tmp; @@ -1046,7 +1049,7 @@ EnsureTouchClients(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, ti->active_clients * sizeof(TouchClientRec)); } else if (sourcedev->spriteInfo->sprite) - srcprite = sourcedev->spriteInfo->sprite; + srcsprite = sourcedev->spriteInfo->sprite; else return FALSE; @@ -1058,6 +1061,7 @@ EnsureTouchClients(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, { sprite->spriteTraceGood = 0; ti->active_clients = 0; + ti->owner = -1; return FALSE; } sprite->spriteTrace = trace; @@ -1077,10 +1081,7 @@ EnsureTouchClients(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, for (i = 0; i < sprite->spriteTraceGood; i++) { WindowPtr win = sprite->spriteTrace[i]; - DeviceIntPtr deliverdev = sourcedev; GrabPtr grab; - TouchClientPtr client; - TouchClientType type; InternalEvent ev; if (win == grab_window) @@ -1092,7 +1093,7 @@ EnsureTouchClients(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, continue; ev.any.type = ET_TouchBegin; - if ((grab = CheckPassiveGrabsOnWindow(win, sourcedev, ev, FALSE, + if ((grab = CheckPassiveGrabsOnWindow(win, sourcedev, &ev, FALSE, FALSE))) { if (AddTouchClient(ti, CLIENT_ID(grab->resource), win, TOUCH_GRAB, @@ -1101,7 +1102,7 @@ EnsureTouchClients(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, continue; } if (masterdev && - (grab = CheckPassiveGrabsOnWindow(win, masterdev, ev, FALSE, + (grab = CheckPassiveGrabsOnWindow(win, masterdev, &ev, FALSE, FALSE))) { if (AddTouchClient(ti, CLIENT_ID(grab->resource), win, TOUCH_GRAB, @@ -1109,34 +1110,6 @@ EnsureTouchClients(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, goto done; continue; } - - ev.any.type = ET_ButtonPress; - ev.device_event.detail.button = 1; - if ((grab = CheckPassiveGrabsOnWindow(win, sourcedev, ev, FALSE, - FALSE))) - { - if (grab->pointerMode == GrabModeSync) - type = POINTER_GRAB_SYNC; - else - type = POINTER_GRAB_ASYNC; - if (AddTouchClient(ti, CLIENT_ID(grab->resource), win, type, - sourcedev, sourcedev, grab)) - goto done; - continue; - } - if (masterdev && - (grab = CheckPassiveGrabsOnWindow(win, masterdev, ev, FALSE, - FALSE))) - { - if (grab->pointerMode == GrabModeSync) - type = POINTER_GRAB_SYNC; - else - type = POINTER_GRAB_ASYNC; - if (AddTouchClient(ti, CLIENT_ID(grab->resource), win, type, - masterdev, sourcedev, grab)) - goto done; - continue; - } } for (i = sprite->spriteTraceGood - 1; i >= 0; i--) @@ -1169,7 +1142,7 @@ EnsureTouchClients(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, { if (AddTouchClient(ti, CLIENT_ID(inputClients->resource), win, TOUCH_SELECT_UNOWNED, sourcedev, - sourcedev, grab)) + sourcedev, NULL)) goto done; select_seen = TRUE; continue; @@ -1182,7 +1155,7 @@ EnsureTouchClients(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, { if (AddTouchClient(ti, CLIENT_ID(inputClients->resource), win, TOUCH_SELECT_UNOWNED, masterdev, - sourcedev, grab)) + sourcedev, NULL)) goto done; select_seen = TRUE; continue; @@ -1211,7 +1184,7 @@ EnsureTouchClients(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XI_TouchMotion)) { AddTouchClient(ti, CLIENT_ID(inputClients->resource), win, - TOUCH_SELECT, sourcedev, sourcedev, grab); + TOUCH_SELECT, sourcedev, sourcedev, NULL); goto done; } else if (masterdev && @@ -1221,39 +1194,18 @@ EnsureTouchClients(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XI_TouchMotion))) { AddTouchClient(ti, CLIENT_ID(inputClients->resource), win, - TOUCH_SELECT, masterdev, sourcedev, grab); + TOUCH_SELECT, masterdev, sourcedev, NULL); goto done; } } } - - for (j = 0; j < 3; j++) - { - static const enum EventType events[] = {ET_ButtonPress, - ET_ButtonRelease, - ET_Motion}; - InternalEvent ev; - - ev.any.type = events[j]; - if (EventIsDeliverable(sourcedev, &ev, win)) - { - AddTouchClient(ti, 0, win, POINTER_SELECT, sourcedev, - sourcedev, grab); - goto done; - } - else if (masterdev && EventIsDeliverable(masterdev, &ev, win)) - { - AddTouchClient(ti, 0, win, POINTER_SELECT, masterdev, - sourcedev, grab); - goto done; - } - } } done: return (ti->active_clients > 0); } +#if 0 /** * @returns TRUE if the specified grab or selection is currently listening to * events from ti's touch sequence. @@ -1281,6 +1233,7 @@ TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource) { return (ti->listeners[0] == resource); } +#endif /** * Attempts to deliver a touch event to the given client. @@ -1314,10 +1267,9 @@ DeliverOneTouchEvent(TouchClientPtr client, TouchPointInfoPtr ti, return TRUE; } -int +static int DeliverTouchOwnershipEvent(TouchClientPtr client, TouchPointInfoPtr ti) { - TouchClassPtr t = pDev->touch; TouchOwnershipEvent event; memset(&event, 0, sizeof(TouchOwnershipEvent)); @@ -1334,6 +1286,7 @@ DeliverTouchOwnershipEvent(TouchClientPtr client, TouchPointInfoPtr ti) return 1; } +#if 0 static DeviceIntPtr CheckXI2Masks(OtherInputMasks *inputMasks, DeviceIntPtr sourcedev, uint16_t evtype) @@ -1348,6 +1301,7 @@ CheckXI2Masks(OtherInputMasks *inputMasks, DeviceIntPtr sourcedev, return NULL; } +#endif /* Add the given event to the history for the touch point. */ static void @@ -1378,6 +1332,7 @@ UpdateTouchHistory(TouchPointInfoPtr ti, InternalEvent *ev) } } +#if 0 /* Handle TouchBegin events for non-grabbing clients */ static int DeliverTouchBeginSelection(TouchPointInfoPtr ti, DeviceIntPtr sourcedev, @@ -1528,6 +1483,7 @@ DeliverTouchSelection(TouchPointInfoPtr ti, DeviceIntPtr sourcedev, return ret; } +#endif static EventList * GetEvents(void) @@ -1542,14 +1498,6 @@ GetEvents(void) return events; } -/* Emit pointer emulation events for the given touch event. Touch begin and - * end cause motion then primary button down or up. */ -static void -TouchPointerEmulation(enum EventType evtype, DeviceIntPtr dev, - ValuatorMask *mask) -{ -} - /* Helper function to set up touch pointer emulation. */ static void SetTouchEmulationMask(InternalEvent *ev, ValuatorMask *mask, int x_axis, @@ -1566,19 +1514,24 @@ SetTouchEmulationMask(InternalEvent *ev, ValuatorMask *mask, int x_axis, /* Process touch emulation. */ static void -EmulateTouchEvents(TouchClientPtr client, TouchPointInfoPtr ti, - InternalEvent *ev) +EmulateTouchEvents(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev) { - DeviceIntPtr dev = client->source; EventList *emulationEvents = GetEvents(); ValuatorMask mask; + enum EventType evtype = ev->any.type; int nevents = 0; int x_axis = dev->touch->x_axis; int y_axis = dev->touch->y_axis; + int i; /* Set the emulation touch for the device. Only one touch may be emulated * at a time. */ + if (dev->touch->emulate && dev->touch->emulate != ti) + return; + dev->touch->emulate = ti; + if (dev->u.master && !dev->u.master->emulate_dev) + dev->u.master->emulate_dev = dev; /* Emulate a normal event. */ SetTouchEmulationMask(ev, &mask, x_axis, y_axis); @@ -1586,32 +1539,54 @@ EmulateTouchEvents(TouchClientPtr client, TouchPointInfoPtr ti, if (evtype == ET_TouchBegin) { nevents = GetPointerEvents(emulationEvents, dev, - MotionNotify, 0, POINTER_ABSOLUTE, mask); + MotionNotify, 0, POINTER_ABSOLUTE, &mask); nevents += GetPointerEvents(emulationEvents + nevents, dev, - ButtonPress, 1, POINTER_ABSOLUTE, mask); + ButtonPress, 1, POINTER_ABSOLUTE, &mask); } else if (evtype == ET_TouchMotion) nevents = GetPointerEvents(emulationEvents, dev, MotionNotify, 0, - POINTER_ABSOLUTE, mask); + POINTER_ABSOLUTE, &mask); else if (evtype == ET_TouchEnd) { nevents = GetPointerEvents(emulationEvents, dev, MotionNotify, 0, - POINTER_ABSOLUTE, mask); + POINTER_ABSOLUTE, &mask); nevents += GetPointerEvents(emulationEvents + nevents, dev, - ButtonRelease, 1, POINTER_ABSOLUTE, mask); + ButtonRelease, 1, POINTER_ABSOLUTE, &mask); } for (i = 0; i < nevents; i++) { InternalEvent *event = (InternalEvent *)((emulationEvents + i)->event); + InternalEvent mevent; + DeviceIntPtr master; event->device_event.flags |= XITouchPointer; - dev->public.processInputProc( - (InternalEvent*)((emulationEvents + i)->event), dev); + master = CopyGetMasterEvent(dev, event, &mevent); + if (master) + master->u.lastSlave = dev; + + /*if (dev->deviceGrab.grab && + (BitIsOn(dev->deviceGrab.grab->xi2mask[0], XI_TouchBegin) || + BitIsOn(dev->deviceGrab.grab->xi2mask[dev->id], XI_TouchBegin))) + dev->public.enqueueInputProc(event, dev); + else*/ + dev->public.processInputProc(event, dev); + + if (master) + { + /*if (master->deviceGrab.grab && + (BitIsOn(master->deviceGrab.grab->xi2mask[1], XI_TouchBegin) || + BitIsOn(master->deviceGrab.grab->xi2mask[master->id], + XI_TouchBegin))) + master->public.enqueueInputProc(&mevent, master); + else*/ + master->public.processInputProc(&mevent, master); + } } } +#if 0 /** * Delivers a touch event to all interested clients. For TouchBegin events, * will update ti->listeners, ti->num_listeners, and ti->num_grabs. @@ -1741,7 +1716,9 @@ DeliverTouchEvents(TouchClientPtr client, InternalEvent *ev, DeviceIntPtr dev) sourcedev->touch->mode == XIDirectTouch)) EmulateTouchEvents(sourcedev, ti, ev); } +#endif +#if 0 /** * Processes a TouchOwnership event, indicating a grab has accepted the touch * it currently owns, or a grab or selection has been removed. Will generate @@ -1851,14 +1828,15 @@ ProcessTouchOwnershipEvent(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, } } } +#endif -void -RemoveTouchPointerEvents() +static void +RemoveTouchPointerEvents(void) { QdEventPtr qe; QdEventPtr prev_qe = NULL; - for (qe = syncEvents.pending; qe; qe->next) + for (qe = syncEvents.pending; qe; qe = qe->next) { InternalEvent *ev = qe->event; @@ -1876,11 +1854,11 @@ RemoveTouchPointerEvents() else prev_qe = qe; } - syncEvents.pendtail = prev_qe; + *syncEvents.pendtail = prev_qe; } -Bool -FindNextGrab(DevIntPtr dev, TouchPointInfoPtr ti, WindowPtr start_win) +static Bool +FindNextGrab(DeviceIntPtr dev, TouchPointInfoPtr ti, WindowPtr start_win) { Bool seen_win = FALSE; DeviceIntPtr master = dev->u.master; @@ -1891,15 +1869,15 @@ FindNextGrab(DevIntPtr dev, TouchPointInfoPtr ti, WindowPtr start_win) if (dev->deviceGrab.grab) return TRUE; - p_event->any.type == ET_ButtonPress; - t_event->any.type == ET_TouchBegin; + p_event.any.type = ET_ButtonPress; + t_event.any.type = ET_TouchBegin; - j = ti->owner; + j = ti->owner >= 0 ? ti->owner : 0; for (i = 0; i < ti->sprite.spriteTraceGood; i++) { WindowPtr win = ti->sprite.spriteTrace[i]; - TouchClientPtr client = ti->clients[j]; + TouchClientPtr client = &ti->clients[j]; if (win == start_win) seen_win = TRUE; @@ -1929,13 +1907,40 @@ next: return FALSE; } +static void +init_event(DeviceIntPtr dev, DeviceEvent* event, Time ms) +{ + memset(event, 0, sizeof(DeviceEvent)); + event->header = ET_Internal; + event->length = sizeof(DeviceEvent); + event->time = ms; + event->deviceid = dev->id; + event->sourceid = dev->id; +} + void -ProcessTouchOwnership(DevIntPtr dev, TouchPointInfoPtr ti, uint8_t reason) +ProcessTouchOwnership(DeviceIntPtr dev, TouchPointInfoPtr ti, uint8_t reason) { Bool touch_grab = TRUE; + DeviceIntPtr sourcedev; + DeviceIntPtr masterdev; + + if (IsMaster(dev)) + { + masterdev = dev; + sourcedev = dev->emulate_dev; + } + else + { + masterdev = dev->u.master; + sourcedev = dev; + } if (!ti) { - ti = dev->emulate_touch; + if (!sourcedev) + return; + + ti = sourcedev->touch->emulate; touch_grab = FALSE; } @@ -1947,16 +1952,17 @@ ProcessTouchOwnership(DevIntPtr dev, TouchPointInfoPtr ti, uint8_t reason) if (!touch_grab) { ti->active_clients = 0; + ti->owner = -1; return; } - init_event(client->device, &event, GetTimeInMillis()); + init_event(dev, &event, GetTimeInMillis()); event.type = ET_TouchEnd; - event.detail = ti->client_id; + event.detail.touch = ti->client_id; for (i = ti->owner + 1; i < ti->active_clients; i++) { - TouchClientPtr client = ti->clients[i]; + TouchClientPtr client = &ti->clients[i]; if (client->type == TOUCH_GRAB || client->type == TOUCH_SELECT_UNOWNED) @@ -1964,35 +1970,50 @@ ProcessTouchOwnership(DevIntPtr dev, TouchPointInfoPtr ti, uint8_t reason) event.deviceid = client->device->id; event.sourceid = client->source->id; - DeliverOneTouchEvent(client, ti, (InternalEvent *)&ev); + DeliverOneTouchEvent(client, ti, (InternalEvent *)&event); } } + ti->active_clients = ti->owner + 1; + ti->clients[ti->owner].type = TOUCH_SELECT; RemoveTouchPointerEvents(); } else { - TouchClientPtr client = &ti->clients[ti->owner]; + TouchClientPtr client; if (touch_grab) { - DeviceIntPtr master = client->source->u.master; DeviceEvent event; + client = &ti->clients[ti->owner]; + init_event(client->device, &event, GetTimeInMillis()); event.type = ET_TouchEnd; - event.detail = ti->client_id; + event.detail.touch = ti->client_id; event.deviceid = client->device->id; event.sourceid = client->source->id; - DeliverOneTouchEvent(client, ti, (InternalEvent *)&ev); + DeliverOneTouchEvent(client, ti, (InternalEvent *)&event); ti->owner++; - dev->deviceGrab.DeactivateGrab(dev, FALSE); + if (sourcedev->deviceGrab.grab && + GrabMatchesSecond(sourcedev->deviceGrab.grab, client->grab, + FALSE)) + sourcedev->deviceGrab.DeactivateGrab(sourcedev); + else if (masterdev && masterdev->deviceGrab.grab && + GrabMatchesSecond(masterdev->deviceGrab.grab, + client->grab, FALSE)) + masterdev->deviceGrab.DeactivateGrab(masterdev); } + else if (ti->owner < 0) + ti->owner = 0; if (ti->owner >= ti->active_clients) + { ti->active_clients = 0; + ti->owner = -1; + } else { if (FindNextGrab(client->device, ti, client->window)) return; @@ -2005,9 +2026,31 @@ ProcessTouchOwnership(DevIntPtr dev, TouchPointInfoPtr ti, uint8_t reason) RemoveTouchPointerEvents(); } else if (client->type == TOUCH_SELECT) + { + InternalEvent *ev; + Bool ret; + + /* Deliver the saved touch begin event. */ + ret = DeliverOneTouchEvent(client, ti, ti->begin_event); + + /* Deliver all the touch motion events in the ring buffer. */ + ev = ti->first_history; + while (ret && ev != ti->next_history) + { + ret = DeliverOneTouchEvent(client, ti, ev); + + if (ev->any.type == ET_TouchEnd) + EndTouchPoint(sourcedev, ti); + + ev++; + if (ev == ti->history + ti->history_size) + ev = ti->history; + } + RemoveTouchPointerEvents(); + } else - ti->active_clients = 0; + EndTouchPoint(sourcedev, ti); } } } @@ -2023,19 +2066,17 @@ ProcessTouchOwnership(DevIntPtr dev, TouchPointInfoPtr ti, uint8_t reason) static void ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr sourcedev) { - DeviceIntPtr masterdev = NULL; + DeviceIntPtr masterdev = sourcedev->u.master; TouchClassPtr t = sourcedev->touch; TouchPointInfoPtr ti; - SpritePtr sprite; + TouchClientPtr client; uint32_t touchid; - Bool emulated = FALSE; + int i; /* We handle deliveries to MDs through the SD, rather than copying * the event and processing it twice. */ if (IsMaster(sourcedev)) return; - if (sourcedev->u.master) - masterdev = sourcedev->u.master; if (!t) return; @@ -2049,8 +2090,6 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr sourcedev) tmp = realloc(t->touches, (t->num_touches * 2) * sizeof(*t->touches)); if (tmp) { - int i; - t->touches = tmp; memset(t->touches + t->num_touches, 0, t->num_touches * sizeof(*t->touches)); @@ -2088,60 +2127,74 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr sourcedev) if (!EnsureTouchClients(sourcedev, ti, ev)) { EmulateTouchEvents(sourcedev, ti, ev); + + if (ev->any.type == ET_TouchEnd) + EndTouchPoint(sourcedev, ti); + return; } + UpdateTouchHistory(ti, ev); + if (ev->any.type == ET_TouchBegin) - FindNextGrab(sourcedev, ti, ev->device_event.root); + FindNextGrab(sourcedev, ti, ti->sprite.spriteTrace[0]); + + if (sourcedev->deviceGrab.grab || (masterdev && masterdev->deviceGrab.grab)) + EmulateTouchEvents(sourcedev, ti, ev); - client = &ti->clients[ti->owner]; + if (ti->owner >= 0) + client = &ti->clients[ti->owner]; - if (client->type == TOUCH_GRAB) + if (ti->owner >= 0 && + ((sourcedev->deviceGrab.grab && + GrabMatchesSecond(sourcedev->deviceGrab.grab, client->grab, FALSE)) || + (masterdev && masterdev->deviceGrab.grab && + GrabMatchesSecond(masterdev->deviceGrab.grab, client->grab, FALSE)) || + (!sourcedev->deviceGrab.grab && !masterdev->deviceGrab.grab))) { - if (ev->any.type == ET_TouchEnd) + client = &ti->clients[ti->owner]; + + if (client->type == TOUCH_GRAB) { - ev->any.type = ET_TouchMotion; - ev->device_event.flags |= XITouchPendingFinish; - } + if (ev->any.type == ET_TouchEnd) + { + ev->any.type = ET_TouchMotion; + ev->device_event.flags |= XITouchPendingFinish; + } - ev->device_event.deviceid = client->device; - ev->device_event.deviceid = client->source; + ev->device_event.deviceid = client->device->id; + ev->device_event.sourceid = client->source->id; - DeliverOneTouchEvent(client, ti, (InternalEvent *)ev); - if (ev->any.type == ET_TouchBegin && !client->device->deviceGrab.grab) - DeliverTouchOwnershipEvent(client, ti); - } - else if (client->type == TOUCH_SELECT || - client->type == TOUCH_SELECT_UNOWNED || - client->type == POINTER_SELECT) - { - for (i = ti->owner; i < ti->active_clients; i++) + DeliverOneTouchEvent(client, ti, ev); + if (ev->any.type == ET_TouchBegin && !client->device->deviceGrab.grab) + DeliverTouchOwnershipEvent(client, ti); + } + else if (client->type == TOUCH_SELECT || + client->type == TOUCH_SELECT_UNOWNED) { - client = &ti->clients[ti->owner]; + for (i = ti->owner; i < ti->active_clients; i++) + { + client = &ti->clients[ti->owner]; - ev->device_event.deviceid = client->device; - ev->device_event.deviceid = client->source; + ev->device_event.deviceid = client->device->id; + ev->device_event.sourceid = client->source->id; - if (client->type == TOUCH_SELECT) - DeliverOneTouchEvent(client, ti, (InternalEvent *)ev); - else if (client->type == TOUCH_SELECT_UNOWNED) - { - DeliverOneTouchEvent(client, ti, (InternalEvent *)ev); - if (ev->any.type == ET_TouchBegin) - DeliverTouchOwnershipEvent(client, ti); + if (client->type == TOUCH_SELECT) + DeliverOneTouchEvent(client, ti, ev); + else if (client->type == TOUCH_SELECT_UNOWNED) + { + DeliverOneTouchEvent(client, ti, ev); + if (ev->any.type == ET_TouchBegin) + DeliverTouchOwnershipEvent(client, ti); + } + + return; } - else - EmulateTouchEvents(sourcedev, ti, InternalEvent *ev); - return; + if (ev->any.type == ET_TouchEnd) + EndTouchPoint(sourcedev, ti); } } - else if (client->type == POINTER_GRAB_SYNC || - client->type == POINTER_GRAB_ASYNC) - { - EmulateTouchEvents(sourcedev, ti, InternalEvent *ev); - emulated = TRUE; - } if (ev->any.type == ET_TouchMotion) ev->any.type = ET_TouchMotionUnowned; @@ -2156,18 +2209,12 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr sourcedev) { TouchClientPtr client = &ti->clients[i]; - ev->device_event.deviceid = client->device; - ev->device_event.deviceid = client->source; + ev->device_event.deviceid = client->device->id; + ev->device_event.sourceid = client->source->id; if (client->type == TOUCH_GRAB || client->type == TOUCH_SELECT_UNOWNED) - DeliverOneTouchEvent(client, ti, (InternalEvent *)ev); - else if (!emulated && (client->type == POINTER_GRAB_SYNC || - client->type == POINTER_GRAB_ASYNC)) - { - EmulateTouchEvents(sourcedev, ti, InternalEvent *ev); - emulated = TRUE; - } + DeliverOneTouchEvent(client, ti, ev); } } @@ -2876,10 +2923,12 @@ GrabTouch(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr mod_dev, rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); if (rc != Success) return rc; - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGrabAccess); + rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixFreezeAccess); if (rc != Success) return rc; + param->other_devices_mode = GrabModeSync; + grab = CreateGrab(client->index, dev, mod_dev, pWin, GRABTYPE_XI2, mask, param, XI_TouchBegin, 0, NullWindow, NullCursor); if (!grab) diff --git a/Xi/xiallowev.c b/Xi/xiallowev.c index eb2dfd761..495d8bbf9 100644 --- a/Xi/xiallowev.c +++ b/Xi/xiallowev.c @@ -42,6 +42,8 @@ #include "exglobals.h" /* BadDevice */ #include "xiallowev.h" +#include "exevents.h" +#include "dixgrabs.h" int SProcXIAllowEvents(ClientPtr client) @@ -121,11 +123,12 @@ int ProcXIAllowTouchEvents(ClientPtr client) { DeviceIntPtr dev; + DeviceIntPtr masterdev; TouchPointInfoPtr ti; - int ret, nev, i; + TouchClientPtr tc; + int ret; uint8_t reason; EventList *events = InitEventList(GetMaximumEventsNum()); - InternalEvent *ev; REQUEST(xXIAllowTouchEventsReq); REQUEST_SIZE_MATCH(xXIAllowTouchEventsReq); @@ -149,7 +152,16 @@ ProcXIAllowTouchEvents(ClientPtr client) return BadValue; } - if (ti->num_listeners == 0 || CLIENT_ID(ti->listeners[0]) != client->index) + tc = &ti->clients[ti->owner]; + masterdev = dev->u.master; + + if (client != tc->client || !tc->grab) + return BadAccess; + + if ((!dev->deviceGrab.grab || + !GrabMatchesSecond(dev->deviceGrab.grab, tc->grab, FALSE)) && + (!masterdev || !masterdev->deviceGrab.grab || + !GrabMatchesSecond(masterdev->deviceGrab.grab, tc->grab, FALSE))) return BadAccess; if (stuff->mode & XITouchOwnerAccept) diff --git a/dix/devices.c b/dix/devices.c index b5cc47f65..a1aedd079 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -762,7 +762,7 @@ FreeDeviceClass(int type, pointer *class) for (i = 0; i < (*t)->num_touches; i++) { free((*t)->touches[i].sprite.spriteTrace); - free((*t)->touches[i].listeners); + //free((*t)->touches[i].listeners); } free((*t)); diff --git a/dix/events.c b/dix/events.c index d64b615d7..bfbc4ac75 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1515,7 +1515,7 @@ DeactivatePointerGrab(DeviceIntPtr mouse) if (!wasImplicit && grab->grabtype == GRABTYPE_XI2) ReattachToOldMaster(mouse); - for (qe = syncEvents.pending; qe; qe = qe->next) + /*for (qe = syncEvents.pending; qe; qe = qe->next) { if ((qe->event->any.type == ET_ButtonPress || qe->event->any.type == ET_ButtonRelease || @@ -1532,7 +1532,7 @@ DeactivatePointerGrab(DeviceIntPtr mouse) ProcessTouchOwnership(mouse, NULL, XITouchOwnerReject); if (mouse->deviceGrab.grab) return; - } + }*/ ComputeFreezes(); } diff --git a/dix/grabs.c b/dix/grabs.c index 437642eac..721ff443b 100644 --- a/dix/grabs.c +++ b/dix/grabs.c @@ -141,7 +141,7 @@ TouchListenerGone(XID resource) if (!ti->active) continue; - for (j = 0; j < ti->num_listeners; j++) + /*for (j = 0; j < ti->num_listeners; j++) { if (ti->listeners[j] != resource) continue; @@ -155,7 +155,7 @@ TouchListenerGone(XID resource) } break; - } + }*/ } } } diff --git a/dix/inpututils.c b/dix/inpututils.c index 9552d33c4..c659dd2a0 100644 --- a/dix/inpututils.c +++ b/dix/inpututils.c @@ -636,6 +636,7 @@ BeginTouchPoint(DeviceIntPtr dev, uint32_t ddx_id) ti->active = TRUE; ti->ddx_id = ddx_id; ti->client_id = t->next_client_id; + ti->owner = -1; t->active_touches++; next_touch_id: t->next_client_id++; @@ -667,19 +668,24 @@ EndTouchPoint(DeviceIntPtr dev, TouchPointInfoPtr ti) ti->active = FALSE; ti->pending_finish = FALSE; ti->sprite.spriteTraceGood = 0; - free(ti->listeners); + /*free(ti->listeners); ti->listeners = NULL; ti->num_listeners = 0; - ti->num_grabs = 0; + ti->num_grabs = 0; */ ti->client_id = 0; ti->ddx_id = 0; ti->first_history = ti->history; ti->next_history = ti->history; - ti->select_win = NULL; + //ti->select_win = NULL; + ti->active_clients = 0; t->active_touches--; if (dev->touch->emulate == ti) + { dev->touch->emulate = NULL; + if (dev->u.master) + dev->u.master->emulate_dev = NULL; + } for (i = 0; i < ti->num_valuators; i++) ti->valuators[i] = 0; diff --git a/include/exevents.h b/include/exevents.h index 32a3962a7..ad441e2a0 100644 --- a/include/exevents.h +++ b/include/exevents.h @@ -329,4 +329,7 @@ XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client, extern int XICheckInvalidMaskBits(ClientPtr client, unsigned char *mask, int len); +extern void +ProcessTouchOwnership(DeviceIntPtr dev, TouchPointInfoPtr ti, uint8_t reason); + #endif /* EXEVENTS_H */ diff --git a/include/inputstr.h b/include/inputstr.h index e3c9fd7bd..b5e36e828 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -292,10 +292,7 @@ typedef struct _ValuatorClassRec { typedef enum { TOUCH_GRAB, TOUCH_SELECT, - TOUCH_SELECT_UNOWNED, - POINTER_GRAB_SYNC, - POINTER_GRAB_ASYNC, - POINTER_SELECT + TOUCH_SELECT_UNOWNED } TouchClientType; typedef struct _TouchClientRec { @@ -313,11 +310,14 @@ typedef struct _TouchPointInfo { * but still owned by a grab */ uint32_t client_id; /* touch ID as seen in client events */ uint32_t ddx_id; /* touch ID given by the DDX */ + SpriteRec sprite; /* window trace for delivery */ TouchClientPtr clients; int num_clients; int active_clients; + int owner; int *valuators; /* last recorded axis values */ int num_valuators; /* == TouchClassInfo::num_axes */ +#if 0 XID *listeners; /* grabs/event selection IDs receiving * events for this touch */ int num_listeners; @@ -325,6 +325,7 @@ typedef struct _TouchPointInfo { * which have not accepted or rejected */ WindowPtr select_win; Bool select_unowned; +#endif Bool emulate_pointer; InternalEvent *begin_event; /* Touch begin event for history */ InternalEvent *history; /* Touch motion and end history events */ @@ -533,8 +534,7 @@ typedef struct _GrabInfoRec { TimeStamp /*time*/, Bool /*autoGrab*/); void (*DeactivateGrab)( - DeviceIntPtr /*device*/, - Bool /* computeFreezes */); + DeviceIntPtr /*device*/); struct { Bool frozen; int state; @@ -606,6 +606,7 @@ typedef struct _DeviceIntRec { DeviceIntPtr master; /* master device */ DeviceIntPtr lastSlave; /* last slave device used */ } u; + DeviceIntPtr emulate_dev; /* last valuator values recorded, not posted to client; * for slave devices, valuators is in device coordinates |