summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2007-12-04 19:07:46 +1030
committerPeter Hutterer <peter@cs.unisa.edu.au>2007-12-04 19:07:46 +1030
commitf44d7dcb5fefca3ddfd45e75d0bd0b47ec785e48 (patch)
tree57767d7355c10676bca087d4da8311e96882d492
parent0931f40bf1bd6e00b8d95968d761a495b2c9a46c (diff)
dix: change the filters to be per-device.
If we have one global filter, one pointer may change the filter value and affect another pointer. Reproduceable effect: blackbox and xterm, start dragging xterm then click anywhere with the other pointer (attached to different masterd device!). The button release resets the filter[Motion_Filter(button)] value, thus stopping dragging and no event is sent to the client anymore. Having the filters set per device gets around this.
-rw-r--r--Xi/exevents.c4
-rw-r--r--Xi/extinit.c12
-rw-r--r--dix/events.c64
-rw-r--r--include/dix.h1
4 files changed, 52 insertions, 29 deletions
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 8c8cdfdd4..f0d288ff4 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -550,7 +550,7 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
return DONT_PROCESS;
if (b->map[key] <= 5)
b->state |= (Button1Mask >> 1) << b->map[key];
- SetMaskForEvent(Motion_Filter(b), DeviceMotionNotify);
+ SetMaskForEvent(device->id, Motion_Filter(b), DeviceMotionNotify);
} else if (xE->u.u.type == DeviceButtonRelease) {
if (!b)
return DONT_PROCESS;
@@ -567,7 +567,7 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
return DONT_PROCESS;
if (b->map[key] <= 5)
b->state &= ~((Button1Mask >> 1) << b->map[key]);
- SetMaskForEvent(Motion_Filter(b), DeviceMotionNotify);
+ SetMaskForEvent(device->id, Motion_Filter(b), DeviceMotionNotify);
} else if (xE->u.u.type == ProximityIn)
device->valuator->mode &= ~OutOfProximity;
else if (xE->u.u.type == ProximityOut)
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 2d077b2aa..cc75d23f4 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -827,13 +827,16 @@ SetExclusiveAccess(Mask mask)
static void
SetMaskForExtEvent(Mask mask, int event)
{
+ int i;
EventInfo[ExtEventIndex].mask = mask;
EventInfo[ExtEventIndex++].type = event;
if ((event < LASTEvent) || (event >= 128))
FatalError("MaskForExtensionEvent: bogus event number");
- SetMaskForEvent(mask, event);
+
+ for (i = 0; i < MAX_DEVICES; i++)
+ SetMaskForEvent(i, mask, event);
}
/************************************************************************
@@ -974,13 +977,16 @@ FixExtensionEvents(ExtensionEntry * extEntry)
static void
RestoreExtensionEvents(void)
{
- int i;
+ int i, j;
IReqCode = 0;
for (i = 0; i < ExtEventIndex - 1; i++) {
if ((EventInfo[i].type >= LASTEvent) && (EventInfo[i].type < 128))
- SetMaskForEvent(0, EventInfo[i].type);
+ {
+ for (j = 0; j < MAX_DEVICES; j++)
+ SetMaskForEvent(j, 0, EventInfo[i].type);
+ }
EventInfo[i].mask = 0;
EventInfo[i].type = 0;
}
diff --git a/dix/events.c b/dix/events.c
index 21b0eeea3..046e4cde5 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -367,8 +367,12 @@ static Mask lastEventMask;
extern int DeviceMotionNotify;
+/**
+ * Event filters. One set of filters for each device, but only the first layer
+ * is initialized. The rest is memcpy'd in InitEvents.
+ */
#define CantBeFiltered NoEventMask
-static Mask filters[128] =
+static Mask filters[MAX_DEVICES][128] = {
{
NoSuchEvent, /* 0 */
NoSuchEvent, /* 1 */
@@ -405,7 +409,7 @@ static Mask filters[128] =
ColormapChangeMask, /* ColormapNotify */
CantBeFiltered, /* ClientMessage */
CantBeFiltered /* MappingNotify */
-};
+}};
/**
@@ -787,17 +791,19 @@ XineramaChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor)
#endif /* PANORAMIX */
void
-SetMaskForEvent(Mask mask, int event)
+SetMaskForEvent(int deviceid, Mask mask, int event)
{
int coretype;
+ if (deviceid < 0 || deviceid > MAX_DEVICES)
+ FatalError("SetMaskForEvent: bogus device id");
if ((event < LASTEvent) || (event >= 128))
FatalError("SetMaskForEvent: bogus event number");
- filters[event] = mask;
+ filters[deviceid][event] = mask;
/* Need to change the mask for the core events too */
coretype = XItoCoreType(event);
if (coretype)
- filters[coretype] = mask;
+ filters[deviceid][coretype] = mask;
}
_X_EXPORT void
@@ -2440,7 +2446,7 @@ DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab,
{
Window child = None;
int type = xE->u.u.type;
- Mask filter = filters[type];
+ Mask filter = filters[dev->id][type];
int deliveries = 0;
if (type & EXTENSION_EVENT_BASE)
@@ -2555,7 +2561,9 @@ DeliverEvents(WindowPtr pWin, xEvent *xE, int count,
if (!count)
return 0;
- filter = filters[xE->u.u.type];
+ /* We don't know a device here. However, this should only ever be called
+ for a non-device event so we are safe to use 0*/
+ filter = filters[0][xE->u.u.type];
if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
xE->u.destroyNotify.event = pWin->drawable.id;
if (filter != StructureAndSubMask)
@@ -3466,8 +3474,8 @@ CheckPassiveGrabsOnWindow(
FixUpEventFromWindow(device, xE, grab->window, None, TRUE);
(void) TryClientEvents(rClient(grab), xE, count,
- filters[xE->u.u.type],
- filters[xE->u.u.type], grab);
+ filters[device->id][xE->u.u.type],
+ filters[device->id][xE->u.u.type], grab);
if (grabinfo->sync.state == FROZEN_NO_EVENT)
{
@@ -3590,7 +3598,8 @@ DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
FixUpEventFromWindow(pointer, xE, focus, None, FALSE);
if (xE->u.u.type & EXTENSION_EVENT_BASE)
mskidx = keybd->id;
- (void)DeliverEventsToWindow(keybd, focus, xE, count, filters[xE->u.u.type],
+ (void)DeliverEventsToWindow(keybd, focus, xE, count,
+ filters[keybd->id][xE->u.u.type],
NullGrab, mskidx);
}
@@ -3671,7 +3680,7 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
IsInterferingGrab(rClient(grab), thisDev, xE)))
{
deliveries = TryClientEvents(rClient(grab), xE, count,
- mask, filters[xE->u.u.type], grab);
+ mask, filters[thisDev->id][xE->u.u.type], grab);
}
}
if (deliveries && (xE->u.u.type == MotionNotify
@@ -3989,7 +3998,7 @@ ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count)
*/
if (xE->u.u.detail == 0)
return;
- filters[MotionNotify] = Motion_Filter(butc);
+ filters[mouse->id][Motion_Filter(butc)] = MotionNotify;
if (!grab)
if (CheckDeviceGrabs(mouse, xE, 0, count))
return;
@@ -3997,7 +4006,7 @@ ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count)
case ButtonRelease:
if (xE->u.u.detail == 0)
return;
- filters[MotionNotify] = Motion_Filter(butc);
+ filters[mouse->id][Motion_Filter(butc)] = MotionNotify;
if (!butc->state && mouse->deviceGrab.fromPassiveGrab)
deactivateGrab = TRUE;
break;
@@ -4350,14 +4359,14 @@ EnterLeaveEvent(
sendevent = TRUE;
}
- if ((mask & filters[type]) && sendevent)
+ if ((mask & filters[mouse->id][type]) && sendevent)
{
if (grab)
(void)TryClientEvents(rClient(grab), &event, 1, mask,
- filters[type], grab);
+ filters[mouse->id][type], grab);
else
- (void)DeliverEventsToWindow(mouse, pWin, &event, 1, filters[type],
- NullGrab, 0);
+ (void)DeliverEventsToWindow(mouse, pWin, &event, 1,
+ filters[mouse->id][type], NullGrab, 0);
}
/* we don't have enough bytes, so we squash flags and mode into
@@ -4372,15 +4381,17 @@ EnterLeaveEvent(
mskidx = mouse->id;
inputMasks = wOtherInputMasks(pWin);
if (inputMasks &&
- (filters[devEnterLeave->type] & inputMasks->deliverableEvents[mskidx]))
+ (filters[mouse->id][devEnterLeave->type] &
+ inputMasks->deliverableEvents[mskidx]))
{
if (devgrab)
(void)TryClientEvents(rClient(devgrab), (xEvent*)devEnterLeave, 1,
- mask, filters[devEnterLeave->type], devgrab);
+ mask, filters[mouse->id][devEnterLeave->type],
+ devgrab);
else
(void)DeliverEventsToWindow(mouse, pWin, (xEvent*)devEnterLeave,
- 1, filters[devEnterLeave->type],
- NullGrab, mouse->id);
+ 1, filters[mouse->id][devEnterLeave->type],
+ NullGrab, mouse->id);
}
if ((type == EnterNotify) && (mask & KeymapStateMask))
@@ -4579,8 +4590,8 @@ FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin)
event.u.u.type = type;
event.u.u.detail = detail;
event.u.focus.window = pWin->drawable.id;
- (void)DeliverEventsToWindow(dev, pWin, &event, 1, filters[type], NullGrab,
- 0);
+ (void)DeliverEventsToWindow(dev, pWin, &event, 1,
+ filters[dev->id][type], NullGrab, 0);
if ((type == FocusIn) &&
((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
{
@@ -5528,7 +5539,12 @@ InitEvents(void)
inputInfo.keyboard = (DeviceIntPtr)NULL;
inputInfo.pointer = (DeviceIntPtr)NULL;
lastEventMask = OwnerGrabButtonMask;
- filters[MotionNotify] = PointerMotionMask;
+ filters[0][PointerMotionMask] = MotionNotify;
+ for (i = 1; i < MAX_DEVICES; i++)
+ {
+ memcpy(&filters[i], filters[0], sizeof(filters[0]));
+ }
+
#ifdef XEVIE
xeviewin = NULL;
#endif
diff --git a/include/dix.h b/include/dix.h
index db90579aa..6da3ee86f 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -345,6 +345,7 @@ extern void SetVendorString(char *string);
/* events.c */
extern void SetMaskForEvent(
+ int /* deviceid */,
Mask /* mask */,
int /* event */);