dix: Enable XI2 delivery for events and focused events.
No support for grabbed events yet.
This commit is contained in:
parent
87ff1159b4
commit
808a158182
123
dix/events.c
123
dix/events.c
|
@ -409,16 +409,24 @@ static Mask filters[MAXDEVICES][128] = {
|
||||||
* For the given event, return the matching event filter. This filter may then
|
* For the given event, return the matching event filter. This filter may then
|
||||||
* be AND'ed with the selected event mask.
|
* be AND'ed with the selected event mask.
|
||||||
*
|
*
|
||||||
|
* For XI2 events, the returned filter is simply the byte containing the event
|
||||||
|
* mask we're interested in. E.g. for a mask of (1 << 13), this would be
|
||||||
|
* byte[1].
|
||||||
|
*
|
||||||
* @param[in] dev The device the event belongs to, may be NULL.
|
* @param[in] dev The device the event belongs to, may be NULL.
|
||||||
* @param[in] event The event to get the filter for. Only the type of the
|
* @param[in] event The event to get the filter for. Only the type of the
|
||||||
* event matters, or the extension + evtype for GenericEvents.
|
* event matters, or the extension + evtype for GenericEvents.
|
||||||
* @return The filter mask for the given event.
|
* @return The filter mask for the given event.
|
||||||
|
*
|
||||||
|
* @see GetEventMask
|
||||||
*/
|
*/
|
||||||
static Mask
|
static Mask
|
||||||
GetEventFilter(DeviceIntPtr dev, xEvent *event)
|
GetEventFilter(DeviceIntPtr dev, xEvent *event)
|
||||||
{
|
{
|
||||||
if (event->u.u.type != GenericEvent)
|
if (event->u.u.type != GenericEvent)
|
||||||
return filters[dev ? dev->id : 0][event->u.u.type];
|
return filters[dev ? dev->id : 0][event->u.u.type];
|
||||||
|
else if (XI2_EVENT(event))
|
||||||
|
return (1 << (((xXIDeviceEvent*)event)->evtype % 8));
|
||||||
ErrorF("[dix] Unknown device type %d. No filter\n", event->u.u.type);
|
ErrorF("[dix] Unknown device type %d. No filter\n", event->u.u.type);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -444,6 +452,21 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
|
||||||
(inputMasks->xi2mask[AllMasterDevices][evtype/8] && dev->isMaster));
|
(inputMasks->xi2mask[AllMasterDevices][evtype/8] && dev->isMaster));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Mask
|
||||||
|
GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other)
|
||||||
|
{
|
||||||
|
/* XI2 filters are only ever 8 bit, so let's return a 8 bit mask */
|
||||||
|
if (XI2_EVENT(event))
|
||||||
|
{
|
||||||
|
int byte = ((xGenericEvent*)event)->evtype / 8;
|
||||||
|
return other->xi2mask[dev->id][byte];
|
||||||
|
} else if (CORE_EVENT(event))
|
||||||
|
return other->mask[AllDevices];
|
||||||
|
else
|
||||||
|
return other->mask[dev->id];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static CARD8 criticalEvents[32] =
|
static CARD8 criticalEvents[32] =
|
||||||
{
|
{
|
||||||
0x7c, 0x30, 0x40 /* key, button, expose, and configure events */
|
0x7c, 0x30, 0x40 /* key, button, expose, and configure events */
|
||||||
|
@ -1969,7 +1992,16 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
|
||||||
{
|
{
|
||||||
if (CORE_EVENT(pEvents))
|
if (CORE_EVENT(pEvents))
|
||||||
other = (InputClients *)wOtherClients(pWin);
|
other = (InputClients *)wOtherClients(pWin);
|
||||||
else {
|
else if (XI2_EVENT(pEvents))
|
||||||
|
{
|
||||||
|
OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
|
||||||
|
int evtype = ((xGenericEvent*)pEvents)->evtype;
|
||||||
|
/* Has any client selected for the event? */
|
||||||
|
if (!inputMasks ||
|
||||||
|
!(inputMasks->xi2mask[mskidx][evtype/8] & filter))
|
||||||
|
return 0;
|
||||||
|
other = inputMasks->inputClients;
|
||||||
|
} else {
|
||||||
OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
|
OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
|
||||||
/* Has any client selected for the event? */
|
/* Has any client selected for the event? */
|
||||||
if (!inputMasks ||
|
if (!inputMasks ||
|
||||||
|
@ -1981,22 +2013,24 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
|
||||||
|
|
||||||
for (; other; other = other->next)
|
for (; other; other = other->next)
|
||||||
{
|
{
|
||||||
|
Mask mask;
|
||||||
if (IsInterferingGrab(rClient(other), pDev, pEvents))
|
if (IsInterferingGrab(rClient(other), pDev, pEvents))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
mask = GetEventMask(pDev, pEvents, other);
|
||||||
|
|
||||||
if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin,
|
if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin,
|
||||||
pEvents, count))
|
pEvents, count))
|
||||||
/* do nothing */;
|
/* do nothing */;
|
||||||
else if ( (attempt = TryClientEvents(rClient(other), pDev,
|
else if ( (attempt = TryClientEvents(rClient(other), pDev,
|
||||||
pEvents, count,
|
pEvents, count,
|
||||||
other->mask[mskidx],
|
mask, filter, grab)) )
|
||||||
filter, grab)) )
|
|
||||||
{
|
{
|
||||||
if (attempt > 0)
|
if (attempt > 0)
|
||||||
{
|
{
|
||||||
deliveries++;
|
deliveries++;
|
||||||
client = rClient(other);
|
client = rClient(other);
|
||||||
deliveryMask = other->mask[mskidx];
|
deliveryMask = mask;
|
||||||
} else
|
} else
|
||||||
nondeliveries--;
|
nondeliveries--;
|
||||||
}
|
}
|
||||||
|
@ -2225,6 +2259,7 @@ FixUpEventFromWindow(
|
||||||
#define XI_MASK (1 << 0) /**< XI mask set on window */
|
#define XI_MASK (1 << 0) /**< XI mask set on window */
|
||||||
#define CORE_MASK (1 << 1) /**< Core mask set on window */
|
#define CORE_MASK (1 << 1) /**< Core mask set on window */
|
||||||
#define DONT_PROPAGATE_MASK (1 << 2) /**< DontPropagate mask set on window */
|
#define DONT_PROPAGATE_MASK (1 << 2) /**< DontPropagate mask set on window */
|
||||||
|
#define XI2_MASK (1 << 3) /**< XI2 mask set on window */
|
||||||
/* @} */
|
/* @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2236,13 +2271,12 @@ FixUpEventFromWindow(
|
||||||
* @param[in] dev The device this event is being sent for.
|
* @param[in] dev The device this event is being sent for.
|
||||||
* @param[in] event The event that is to be sent.
|
* @param[in] event The event that is to be sent.
|
||||||
* @param[in] win The current event window.
|
* @param[in] win The current event window.
|
||||||
* @param[out] filter_out The event filter for this event.
|
|
||||||
*
|
*
|
||||||
* @return Bitmask of ::XI_MASK, ::CORE_MASK, and ::DONT_PROPAGATE_MASK.
|
* @return Bitmask of ::XI2_MASK, ::XI_MASK, ::CORE_MASK, and
|
||||||
|
* ::DONT_PROPAGATE_MASK.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win,
|
EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win)
|
||||||
Mask *filter_out)
|
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int filter = 0;
|
int filter = 0;
|
||||||
|
@ -2250,12 +2284,22 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win,
|
||||||
OtherInputMasks *inputMasks;
|
OtherInputMasks *inputMasks;
|
||||||
xEvent ev;
|
xEvent ev;
|
||||||
|
|
||||||
|
/* XXX: this makes me gag */
|
||||||
|
type = GetXI2Type(event);
|
||||||
|
ev.u.u.type = GenericEvent; /* GetEventFilter only cares about type and evtype*/
|
||||||
|
((xGenericEvent*)&ev)->extension = IReqCode;
|
||||||
|
((xGenericEvent*)&ev)->evtype = type;
|
||||||
|
filter = GetEventFilter(dev, &ev);
|
||||||
|
if (type && (inputMasks = wOtherInputMasks(win)) &&
|
||||||
|
inputMasks->xi2mask[dev->id][type / 8] & filter)
|
||||||
|
rc |= XI2_MASK;
|
||||||
|
|
||||||
type = GetXIType(event);
|
type = GetXIType(event);
|
||||||
ev.u.u.type = type; /* GetEventFilter only cares about type */
|
ev.u.u.type = type;
|
||||||
filter = GetEventFilter(dev, &ev);
|
filter = GetEventFilter(dev, &ev);
|
||||||
|
|
||||||
/* Check for XI mask */
|
/* Check for XI mask */
|
||||||
if (type && (inputMasks = wOtherInputMasks(win)) &&
|
if (type && inputMasks &&
|
||||||
(inputMasks->deliverableEvents[dev->id] & filter) &&
|
(inputMasks->deliverableEvents[dev->id] & filter) &&
|
||||||
(inputMasks->inputEvents[dev->id] & filter))
|
(inputMasks->inputEvents[dev->id] & filter))
|
||||||
rc |= XI_MASK;
|
rc |= XI_MASK;
|
||||||
|
@ -2275,7 +2319,6 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win,
|
||||||
if (type && (filter & wDontPropagateMask(win)))
|
if (type && (filter & wDontPropagateMask(win)))
|
||||||
rc |= DONT_PROPAGATE_MASK;
|
rc |= DONT_PROPAGATE_MASK;
|
||||||
|
|
||||||
*filter_out = filter;
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2330,11 +2373,31 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
|
||||||
|
|
||||||
while (pWin)
|
while (pWin)
|
||||||
{
|
{
|
||||||
if ((mask = EventIsDeliverable(dev, event, pWin, &filter)))
|
if ((mask = EventIsDeliverable(dev, event, pWin)))
|
||||||
{
|
{
|
||||||
|
if (mask & XI2_MASK)
|
||||||
|
{
|
||||||
|
xEvent *xi2 = NULL;
|
||||||
|
rc = EventToXI2(event, &xi2);
|
||||||
|
if (rc != Success)
|
||||||
|
{
|
||||||
|
ErrorF("[dix] %s: XI2 conversion failed in DDE (%d).\n",
|
||||||
|
dev->name, rc);
|
||||||
|
goto unwind;
|
||||||
|
}
|
||||||
|
filter = GetEventFilter(dev, xi2);
|
||||||
|
FixUpEventFromWindow(dev, xi2, pWin, child, FALSE);
|
||||||
|
deliveries = DeliverEventsToWindow(dev, pWin, xi2, 1,
|
||||||
|
filter, grab, dev->id);
|
||||||
|
xfree(xi2);
|
||||||
|
if (deliveries > 0)
|
||||||
|
goto unwind;
|
||||||
|
}
|
||||||
|
|
||||||
/* XI events first */
|
/* XI events first */
|
||||||
if (mask & XI_MASK)
|
if (mask & XI_MASK)
|
||||||
{
|
{
|
||||||
|
filter = GetEventFilter(dev, xE);
|
||||||
FixUpEventFromWindow(dev, xE, pWin, child, FALSE);
|
FixUpEventFromWindow(dev, xE, pWin, child, FALSE);
|
||||||
deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
|
deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
|
||||||
filter, grab, dev->id);
|
filter, grab, dev->id);
|
||||||
|
@ -2354,6 +2417,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
|
||||||
goto unwind;
|
goto unwind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filter = GetEventFilter(dev, &core);
|
||||||
FixUpEventFromWindow(dev, &core, pWin, child, FALSE);
|
FixUpEventFromWindow(dev, &core, pWin, child, FALSE);
|
||||||
deliveries = DeliverEventsToWindow(dev, pWin, &core, 1,
|
deliveries = DeliverEventsToWindow(dev, pWin, &core, 1,
|
||||||
filter, grab, dev->id);
|
filter, grab, dev->id);
|
||||||
|
@ -3232,6 +3296,7 @@ CheckPassiveGrabsOnWindow(
|
||||||
xkbi= gdev->key->xkbInfo;
|
xkbi= gdev->key->xkbInfo;
|
||||||
tempGrab.modifierDevice = grab->modifierDevice;
|
tempGrab.modifierDevice = grab->modifierDevice;
|
||||||
tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
|
tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
|
||||||
|
/* FIXME: check for xi2 grabs */
|
||||||
|
|
||||||
/* Check for XI grabs first */
|
/* Check for XI grabs first */
|
||||||
tempGrab.type = GetXIType((InternalEvent*)event);
|
tempGrab.type = GetXIType((InternalEvent*)event);
|
||||||
|
@ -3435,7 +3500,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
|
||||||
WindowPtr focus = keybd->focus->win;
|
WindowPtr focus = keybd->focus->win;
|
||||||
BOOL sendCore = (keybd->isMaster && keybd->coreEvents);
|
BOOL sendCore = (keybd->isMaster && keybd->coreEvents);
|
||||||
xEvent core;
|
xEvent core;
|
||||||
xEvent *xE = NULL;
|
xEvent *xE = NULL, *xi2 = NULL;
|
||||||
int count, rc;
|
int count, rc;
|
||||||
int deliveries = 0;
|
int deliveries = 0;
|
||||||
|
|
||||||
|
@ -3455,7 +3520,6 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
|
||||||
}
|
}
|
||||||
ptr = GetPairedDevice(keybd);
|
ptr = GetPairedDevice(keybd);
|
||||||
|
|
||||||
|
|
||||||
rc = EventToXI(event, &xE, &count);
|
rc = EventToXI(event, &xE, &count);
|
||||||
if (rc != Success)
|
if (rc != Success)
|
||||||
{
|
{
|
||||||
|
@ -3468,6 +3532,23 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
|
||||||
if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count))
|
if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count))
|
||||||
goto unwind;
|
goto unwind;
|
||||||
|
|
||||||
|
rc = EventToXI2(event, &xi2);
|
||||||
|
if (rc != Success)
|
||||||
|
{
|
||||||
|
ErrorF("[dix] %s: XI2 conversion failed in DFE (%d, %d). Skipping delivery.\n",
|
||||||
|
keybd->name, event->u.any.type, rc);
|
||||||
|
goto unwind;
|
||||||
|
} else if (xi2)
|
||||||
|
{
|
||||||
|
int filter = GetEventFilter(keybd, xi2);
|
||||||
|
/* just deliver it to the focus window */
|
||||||
|
FixUpEventFromWindow(ptr, xi2, focus, None, FALSE);
|
||||||
|
deliveries = DeliverEventsToWindow(keybd, focus, xi2, 1,
|
||||||
|
filter, NullGrab, keybd->id);
|
||||||
|
if (deliveries > 0)
|
||||||
|
goto unwind;
|
||||||
|
}
|
||||||
|
|
||||||
/* just deliver it to the focus window */
|
/* just deliver it to the focus window */
|
||||||
FixUpEventFromWindow(ptr, xE, focus, None, FALSE);
|
FixUpEventFromWindow(ptr, xE, focus, None, FALSE);
|
||||||
deliveries = DeliverEventsToWindow(keybd, focus, xE, count,
|
deliveries = DeliverEventsToWindow(keybd, focus, xE, count,
|
||||||
|
@ -3496,6 +3577,8 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
|
||||||
unwind:
|
unwind:
|
||||||
if (xE)
|
if (xE)
|
||||||
xfree(xE);
|
xfree(xE);
|
||||||
|
if (xi2)
|
||||||
|
xfree(xi2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3518,6 +3601,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
|
||||||
BOOL sendCore = FALSE;
|
BOOL sendCore = FALSE;
|
||||||
int rc, count = 0;
|
int rc, count = 0;
|
||||||
xEvent *xi = NULL;
|
xEvent *xi = NULL;
|
||||||
|
xEvent *xi2 = NULL;
|
||||||
|
|
||||||
grabinfo = &thisDev->deviceGrab;
|
grabinfo = &thisDev->deviceGrab;
|
||||||
grab = grabinfo->grab;
|
grab = grabinfo->grab;
|
||||||
|
@ -3554,12 +3638,21 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
|
||||||
if (!deliveries)
|
if (!deliveries)
|
||||||
{
|
{
|
||||||
Mask mask;
|
Mask mask;
|
||||||
|
|
||||||
/* XXX: In theory, we could pass the internal events through to
|
/* XXX: In theory, we could pass the internal events through to
|
||||||
* everything and only convert just before hitting the wire. We can't
|
* everything and only convert just before hitting the wire. We can't
|
||||||
* do that yet, so DGE is the last stop for internal events. From here
|
* do that yet, so DGE is the last stop for internal events. From here
|
||||||
* onwards, we deal with core/XI events.
|
* onwards, we deal with core/XI events.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
rc = EventToXI2(event, &xi2);
|
||||||
|
if (rc != Success)
|
||||||
|
{
|
||||||
|
ErrorF("[dix] %s: XI2 conversion failed in DGE (%d, %d). Skipping delivery.\n",
|
||||||
|
thisDev->name, event->u.any.type, rc);
|
||||||
|
goto unwind;
|
||||||
|
}
|
||||||
|
|
||||||
rc = EventToXI(event, &xi, &count);
|
rc = EventToXI(event, &xi, &count);
|
||||||
if (rc != Success)
|
if (rc != Success)
|
||||||
{
|
{
|
||||||
|
@ -3660,6 +3753,8 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
|
||||||
unwind:
|
unwind:
|
||||||
if (xi)
|
if (xi)
|
||||||
xfree(xi);
|
xfree(xi);
|
||||||
|
if (xi2)
|
||||||
|
xfree(xi2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is used to set the key pressed or key released state -
|
/* This function is used to set the key pressed or key released state -
|
||||||
|
|
Loading…
Reference in New Issue