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