xserver: Branch 'master' - 7 commits
Peter Hutterer
whot at kemper.freedesktop.org
Sun Jun 24 18:32:16 PDT 2007
Xi/exevents.c | 6 +-
dix/devices.c | 76 ++++++++++++++++++++++++++++
dix/events.c | 31 +++++++----
dix/getevents.c | 1
dix/grabs.c | 47 +++++++++++++++++
hw/xfree86/common/xf86Config.c | 108 +++++++++++++++++++++++------------------
hw/xfree86/common/xf86Init.c | 14 ++---
hw/xfree86/common/xf86str.h | 2
8 files changed, 219 insertions(+), 66 deletions(-)
New commits:
diff-tree 4c601b904ee6fb01da3343ff9ef00d36f1341fcb (from bec4e47d128ec40b58a2c9aae475f6a6fc4323c3)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date: Mon Jun 25 10:53:05 2007 +0930
configFiles(): don't return anything when declared as void.
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index aedee47..bf22720 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -752,7 +752,7 @@ configFiles(XF86ConfFilesPtr fileconf)
}
#endif
- return TRUE;
+ return;
}
typedef enum {
diff-tree bec4e47d128ec40b58a2c9aae475f6a6fc4323c3 (from 8e5102b9f01821048e72e7f068193a0b3e1816f9)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date: Mon Jun 25 10:51:42 2007 +0930
NULL-terminate device list when synthesizing core devices.
This fix is required for 93ca526892c0d22afa05cce6496198c652043a19 to work.
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 5ccc451..aedee47 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -1339,7 +1339,7 @@ checkCoreInputDevices(serverLayoutPtr se
*devs[count - 1] = Pointer;
devs[count - 1]->extraOptions =
xf86addNewOption(NULL, xnfstrdup("CorePointer"), NULL);
- devs[count]->identifier = NULL;
+ devs[count] = NULL;
servlayoutp->inputs = devs;
}
}
@@ -1379,7 +1379,7 @@ checkCoreInputDevices(serverLayoutPtr se
*devs[count - 1] = Pointer;
devs[count - 1]->extraOptions =
xf86addNewOption(NULL, xnfstrdup("AlwaysCore"), NULL);
- devs[count]->identifier = NULL;
+ devs[count] = NULL;
servlayoutp->inputs = devs;
}
}
@@ -1475,7 +1475,7 @@ checkCoreInputDevices(serverLayoutPtr se
*devs[count - 1] = Keyboard;
devs[count - 1]->extraOptions =
xf86addNewOption(NULL, xnfstrdup("CoreKeyboard"), NULL);
- devs[count]->identifier = NULL;
+ devs[count] = NULL;
servlayoutp->inputs = devs;
}
}
diff-tree 8e5102b9f01821048e72e7f068193a0b3e1816f9 (from 87564543d92c1ee1f8cb6fb9716a15d693e08cf5)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date: Thu Jun 21 15:47:48 2007 +0930
Set the detail field for DeviceKeyEvents to the keycode.
(cherry picked from commit 0c33dc152e372cdc8ae59d9a5696b0774bcd03b7)
diff --git a/dix/getevents.c b/dix/getevents.c
index 6969f78..8a4f8ed 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -446,6 +446,7 @@ GetKeyboardValuatorEvents(xEvent *events
kbp = (deviceKeyButtonPointer *) events;
kbp->time = ms;
kbp->deviceid = pDev->id;
+ kbp->detail = key_code;
if (type == KeyPress)
kbp->type = DeviceKeyPress;
else if (type == KeyRelease)
diff-tree 87564543d92c1ee1f8cb6fb9716a15d693e08cf5 (from 24ee89fd60f489f2d3af0399e0d667057df74d02)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date: Tue Jun 19 18:20:05 2007 +0930
Only decrement buttonsDown when the button count is greater than 0.
Device drivers flush their buttons on device init and cause a button down
event to be generated. If we unconditionally decrease the buttons, we won't be
able to ever get a passive device grab.
Format documentation for CheckDeviceGrabs to make it readable.
(cherry picked from commit 3e894974cdd6a75683d4601f71622d1da7ec4395)
Conflicts:
Xi/exevents.c
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 9e71a9e..fe297ab 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -248,7 +248,9 @@ ProcessOtherEvent(xEventPtr xE, DeviceIn
SetMaskForEvent(Motion_Filter(b), DeviceMotionNotify);
if (!grab)
if (CheckDeviceGrabs(other, xE, 0, count))
- return;
+ /* if a passive grab was activated, the event has been sent
+ * already */
+ return;
} else if (xE->u.u.type == DeviceButtonRelease) {
if (!b)
@@ -258,7 +260,7 @@ ProcessOtherEvent(xEventPtr xE, DeviceIn
*kptr &= ~bit;
if (other->valuator)
other->valuator->motionHintWindow = NullWindow;
- if (!--b->buttonsDown)
+ if (b->buttonsDown >= 1 && !--b->buttonsDown)
b->motionMask = 0;
xE->u.u.detail = b->map[key];
if (xE->u.u.detail == 0)
diff --git a/dix/events.c b/dix/events.c
index 887cbcd..63bc379 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2629,6 +2629,7 @@ BorderSizeNotEmpty(WindowPtr pWin)
/**
* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
* passive grab set on the window to be activated.
+ * If a passive grab is activated, the event will be delivered to the client.
*
* @param pWin The window that may be subject to a passive grab.
* @param device Device that caused the event.
@@ -2728,16 +2729,26 @@ CheckPassiveGrabsOnWindow(
}
/**
-"CheckDeviceGrabs" handles both keyboard and pointer events that may cause
-a passive grab to be activated. If the event is a keyboard event, the
-ancestors of the focus window are traced down and tried to see if they have
-any passive grabs to be activated. If the focus window itself is reached and
-it's descendants contain they pointer, the ancestors of the window that the
-pointer is in are then traced down starting at the focus window, otherwise no
-grabs are activated. If the event is a pointer event, the ancestors of the
-window that the pointer is in are traced down starting at the root until
-CheckPassiveGrabs causes a passive grab to activate or all the windows are
-tried. PRH
+ * CheckDeviceGrabs handles both keyboard and pointer events that may cause
+ * a passive grab to be activated.
+ *
+ * If the event is a keyboard event, the ancestors of the focus window are
+ * traced down and tried to see if they have any passive grabs to be
+ * activated. If the focus window itself is reached and it's descendants
+ * contain the pointer, the ancestors of the window that the pointer is in
+ * are then traced down starting at the focus window, otherwise no grabs are
+ * activated.
+ * If the event is a pointer event, the ancestors of the window that the
+ * pointer is in are traced down starting at the root until CheckPassiveGrabs
+ * causes a passive grab to activate or all the windows are
+ * tried. PRH
+ *
+ * If a grab is activated, the event has been sent to the client already!
+ *
+ * @param device The device that caused the event.
+ * @param xE The event to handle (most likely {Device}ButtonPress).
+ * @param count Number of events in list.
+ * @return TRUE if a grab has been activated or false otherwise.
*/
Bool
diff-tree 24ee89fd60f489f2d3af0399e0d667057df74d02 (from 93ca526892c0d22afa05cce6496198c652043a19)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date: Tue Jun 19 15:31:56 2007 +0930
Add a few comments to devices.c
diff --git a/dix/devices.c b/dix/devices.c
index 6c69454..57e93bb 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -80,9 +80,20 @@ SOFTWARE.
#include "exglobals.h"
#include "exevents.h"
+/** @file
+ * This file handles input device-related stuff.
+ */
+
int CoreDevicePrivatesIndex = 0;
static int CoreDevicePrivatesGeneration = -1;
+/**
+ * Create a new input device and init it to sane values. The device is added
+ * to the server's off_devices list.
+ *
+ * @param deviceProc Callback for device control function (switch dev on/off).
+ * @return The newly created device.
+ */
DeviceIntPtr
AddInputDevice(DeviceProc deviceProc, Bool autoStart)
{
@@ -153,6 +164,15 @@ AddInputDevice(DeviceProc deviceProc, Bo
return dev;
}
+/**
+ * Switch device ON through the driver and push it onto the global device
+ * list. All clients are notified about the device being enabled.
+ *
+ * A device will send events once enabled.
+ *
+ * @param The device to be enabled.
+ * @return TRUE on success or FALSE otherwise.
+ */
Bool
EnableDevice(DeviceIntPtr dev)
{
@@ -189,6 +209,13 @@ EnableDevice(DeviceIntPtr dev)
return TRUE;
}
+/**
+ * Switch a device off through the driver and push it onto the off_devices
+ * list. A device will not send events while disabled. All clients are
+ * notified about the device being disabled.
+ *
+ * @return TRUE on success or FALSE otherwise.
+ */
Bool
DisableDevice(DeviceIntPtr dev)
{
@@ -219,6 +246,14 @@ DisableDevice(DeviceIntPtr dev)
return TRUE;
}
+/**
+ * Initialise a new device through the driver and tell all clients about the
+ * new device.
+ *
+ * The device will NOT send events until it is enabled!
+ *
+ * @return Success or an error code on failure.
+ */
int
ActivateDevice(DeviceIntPtr dev)
{
@@ -243,6 +278,10 @@ ActivateDevice(DeviceIntPtr dev)
return ret;
}
+/**
+ * Ring the bell.
+ * The actual task of ringing the bell is the job of the DDX.
+ */
static void
CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
{
@@ -257,6 +296,9 @@ CoreKeyboardCtl(DeviceIntPtr pDev, Keybd
return;
}
+/**
+ * Device control function for the Virtual Core Keyboard.
+ */
static int
CoreKeyboardProc(DeviceIntPtr pDev, int what)
{
@@ -317,6 +359,9 @@ CoreKeyboardProc(DeviceIntPtr pDev, int
return Success;
}
+/**
+ * Device control function for the Virtual Core Pointer.
+ */
static int
CorePointerProc(DeviceIntPtr pDev, int what)
{
@@ -347,6 +392,12 @@ CorePointerProc(DeviceIntPtr pDev, int w
return Success;
}
+/**
+ * Initialise the two core devices, VCP and VCK (see events.c).
+ * The devices are activated but not enabled.
+ * Note that the server MUST have two core devices at all times, even if there
+ * is no physical device connected.
+ */
void
InitCoreDevices(void)
{
@@ -406,6 +457,14 @@ InitCoreDevices(void)
}
}
+/**
+ * Activate all switched-off devices and then enable all those devices.
+ *
+ * Will return an error if no core keyboard or core pointer is present.
+ * In theory this should never happen if you call InitCoreDevices() first.
+ *
+ * @return Success or error code on failure.
+ */
int
InitAndStartDevices(void)
{
@@ -441,6 +500,13 @@ InitAndStartDevices(void)
return Success;
}
+/**
+ * Close down a device and free all resources.
+ * Once closed down, the driver will probably not expect you that you'll ever
+ * enable it again and free associated structs. If you want the device to just
+ * be disabled, DisableDevice().
+ * Don't call this function directly, use RemoveDevice() instead.
+ */
static void
CloseDevice(DeviceIntPtr dev)
{
@@ -542,6 +608,10 @@ CloseDevice(DeviceIntPtr dev)
xfree(dev);
}
+/**
+ * Shut down all devices, free all resources, etc.
+ * Only useful if you're shutting down the server!
+ */
void
CloseDownDevices(void)
{
@@ -563,6 +633,12 @@ CloseDownDevices(void)
inputInfo.pointer = NULL;
}
+/**
+ * Remove a device from the device list, closes it and thus frees all
+ * resources.
+ * Removes both enabled and disabled devices and notifies all devices about
+ * the removal of the device.
+ */
int
RemoveDevice(DeviceIntPtr dev)
{
diff-tree 93ca526892c0d22afa05cce6496198c652043a19 (from b141b85c254afff3ce2221d899787fab3dc295bd)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date: Wed Jun 13 15:28:15 2007 +0930
Split up memory for devices configured in the config file.
If we're using a continuous block here, we segfault when a device removal
triggers an xfree call.
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 8e58bef..5ccc451 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -442,7 +442,7 @@ xf86InputDriverlistFromConfig()
{
int count = 0;
char **modulearray;
- IDevPtr idp;
+ IDevPtr* idp;
/*
* make sure the config file has been parsed and that we have a
@@ -460,7 +460,7 @@ xf86InputDriverlistFromConfig()
*/
if (xf86ConfigLayout.inputs) {
idp = xf86ConfigLayout.inputs;
- while (idp->identifier) {
+ while (*idp) {
count++;
idp++;
}
@@ -475,8 +475,8 @@ xf86InputDriverlistFromConfig()
modulearray = xnfalloc((count + 1) * sizeof(char*));
count = 0;
idp = xf86ConfigLayout.inputs;
- while (idp->identifier) {
- modulearray[count] = idp->driver;
+ while (idp && *idp) {
+ modulearray[count] = (*idp)->driver;
count++;
idp++;
}
@@ -1185,7 +1185,8 @@ checkCoreInputDevices(serverLayoutPtr se
IDevPtr corePointer = NULL, coreKeyboard = NULL;
Bool foundPointer = FALSE, foundKeyboard = FALSE;
const char *pointerMsg = NULL, *keyboardMsg = NULL;
- IDevPtr indp, i;
+ IDevPtr *devs, /* iterator */
+ indp;
IDevRec Pointer, Keyboard;
XF86ConfInputPtr confInput;
XF86ConfInputRec defPtr, defKbd;
@@ -1198,7 +1199,8 @@ checkCoreInputDevices(serverLayoutPtr se
* in the active ServerLayout. If more than one is specified for either,
* remove the core attribute from the later ones.
*/
- for (indp = servlayoutp->inputs; indp->identifier; indp++) {
+ for (devs = servlayoutp->inputs; devs && *devs; devs++) {
+ indp = *devs;
pointer opt1 = NULL, opt2 = NULL;
if (indp->commonOptions &&
xf86CheckBoolOption(indp->commonOptions, "CorePointer", FALSE)) {
@@ -1263,11 +1265,15 @@ checkCoreInputDevices(serverLayoutPtr se
* removed.
*/
if (corePointer) {
- for (indp = servlayoutp->inputs; indp->identifier; indp++)
- if (indp == corePointer)
+ for (devs = servlayoutp->inputs; devs && *devs; devs++)
+ if (*devs == corePointer)
+ {
+ xfree(*devs);
+ *devs = (IDevPtr)0x1; /* ensure we dont skip next loop*/
break;
- for (; indp->identifier; indp++)
- indp[0] = indp[1];
+ }
+ for (; devs && *devs; devs++)
+ devs[0] = devs[1];
count--;
}
corePointer = NULL;
@@ -1327,13 +1333,14 @@ checkCoreInputDevices(serverLayoutPtr se
foundPointer = configInput(&Pointer, confInput, from);
if (foundPointer) {
count++;
- indp = xnfrealloc(servlayoutp->inputs,
- (count + 1) * sizeof(IDevRec));
- indp[count - 1] = Pointer;
- indp[count - 1].extraOptions =
+ devs = xnfrealloc(servlayoutp->inputs,
+ (count + 1) * sizeof(IDevPtr));
+ devs[count - 1] = xnfalloc(sizeof(IDevRec));
+ *devs[count - 1] = Pointer;
+ devs[count - 1]->extraOptions =
xf86addNewOption(NULL, xnfstrdup("CorePointer"), NULL);
- indp[count].identifier = NULL;
- servlayoutp->inputs = indp;
+ devs[count]->identifier = NULL;
+ servlayoutp->inputs = devs;
}
}
@@ -1351,9 +1358,9 @@ checkCoreInputDevices(serverLayoutPtr se
* If you're using an evdev keyboard and expect a default mouse
* section ... deal.
*/
- for (i = servlayoutp->inputs; i->identifier && i->driver; i++) {
- if (!strcmp(i->driver, "void") || !strcmp(i->driver, "mouse") ||
- !strcmp(i->driver, "vmmouse") || !strcmp(i->driver, "evdev")) {
+ for (devs = servlayoutp->inputs; devs && *devs; devs++) {
+ if (!strcmp((*devs)->driver, "void") || !strcmp((*devs)->driver, "mouse") ||
+ !strcmp((*devs)->driver, "vmmouse") || !strcmp((*devs)->driver, "evdev")) {
found = 1; break;
}
}
@@ -1366,13 +1373,14 @@ checkCoreInputDevices(serverLayoutPtr se
foundPointer = configInput(&Pointer, confInput, from);
if (foundPointer) {
count++;
- indp = xnfrealloc(servlayoutp->inputs,
- (count + 1) * sizeof(IDevRec));
- indp[count - 1] = Pointer;
- indp[count - 1].extraOptions =
+ devs = xnfrealloc(servlayoutp->inputs,
+ (count + 1) * sizeof(IDevPtr));
+ devs[count - 1] = xnfalloc(sizeof(IDevRec));
+ *devs[count - 1] = Pointer;
+ devs[count - 1]->extraOptions =
xf86addNewOption(NULL, xnfstrdup("AlwaysCore"), NULL);
- indp[count].identifier = NULL;
- servlayoutp->inputs = indp;
+ devs[count]->identifier = NULL;
+ servlayoutp->inputs = devs;
}
}
@@ -1393,11 +1401,15 @@ checkCoreInputDevices(serverLayoutPtr se
* removed.
*/
if (coreKeyboard) {
- for (indp = servlayoutp->inputs; indp->identifier; indp++)
- if (indp == coreKeyboard)
+ for (devs = servlayoutp->inputs; devs && *devs; devs++)
+ if (*devs == coreKeyboard)
+ {
+ xfree(*devs);
+ *devs = (IDevPtr)0x1; /* ensure we dont skip next loop */
break;
- for (; indp->identifier; indp++)
- indp[0] = indp[1];
+ }
+ for (; devs && *devs; devs++)
+ devs[0] = devs[1];
count--;
}
coreKeyboard = NULL;
@@ -1457,13 +1469,14 @@ checkCoreInputDevices(serverLayoutPtr se
foundKeyboard = configInput(&Keyboard, confInput, from);
if (foundKeyboard) {
count++;
- indp = xnfrealloc(servlayoutp->inputs,
- (count + 1) * sizeof(IDevRec));
- indp[count - 1] = Keyboard;
- indp[count - 1].extraOptions =
+ devs = xnfrealloc(servlayoutp->inputs,
+ (count + 1) * sizeof(IDevPtr));
+ devs[count - 1] = xnfalloc(sizeof(IDevRec));
+ *devs[count - 1] = Keyboard;
+ devs[count - 1]->extraOptions =
xf86addNewOption(NULL, xnfstrdup("CoreKeyboard"), NULL);
- indp[count].identifier = NULL;
- servlayoutp->inputs = indp;
+ devs[count]->identifier = NULL;
+ servlayoutp->inputs = devs;
}
}
@@ -1519,7 +1532,7 @@ configLayout(serverLayoutPtr servlayoutp
MessageType from;
screenLayoutPtr slp;
GDevPtr gdp;
- IDevPtr indp;
+ IDevPtr* indp;
int i = 0, j;
if (!servlayoutp)
@@ -1731,16 +1744,19 @@ configLayout(serverLayoutPtr servlayoutp
ErrorF("Found %d input devices in the layout section %s",
count, conf_layout->lay_identifier);
#endif
- indp = xnfalloc((count + 1) * sizeof(IDevRec));
- indp[count].identifier = NULL;
+ indp = xnfcalloc((count + 1), sizeof(IDevPtr));
+ indp[count] = NULL;
irp = conf_layout->lay_input_lst;
count = 0;
while (irp) {
- if (!configInput(&indp[count], irp->iref_inputdev, X_CONFIG)) {
- xfree(indp);
- return FALSE;
+ indp[count] = xnfalloc(sizeof(IDevRec));
+ if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) {
+ while(count--)
+ xfree(indp[count]);
+ xfree(indp);
+ return FALSE;
}
- indp[count].extraOptions = irp->iref_option_lst;
+ indp[count]->extraOptions = irp->iref_option_lst;
count++;
irp = (XF86ConfInputrefPtr)irp->list.next;
}
@@ -1764,7 +1780,7 @@ configImpliedLayout(serverLayoutPtr serv
MessageType from;
XF86ConfScreenPtr s;
screenLayoutPtr slp;
- IDevPtr indp;
+ IDevPtr *indp;
if (!servlayoutp)
return FALSE;
@@ -1806,8 +1822,8 @@ configImpliedLayout(serverLayoutPtr serv
servlayoutp->inactives = xnfcalloc(1, sizeof(GDevRec));
servlayoutp->options = NULL;
/* Set up an empty input device list, then look for some core devices. */
- indp = xnfalloc(sizeof(IDevRec));
- indp->identifier = NULL;
+ indp = xnfalloc(sizeof(IDevPtr));
+ *indp = NULL;
servlayoutp->inputs = indp;
if (!xf86Info.allowEmptyInput && !checkCoreInputDevices(servlayoutp, TRUE))
return FALSE;
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 16162b7..f3670c4 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -981,7 +981,7 @@ InitInput(argc, argv)
int argc;
char **argv;
{
- IDevPtr pDev;
+ IDevPtr* pDev;
InputDriverPtr pDrv;
InputInfoPtr pInfo;
@@ -990,9 +990,9 @@ InitInput(argc, argv)
if (serverGeneration == 1) {
/* Call the PreInit function for each input device instance. */
- for (pDev = xf86ConfigLayout.inputs; pDev && pDev->identifier; pDev++) {
- if ((pDrv = xf86LookupInputDriver(pDev->driver)) == NULL) {
- xf86Msg(X_ERROR, "No Input driver matching `%s'\n", pDev->driver);
+ for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) {
+ if ((pDrv = xf86LookupInputDriver((*pDev)->driver)) == NULL) {
+ xf86Msg(X_ERROR, "No Input driver matching `%s'\n", (*pDev)->driver);
/* XXX For now, just continue. */
continue;
}
@@ -1002,14 +1002,14 @@ InitInput(argc, argv)
pDrv->driverName);
continue;
}
- pInfo = pDrv->PreInit(pDrv, pDev, 0);
+ pInfo = pDrv->PreInit(pDrv, *pDev, 0);
if (!pInfo) {
xf86Msg(X_ERROR, "PreInit returned NULL for \"%s\"\n",
- pDev->identifier);
+ (*pDev)->identifier);
continue;
} else if (!(pInfo->flags & XI86_CONFIGURED)) {
xf86Msg(X_ERROR, "PreInit failed for input device \"%s\"\n",
- pDev->identifier);
+ (*pDev)->identifier);
xf86DeleteInput(pInfo, 0);
continue;
}
diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index 6e62e52..086d2bf 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -526,7 +526,7 @@ typedef struct _serverlayoutrec {
char * id;
screenLayoutPtr screens;
GDevPtr inactives;
- IDevPtr inputs;
+ IDevPtr* inputs; /* NULL terminated */
pointer options;
} serverLayoutRec, *serverLayoutPtr;
diff-tree b141b85c254afff3ce2221d899787fab3dc295bd (from 19cde59c41cf167cc609debfee75bfc015beac12)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date: Wed Jun 13 15:26:03 2007 +0930
Check for identical grabs when adding a new passive grab. If an identical grab
exists, remove the old one and prepend the new one.
X.org Bug 2738 <https://bugs.freedesktop.org/show_bug.cgi?id=2738>
diff --git a/dix/grabs.c b/dix/grabs.c
index 714fea3..cecd7ec 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -269,6 +269,42 @@ GrabMatchesSecond(GrabPtr pFirstGrab, Gr
return FALSE;
}
+static Bool
+GrabsAreIdentical(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
+{
+ if (pFirstGrab->device != pSecondGrab->device ||
+ (pFirstGrab->modifierDevice != pSecondGrab->modifierDevice) ||
+ (pFirstGrab->type != pSecondGrab->type))
+ return FALSE;
+
+ if (!(DetailSupersedesSecond(pFirstGrab->detail,
+ pSecondGrab->detail,
+ (unsigned short)AnyKey) &&
+ DetailSupersedesSecond(pSecondGrab->detail,
+ pFirstGrab->detail,
+ (unsigned short)AnyKey)))
+ return FALSE;
+
+ if (!(DetailSupersedesSecond(pFirstGrab->modifiersDetail,
+ pSecondGrab->modifiersDetail,
+ (unsigned short)AnyModifier) &&
+ DetailSupersedesSecond(pSecondGrab->modifiersDetail,
+ pFirstGrab->modifiersDetail,
+ (unsigned short)AnyModifier)))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/**
+ * Prepend the new grab to the list of passive grabs on the window.
+ * Any previously existing grab that matches the new grab will be removed.
+ * Adding a new grab that would override another client's grab will result in
+ * a BadAccess.
+ *
+ * @return Success or X error code on failure.
+ */
int
AddPassiveGrabToList(GrabPtr pGrab)
{
@@ -291,6 +327,17 @@ AddPassiveGrabToList(GrabPtr pGrab)
FreeGrab(pGrab);
return BadAlloc;
}
+
+ /* Remove all grabs that match the new one exactly */
+ for (grab = wPassiveGrabs(pGrab->window); grab; grab = grab->next)
+ {
+ if (GrabsAreIdentical(pGrab, grab))
+ {
+ DeletePassiveGrabFromList(grab);
+ break;
+ }
+ }
+
pGrab->next = pGrab->window->optional->passiveGrabs;
pGrab->window->optional->passiveGrabs = pGrab;
if (AddResource(pGrab->resource, RT_PASSIVEGRAB, (pointer)pGrab))
More information about the xorg-commit
mailing list