xserver: Branch 'mpx' - 5 commits

Peter Hutterer whot at kemper.freedesktop.org
Mon Apr 9 13:07:27 EEST 2007


 dix/devices.c                  |   76 +++++++++
 dix/main.c                     |    2 
 hw/xfree86/common/xf86Events.c |   10 -
 include/dix.h                  |    4 
 include/input.h                |    2 
 include/scrnintstr.h           |   16 ++
 mi/midispcur.c                 |  165 +++++++++-----------
 mi/mipointer.c                 |  141 ++++++++++++-----
 mi/mipointer.h                 |   12 +
 mi/misprite.c                  |  325 +++++++++++++++++++++--------------------
 mi/misprite.h                  |    8 +
 mi/mispritest.h                |   13 -
 12 files changed, 480 insertions(+), 294 deletions(-)

New commits:
diff-tree f1f8b562aaaa6ec32ab0d0697f964d92d6d536a4 (from 7cef789fa13ae53bfba6dc7b5a7928b7362b2522)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Mon Apr 9 19:31:59 2007 +0930

    Alloc sprite memory in devices' devPrivates, allow undisplaying cursors.
    
    Improve memory usage by allocating the sprite's memory only to devices that
    actually have a sprite and provide means to remove a device's cursor from the
    screen (more hotplugging, yay!).
    This commit breaks ScreenRec's ABI.

diff --git a/dix/devices.c b/dix/devices.c
index 2b55679..0a91997 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -225,18 +225,29 @@ DisableDevice(DeviceIntPtr dev)
     return TRUE;
 }
 
+/**
+ * Initialize device through driver, allocate memory for cursor sprite (if
+ * applicable) and send a PresenceNotify event to all clients.
+ *
+ * Must be called before EnableDevice.
+ */
 int
 ActivateDevice(DeviceIntPtr dev)
 {
     int ret = Success;
     devicePresenceNotify ev;
     DeviceIntRec dummyDev;
+    ScreenPtr pScreen = screenInfo.screens[0];
 
     if (!dev || !dev->deviceProc)
         return BadImplementation;
 
     ret = (*dev->deviceProc) (dev, DEVICE_INIT);
     dev->inited = (ret == Success);
+
+    /* Initialize memory for sprites. */
+    if (IsPointerDevice(dev))
+        pScreen->DeviceCursorInitialize(dev, pScreen);
     
     ev.type = DevicePresenceNotify;
     ev.time = currentTime.milliseconds;
@@ -497,11 +508,16 @@ CloseDevice(DeviceIntPtr dev)
     StringFeedbackPtr s, snext;
     BellFeedbackPtr b, bnext;
     LedFeedbackPtr l, lnext;
+    ScreenPtr screen = screenInfo.screens[0];
     int j;
 
     if (dev->inited)
 	(void)(*dev->deviceProc)(dev, DEVICE_CLOSE);
 
+    /* free sprite memory */
+    if (IsPointerDevice(dev))
+        screen->DeviceCursorCleanup(dev, screen);
+
     xfree(dev->name);
 
     if (dev->key) {
@@ -624,6 +640,22 @@ CloseDownDevices()
     inputInfo.pointer = NULL;
 }
 
+/**
+ * Remove the cursor sprite for all devices. This needs to be done before any
+ * resources are freed or any device is deleted.
+ */
+void 
+UndisplayDevices()
+{
+    DeviceIntPtr dev;
+    ScreenPtr screen = screenInfo.screens[0];
+
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+        screen->UndisplayCursor(dev, screen);
+    }
+}
+
 int
 RemoveDevice(DeviceIntPtr dev)
 {
@@ -631,23 +663,26 @@ RemoveDevice(DeviceIntPtr dev)
     int ret = BadMatch;
     devicePresenceNotify ev;
     DeviceIntRec dummyDev;
+    ScreenPtr screen = screenInfo.screens[0];
 
     DebugF("(dix) removing device %d\n", dev->id);
 
     if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
         return BadImplementation;
 
+    screen->UndisplayCursor(dev, screen);
+
     prev = NULL;
     for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
 	next = tmp->next;
 	if (tmp == dev) {
-	    CloseDevice(tmp);
 
 	    if (prev==NULL)
 		inputInfo.devices = next;
 	    else
 		prev->next = next;
 
+	    CloseDevice(tmp);
 	    ret = Success;
 	}
     }
diff --git a/dix/main.c b/dix/main.c
index 92c30b6..c7a0f6b 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -466,6 +466,8 @@ main(int argc, char *argv[], char *envp[
 
 	Dispatch();
 
+        UndisplayDevices();
+
 	/* Now free up whatever must be freed */
 	if (screenIsSaved == SCREEN_SAVER_ON)
 	    SaveScreens(SCREEN_SAVER_OFF, ScreenSaverReset);
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 8458899..f826b3b 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -247,9 +247,13 @@ ProcessInputEvents ()
 
   mieqProcessInputEvents();
 
-  /* FIXME: This is a problem if we have multiple pointers */
-  miPointerGetPosition(inputInfo.pointer, &x, &y);
-  xf86SetViewport(xf86Info.currentScreen, x, y);
+  /* PIE can be called after devices have been shut down. Blame DGA. */
+  if (inputInfo.pointer)
+  {
+      /* FIXME: This is a problem if we have multiple pointers */
+      miPointerGetPosition(inputInfo.pointer, &x, &y);
+      xf86SetViewport(xf86Info.currentScreen, x, y);
+  }
 }
 
 void
diff --git a/include/dix.h b/include/dix.h
index 1b112a1..385f56c 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -424,6 +424,10 @@ extern int DeliverDeviceEvents(
 extern void DefineInitialRootWindow(
     WindowPtr /* win */);
 
+extern void SetupSprite(
+    DeviceIntPtr /* pDev */,
+    ScreenPtr    /* pScreen */);
+
 extern void InitializeSprite(
     DeviceIntPtr /* pDev */,
     WindowPtr    /* pWin */);
diff --git a/include/input.h b/include/input.h
index 765d71d..2debce9 100644
--- a/include/input.h
+++ b/include/input.h
@@ -190,6 +190,8 @@ extern int InitAndStartDevices(void);
 
 extern void CloseDownDevices(void);
 
+extern void UndisplayDevices(void);
+
 extern int RemoveDevice(
     DeviceIntPtr /*dev*/);
 
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index 0d468c3..3cfd6c3 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -431,6 +431,18 @@ typedef    void (* MarkUnrealizedWindowP
 	WindowPtr /*pWin*/,
 	Bool /*fromConfigure*/);
 
+typedef    void (* UndisplayCursorProcPtr)(
+        DeviceIntPtr /* pDev */,
+        ScreenPtr    /* pScreen */);
+
+typedef    Bool (* DeviceCursorInitializeProcPtr)(
+        DeviceIntPtr /* pDev */,
+        ScreenPtr    /* pScreen */);
+
+typedef    void (* DeviceCursorCleanupProcPtr)(
+        DeviceIntPtr /* pDev */,
+        ScreenPtr    /* pScreen */);
+
 typedef struct _Screen {
     int			myNum;	/* index of this instance in Screens[] */
     ATOM		id;
@@ -587,6 +599,10 @@ typedef struct _Screen {
     ChangeBorderWidthProcPtr	ChangeBorderWidth;
     MarkUnrealizedWindowProcPtr	MarkUnrealizedWindow;
 
+    /* Device cursor procedures */
+    UndisplayCursorProcPtr        UndisplayCursor;
+    DeviceCursorInitializeProcPtr DeviceCursorInitialize;
+    DeviceCursorCleanupProcPtr    DeviceCursorCleanup;
 } ScreenRec;
 
 typedef struct _ScreenInfo {
diff --git a/mi/midispcur.c b/mi/midispcur.c
index 35f0fba..d4471f9 100644
--- a/mi/midispcur.c
+++ b/mi/midispcur.c
@@ -67,6 +67,9 @@ static unsigned long miDCGeneration = 0;
 
 static Bool	miDCCloseScreen(int index, ScreenPtr pScreen);
 
+/* per device private data */
+static int      miDCSpriteIndex;
+
 typedef struct {
     GCPtr	    pSourceGC, pMaskGC;
     GCPtr	    pSaveGC, pRestoreGC;
@@ -79,13 +82,16 @@ typedef struct {
 #endif
 } miDCBufferRec, *miDCBufferPtr;
 
+#define MIDCBUFFER(dev) \
+ ((DevHasCursor(dev)) ? \
+  (miDCBufferPtr)dev->devPrivates[miDCSpriteIndex].ptr :\
+  (miDCBufferPtr)inputInfo.pointer->devPrivates[miDCSpriteIndex].ptr)
+
 /* 
  * The core pointer buffer will point to the index of the virtual core pointer
  * in the pCursorBuffers array. 
  */
 typedef struct {
-    miDCBufferPtr pCoreBuffer; /* for core pointer */
-    miDCBufferPtr pCursorBuffers;   /* one for each device */
     CloseScreenProcPtr CloseScreen;
 } miDCScreenRec, *miDCScreenPtr;
 
@@ -121,6 +127,9 @@ static Bool	miDCChangeSave(DeviceIntPtr 
                                int x, int y, int w, int h,	
                                int dx, int dy);
 
+static Bool     miDCDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen);
+static void     miDCDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen);
+
 static miSpriteCursorFuncRec miDCFuncs = {
     miDCRealizeCursor,
     miDCUnrealizeCursor,
@@ -129,6 +138,8 @@ static miSpriteCursorFuncRec miDCFuncs =
     miDCRestoreUnderCursor,
     miDCMoveCursor,
     miDCChangeSave,
+    miDCDeviceInitialize,
+    miDCDeviceCleanup
 };
 
 _X_EXPORT Bool
@@ -137,8 +148,6 @@ miDCInitialize (pScreen, screenFuncs)
     miPointerScreenFuncPtr  screenFuncs;
 {
     miDCScreenPtr   pScreenPriv;
-    miDCBufferPtr   pBuffer;
-    int mpBufferIdx;
 
     if (miDCGeneration != serverGeneration)
     {
@@ -151,41 +160,8 @@ miDCInitialize (pScreen, screenFuncs)
     if (!pScreenPriv)
 	return FALSE;
 
-    /*
-     * initialize the entire private structure to zeros
-     */
-
-    pScreenPriv->pCursorBuffers = (miDCBufferPtr)xalloc(MAX_DEVICES *
-            sizeof(miDCBufferRec));
-    if (!pScreenPriv->pCursorBuffers)
-    {
-        xfree((pointer)pScreenPriv);
-        return FALSE;
-    }
-
-    /* virtual core pointer ID is 1 */
-    pScreenPriv->pCoreBuffer = &pScreenPriv->pCursorBuffers[1];
-
-    mpBufferIdx = 0;
-    while(mpBufferIdx < MAX_DEVICES)
-    {
-        pBuffer = &pScreenPriv->pCursorBuffers[mpBufferIdx];
-        pBuffer->pSourceGC =
-            pBuffer->pMaskGC =
-            pBuffer->pSaveGC =
-            pBuffer->pRestoreGC =
-            pBuffer->pMoveGC =
-            pBuffer->pPixSourceGC =
-            pBuffer->pPixMaskGC = NULL;
-#ifdef ARGB_CURSOR
-            pBuffer->pRootPicture = NULL;
-            pBuffer->pTempPicture = NULL;
-#endif
-        pBuffer->pSave = pBuffer->pTemp = NULL;
-
-        mpBufferIdx++;
-    }
 
+    miDCSpriteIndex = AllocateDevicePrivateIndex();
 
     pScreenPriv->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = miDCCloseScreen;
@@ -194,7 +170,6 @@ miDCInitialize (pScreen, screenFuncs)
 
     if (!miSpriteInitialize (pScreen, &miDCFuncs, screenFuncs))
     {
-        xfree ((pointer) pScreenPriv->pCursorBuffers);
 	xfree ((pointer) pScreenPriv);
 	return FALSE;
     }
@@ -211,38 +186,10 @@ miDCCloseScreen (index, pScreen)
     ScreenPtr	pScreen;
 {
     miDCScreenPtr   pScreenPriv;
-    miDCBufferPtr   pBuffer;
-    int mpBufferIdx;
 
     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
     pScreen->CloseScreen = pScreenPriv->CloseScreen;
 
-    mpBufferIdx = 0;
-    while (mpBufferIdx < MAX_DEVICES) 
-    {
-        pBuffer = &pScreenPriv->pCursorBuffers[mpBufferIdx];
-
-        tossGC (pBuffer->pSourceGC);
-        tossGC (pBuffer->pMaskGC);
-        tossGC (pBuffer->pSaveGC);
-        tossGC (pBuffer->pRestoreGC);
-        tossGC (pBuffer->pMoveGC);
-        tossGC (pBuffer->pPixSourceGC);
-        tossGC (pBuffer->pPixMaskGC);
-        tossPix (pBuffer->pSave);
-        tossPix (pBuffer->pTemp);
-#ifdef ARGB_CURSOR
-#if 0				/* This has been free()d before */
-            tossPict (pScreenPriv->pRootPicture);
-#endif 
-            tossPict (pBuffer->pTempPicture);
-#endif
-
-            mpBufferIdx++;
-    }
-
-    xfree((pointer) pScreenPriv->pCursorBuffers);
-
     xfree ((pointer) pScreenPriv);
     return (*pScreen->CloseScreen) (index, pScreen);
 }
@@ -536,10 +483,7 @@ miDCPutUpCursor (pDev, pScreen, pCursor,
     }
     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
     pWin = WindowTable[pScreen->myNum];
-    pBuffer = pScreenPriv->pCoreBuffer;
-
-    if (DevHasCursor(pDev))
-        pBuffer = &pScreenPriv->pCursorBuffers[pDev->id];
+    pBuffer = MIDCBUFFER(pDev);
 
 #ifdef ARGB_CURSOR
     if (pPriv->pPicture)
@@ -587,10 +531,7 @@ miDCSaveUnderCursor (pDev, pScreen, x, y
     GCPtr	    pGC;
 
     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
-    pBuffer = pScreenPriv->pCoreBuffer;
-
-    if (DevHasCursor(pDev))
-        pBuffer = &pScreenPriv->pCursorBuffers[pDev->id];
+    pBuffer = MIDCBUFFER(pDev);
 
     pSave = pBuffer->pSave;
     pWin = WindowTable[pScreen->myNum];
@@ -626,10 +567,7 @@ miDCRestoreUnderCursor (pDev, pScreen, x
     GCPtr	    pGC;
 
     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
-    pBuffer = pScreenPriv->pCoreBuffer;
-
-    if (DevHasCursor(pDev))
-        pBuffer = &pScreenPriv->pCursorBuffers[pDev->id];
+    pBuffer = MIDCBUFFER(pDev);
 
     pSave = pBuffer->pSave;
     pWin = WindowTable[pScreen->myNum];
@@ -659,10 +597,7 @@ miDCChangeSave (pDev, pScreen, x, y, w, 
     int		    sourcex, sourcey, destx, desty, copyw, copyh;
 
     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
-    pBuffer = pScreenPriv->pCoreBuffer;
-
-    if (DevHasCursor(pDev))
-        pBuffer = &pScreenPriv->pCursorBuffers[pDev->id];
+    pBuffer = MIDCBUFFER(pDev);
 
     pSave = pBuffer->pSave;
     pWin = WindowTable[pScreen->myNum];
@@ -810,10 +745,7 @@ miDCMoveCursor (pDev, pScreen, pCursor, 
     }
     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
     pWin = WindowTable[pScreen->myNum];
-    pBuffer = pScreenPriv->pCoreBuffer;
-
-    if (DevHasCursor(pDev))
-        pBuffer = &pScreenPriv->pCursorBuffers[pDev->id];
+    pBuffer = MIDCBUFFER(pDev);
 
     pTemp = pBuffer->pTemp;
     if (!pTemp ||
@@ -905,3 +837,62 @@ miDCMoveCursor (pDev, pScreen, pCursor, 
 			    0, 0, w, h, x, y);
     return TRUE;
 }
+
+static Bool
+miDCDeviceInitialize(pDev, pScreen)
+    DeviceIntPtr pDev;
+    ScreenPtr pScreen;
+{
+    miDCBufferPtr pBuffer;
+
+    if (!AllocateDevicePrivate(pDev, miDCSpriteIndex))
+        return FALSE;
+
+    pBuffer = 
+       pDev->devPrivates[miDCSpriteIndex].ptr = xalloc(sizeof(miDCBufferRec));
+
+    pBuffer->pSourceGC =
+        pBuffer->pMaskGC =
+        pBuffer->pSaveGC =
+        pBuffer->pRestoreGC =
+        pBuffer->pMoveGC =
+        pBuffer->pPixSourceGC =
+        pBuffer->pPixMaskGC = NULL;
+#ifdef ARGB_CURSOR
+    pBuffer->pRootPicture = NULL;
+    pBuffer->pTempPicture = NULL;
+#endif
+    pBuffer->pSave = pBuffer->pTemp = NULL;
+
+    return TRUE;
+}
+
+static void
+miDCDeviceCleanup(pDev, pScreen)
+    DeviceIntPtr pDev;
+    ScreenPtr pScreen;
+{
+    miDCBufferPtr   pBuffer;
+
+    if (DevHasCursor(pDev))
+    {
+        pBuffer = MIDCBUFFER(pDev);
+        tossGC (pBuffer->pSourceGC);
+        tossGC (pBuffer->pMaskGC);
+        tossGC (pBuffer->pSaveGC);
+        tossGC (pBuffer->pRestoreGC);
+        tossGC (pBuffer->pMoveGC);
+        tossGC (pBuffer->pPixSourceGC);
+        tossGC (pBuffer->pPixMaskGC);
+        tossPix (pBuffer->pSave);
+        tossPix (pBuffer->pTemp);
+#ifdef ARGB_CURSOR
+#if 0				/* This has been free()d before */
+        tossPict (pScreenPriv->pRootPicture);
+#endif 
+        tossPict (pBuffer->pTempPicture);
+#endif
+        xfree(pDev->devPrivates[miDCSpriteIndex].ptr);
+        pDev->devPrivates[miDCSpriteIndex].ptr = NULL;
+    }
+}
diff --git a/mi/mipointer.c b/mi/mipointer.c
index b9f54c1..b06a0be 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -54,18 +54,12 @@ static unsigned long miPointerGeneration
 #define GetScreenPrivate(s) ((miPointerScreenPtr) ((s)->devPrivates[miPointerScreenIndex].ptr))
 #define SetupScreen(s)	miPointerScreenPtr  pScreenPriv = GetScreenPrivate(s)
 
-/*
- * until more than one pointer device exists.
- */
-
-static miPointerPtr miCorePointer;
+static int miPointerPrivatesIndex = 0;
 
-/* Multipointers 
- * ID of a device == index in this array.
- */
-static miPointerRec miPointers[MAX_DEVICES];
 #define MIPOINTER(dev) \
-    (DevHasCursor((dev))) ? &miPointers[(dev)->id] : miCorePointer
+    ((DevHasCursor((dev))) ? \
+        (miPointerPtr) dev->devPrivates[miPointerPrivatesIndex].ptr : \
+        (miPointerPtr) inputInfo.pointer->devPrivates[miPointerPrivatesIndex].ptr)
 
 static Bool miPointerRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 
                                    CursorPtr pCursor);
@@ -73,6 +67,7 @@ static Bool miPointerUnrealizeCursor(Dev
                                      CursorPtr pCursor);
 static Bool miPointerDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 
                                    CursorPtr pCursor);
+static void miPointerUndisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen);
 static void miPointerConstrainCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
                                      BoxPtr pBox); 
 static void miPointerPointerNonInterestBox(DeviceIntPtr pDev, 
@@ -87,6 +82,9 @@ static Bool miPointerCloseScreen(int ind
 static void miPointerMove(DeviceIntPtr pDev, ScreenPtr pScreen, 
                           int x, int y,
                           unsigned long time);
+static Bool miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen);
+static void miPointerDeviceCleanup(DeviceIntPtr pDev,
+                                   ScreenPtr pScreen);
 
 static xEvent* events; /* for WarpPointer MotionNotifies */
 
@@ -98,8 +96,6 @@ miPointerInitialize (pScreen, spriteFunc
     Bool		    waitForUpdate;
 {
     miPointerScreenPtr	pScreenPriv;
-    miPointerPtr        pPointer;
-    int                 ptrIdx;
 
     if (miPointerGeneration != serverGeneration)
     {
@@ -131,33 +127,17 @@ miPointerInitialize (pScreen, spriteFunc
     pScreen->ConstrainCursor = miPointerConstrainCursor;
     pScreen->CursorLimits = miPointerCursorLimits;
     pScreen->DisplayCursor = miPointerDisplayCursor;
+    pScreen->UndisplayCursor = miPointerUndisplayCursor;
+    pScreen->UndisplayCursor = miPointerUndisplayCursor;
     pScreen->RealizeCursor = miPointerRealizeCursor;
     pScreen->UnrealizeCursor = miPointerUnrealizeCursor;
     pScreen->SetCursorPosition = miPointerSetCursorPosition;
     pScreen->RecolorCursor = miRecolorCursor;
     pScreen->PointerNonInterestBox = miPointerPointerNonInterestBox;
+    pScreen->DeviceCursorInitialize = miPointerDeviceInitialize;
+    pScreen->DeviceCursorCleanup = miPointerDeviceCleanup;
 
-    /*
-     * set up the pointer object
-     * virtual core pointer ID is always 1, so we let it point to the matching
-     * index in the array.
-     */
-    miCorePointer = &miPointers[1];
-    for(ptrIdx = 0; ptrIdx < MAX_DEVICES; ptrIdx++)
-    {
-            pPointer = &miPointers[ptrIdx];
-            pPointer->pScreen = NULL;
-            pPointer->pSpriteScreen = NULL;
-            pPointer->pCursor = NULL;
-            pPointer->pSpriteCursor = NULL;
-            pPointer->limits.x1 = 0;
-            pPointer->limits.x2 = 32767;
-            pPointer->limits.y1 = 0;
-            pPointer->limits.y2 = 32767;
-            pPointer->confined = FALSE;
-            pPointer->x = 0;
-            pPointer->y = 0;
-    }
+    miPointerPrivatesIndex = AllocateDevicePrivateIndex();
 
     events = NULL;
     return TRUE;
@@ -169,20 +149,30 @@ miPointerCloseScreen (index, pScreen)
     ScreenPtr	pScreen;
 {
     miPointerPtr pPointer;
-    int ptrIdx;
+    DeviceIntPtr pDev;
 
     SetupScreen(pScreen);
 
-    for(ptrIdx = 0; ptrIdx < MAX_DEVICES; ptrIdx++)
+#if 0
+    for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
     {
-        pPointer = &miPointers[ptrIdx];
+        if (DevHasCursor(pDev))
+        {
+            pPointer = MIPOINTER(pDev);
 
-        if (pScreen == pPointer->pScreen)
-            pPointer->pScreen = 0;
-        if (pScreen == pPointer->pSpriteScreen)
-            pPointer->pSpriteScreen = 0;
+            if (pScreen == pPointer->pScreen)
+                pPointer->pScreen = 0;
+            if (pScreen == pPointer->pSpriteScreen)
+                pPointer->pSpriteScreen = 0;
+        }
     }
 
+    if (MIPOINTER(inputInfo.pointer)->pScreen == pScreen)
+        MIPOINTER(inputInfo.pointer)->pScreen = 0;
+    if (MIPOINTER(inputInfo.pointer)->pSpriteScreen == pScreen)
+        MIPOINTER(inputInfo.pointer)->pSpriteScreen = 0;
+#endif
+
     pScreen->CloseScreen = pScreenPriv->CloseScreen;
     xfree ((pointer) pScreenPriv);
     xfree ((pointer) events);
@@ -229,6 +219,15 @@ miPointerDisplayCursor (pDev, pScreen, p
 }
 
 static void
+miPointerUndisplayCursor(pDev, pScreen)
+    DeviceIntPtr pDev;
+    ScreenPtr 	 pScreen;
+{
+    SetupScreen(pScreen);
+    (*pScreenPriv->spriteFuncs->UndisplayCursor)(pDev, pScreen);
+}
+
+static void
 miPointerConstrainCursor (pDev, pScreen, pBox)
     DeviceIntPtr pDev;
     ScreenPtr	pScreen;
@@ -281,6 +280,65 @@ miPointerSetCursorPosition(pDev, pScreen
     return TRUE;
 }
 
+/* Set up sprite information for the device. 
+   This function will be called once for each device after it is initialized
+   in the DIX.
+ */ 
+static Bool
+miPointerDeviceInitialize(pDev, pScreen)
+    DeviceIntPtr pDev;
+    ScreenPtr pScreen;
+{
+    miPointerPtr pPointer;
+    SetupScreen (pScreen);
+
+    if (!AllocateDevicePrivate(pDev, miPointerPrivatesIndex))
+        return FALSE;
+
+    pPointer = xalloc(sizeof(miPointerRec));
+    if (!pPointer)
+        return FALSE;
+
+    pPointer->pScreen = NULL;
+    pPointer->pSpriteScreen = NULL;
+    pPointer->pCursor = NULL;
+    pPointer->pSpriteCursor = NULL;
+    pPointer->limits.x1 = 0;
+    pPointer->limits.x2 = 32767;
+    pPointer->limits.y1 = 0;
+    pPointer->limits.y2 = 32767;
+    pPointer->confined = FALSE;
+    pPointer->x = 0;
+    pPointer->y = 0;
+
+    if (!((*pScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen)))
+    {
+        xfree(pPointer);
+        return FALSE;
+    }
+
+    pDev->devPrivates[miPointerPrivatesIndex].ptr = pPointer;
+    return TRUE;
+}
+
+/* Clean up after device. 
+   This function will be called once before the device is freed in the DIX
+ */
+static void
+miPointerDeviceCleanup(pDev, pScreen)
+    DeviceIntPtr pDev;
+    ScreenPtr pScreen;
+{
+    if (DevHasCursor(pDev))
+    {
+        SetupScreen(pScreen);
+        (*pScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
+        xfree(pDev->devPrivates[miPointerPrivatesIndex].ptr);
+        pDev->devPrivates[miPointerPrivatesIndex].ptr = NULL;
+    }
+}
+
+
 /* Once signals are ignored, the WarpCursor function can call this */
 
 _X_EXPORT void
@@ -413,7 +471,8 @@ miPointerUpdateSprite (DeviceIntPtr pDev
 void
 miPointerDeltaCursor (int dx, int dy, unsigned long time)
 {
-    int x = miCorePointer->x + dx, y = miCorePointer->y + dy;
+    int x = MIPOINTER(inputInfo.pointer)->x = dx;
+    int y = MIPOINTER(inputInfo.pointer)->y = dy;
 
     miPointerSetPosition(inputInfo.pointer, &x, &y, time);
 }
diff --git a/mi/mipointer.h b/mi/mipointer.h
index c483413..666a6eb 100644
--- a/mi/mipointer.h
+++ b/mi/mipointer.h
@@ -53,6 +53,18 @@ typedef struct _miPointerSpriteFuncRec {
                     int  /* x */,
                     int  /* y */
                     );
+    Bool        (*DeviceCursorInitialize)(
+                    DeviceIntPtr /* pDev */,
+                    ScreenPtr /* pScr */
+                    );
+    void        (*DeviceCursorCleanup)(
+                    DeviceIntPtr /* pDev */,
+                    ScreenPtr /* pScr */
+                    );
+    void        (*UndisplayCursor)(
+                    DeviceIntPtr /* pDev */,
+                    ScreenPtr /* pScr */
+                    );
 } miPointerSpriteFuncRec, *miPointerSpriteFuncPtr;
 
 typedef struct _miPointerScreenFuncRec {
diff --git a/mi/misprite.c b/mi/misprite.c
index bb67f48..60774b5 100644
--- a/mi/misprite.c
+++ b/mi/misprite.c
@@ -72,6 +72,13 @@ in this Software without prior written a
 #define SPRITE_DEBUG(x)
 #endif
 
+
+static int miSpriteDevPrivatesIndex;
+#define MISPRITE(dev) \
+    ((DevHasCursor(dev)) ? \
+       (miCursorInfoPtr) dev->devPrivates[miSpriteDevPrivatesIndex].ptr : \
+       (miCursorInfoPtr) inputInfo.pointer->devPrivates[miSpriteDevPrivatesIndex].ptr)
+
 /*
  * screen wrappers
  */
@@ -104,6 +111,11 @@ static void	    miSpriteSaveDoomedAreas(
 static void	    miSpriteComputeSaved(DeviceIntPtr pDev, 
                                          ScreenPtr pScreen);
 
+static Bool         miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, 
+                                                   ScreenPtr pScreen);
+static void         miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, 
+                                                ScreenPtr pScreen);
+
 #define SCREEN_PROLOGUE(pScreen, field)\
   ((pScreen)->field = \
    ((miSpriteScreenPtr) (pScreen)->devPrivates[miSpriteScreenIndex].ptr)->field)
@@ -123,12 +135,16 @@ static void miSpriteSetCursor(DeviceIntP
                               CursorPtr pCursor, int x, int y);
 static void miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 
                                int x, int y);
+static void miSpriteUndisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen);
 
 _X_EXPORT miPointerSpriteFuncRec miSpritePointerFuncs = {
     miSpriteRealizeCursor,
     miSpriteUnrealizeCursor,
     miSpriteSetCursor,
     miSpriteMoveCursor,
+    miSpriteDeviceCursorInitialize,
+    miSpriteDeviceCursorCleanup,
+    miSpriteUndisplayCursor
 };
 
 /*
@@ -156,7 +172,7 @@ miSpriteReportDamage (DamagePtr pDamage,
     {
         if (DevHasCursor(pDev))
         {
-            pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
+            pCursorInfo = MISPRITE(pDev);
 
             if (pCursorInfo->isUp &&
                 RECT_IN_REGION (pScreen, pRegion, &pCursorInfo->saved) 
@@ -183,8 +199,6 @@ miSpriteInitialize (pScreen, cursorFuncs
 {
     miSpriteScreenPtr	pScreenPriv;
     VisualPtr		pVisual;
-    miCursorInfoPtr     pCursorInfo;
-    int cursorIdx;
     
     if (!DamageSetup (pScreen))
 	return FALSE;
@@ -231,44 +245,19 @@ miSpriteInitialize (pScreen, cursorFuncs
     pScreenPriv->StoreColors = pScreen->StoreColors;
     
     pScreenPriv->BlockHandler = pScreen->BlockHandler;
-    
-    /* alloc and zero memory for all cursors */
-    pScreenPriv->pDevCursors = 
-        (miCursorInfoPtr)xalloc(MAX_DEVICES * sizeof(miCursorInfoRec));
 
-    if (!pScreenPriv->pDevCursors)
-    {
-        xfree((pointer)pScreenPriv);
-        return FALSE;
-    }
-    /* virtual core pointer's ID is 1 */
-    pScreenPriv->cp = &(pScreenPriv->pDevCursors[1]);
-
-    cursorIdx = 0;
-    while (cursorIdx < MAX_DEVICES)
-    {
-        pCursorInfo = &(pScreenPriv->pDevCursors[cursorIdx]);
-        pCursorInfo->pCursor = NULL;
-        pCursorInfo->x = 0;
-        pCursorInfo->y = 0;
-        pCursorInfo->isUp = FALSE;
-        pCursorInfo->shouldBeUp = FALSE;
-        pCursorInfo->pCacheWin = NullWindow;
-        pCursorInfo->isInCacheWin = FALSE;
-        pCursorInfo->checkPixels = TRUE;
-        pCursorInfo->pInstalledMap = NULL;
-        pCursorInfo->pColormap = NULL;
-        pCursorInfo->colors[SOURCE_COLOR].red = 0;
-        pCursorInfo->colors[SOURCE_COLOR].green = 0;
-        pCursorInfo->colors[SOURCE_COLOR].blue = 0;
-        pCursorInfo->colors[MASK_COLOR].red = 0;
-        pCursorInfo->colors[MASK_COLOR].green = 0;
-        pCursorInfo->colors[MASK_COLOR].blue = 0;
-
-        cursorIdx++;
-    }
+    pScreenPriv->DeviceCursorInitialize = pScreen->DeviceCursorInitialize;
+    pScreenPriv->DeviceCursorCleanup = pScreen->DeviceCursorCleanup;
 
+    pScreenPriv->pInstalledMap = NULL;
+    pScreenPriv->pColormap = NULL;
     pScreenPriv->funcs = cursorFuncs;
+    pScreenPriv->colors[SOURCE_COLOR].red = 0;
+    pScreenPriv->colors[SOURCE_COLOR].green = 0;
+    pScreenPriv->colors[SOURCE_COLOR].blue = 0;
+    pScreenPriv->colors[MASK_COLOR].red = 0;
+    pScreenPriv->colors[MASK_COLOR].green = 0;
+    pScreenPriv->colors[MASK_COLOR].blue = 0;
     pScreen->devPrivates[miSpriteScreenIndex].ptr = (pointer) pScreenPriv;
 
     pScreen->CloseScreen = miSpriteCloseScreen;
@@ -286,6 +275,8 @@ miSpriteInitialize (pScreen, cursorFuncs
     pScreen->BlockHandler = miSpriteBlockHandler;
 
     damageRegister = 0;
+    miSpriteDevPrivatesIndex = AllocateDevicePrivateIndex();
+
 
     return TRUE;
 }
@@ -318,18 +309,8 @@ miSpriteCloseScreen (i, pScreen)
     pScreen->StoreColors = pScreenPriv->StoreColors;
 
     pScreen->SaveDoomedAreas = pScreenPriv->SaveDoomedAreas;
-    for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
-    {
-        if (DevHasCursor(pDev))
-        {
-            miCursorInfoPtr pCursor;
-            pCursor = &pScreenPriv->pDevCursors[pDev->id];
-            miSpriteIsUpFALSE (pCursor, pScreen, pScreenPriv);
-        }
-    }
     DamageDestroy (pScreenPriv->pDamage);
 
-    xfree ((pointer)(pScreenPriv->pDevCursors));
     xfree ((pointer) pScreenPriv);
 
     return (*pScreen->CloseScreen) (i, pScreen);
@@ -356,7 +337,7 @@ miSpriteGetImage (pDrawable, sx, sy, w, 
     {
         if (DevHasCursor(pDev))
         {
-             pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
+             pCursorInfo = MISPRITE(pDev);
              if (pDrawable->type == DRAWABLE_WINDOW &&
                      pCursorInfo->isUp &&
                      ORG_OVERLAP(&pCursorInfo->saved,pDrawable->x,pDrawable->y, 
@@ -396,7 +377,7 @@ miSpriteGetSpans (pDrawable, wMax, ppt, 
     {
         if (DevHasCursor(pDev))
         {
-            pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
+            pCursorInfo = MISPRITE(pDev);
 
             if (pDrawable->type == DRAWABLE_WINDOW && pCursorInfo->isUp)
             {
@@ -448,7 +429,7 @@ miSpriteSourceValidate (pDrawable, x, y,
     {
         if (DevHasCursor(pDev))
         {
-            pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
+            pCursorInfo = MISPRITE(pDev);
             if (pDrawable->type == DRAWABLE_WINDOW && pCursorInfo->isUp &&
                     ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y,
                         x, y, width, height))
@@ -481,7 +462,7 @@ miSpriteCopyWindow (WindowPtr pWindow, D
     {
         if (DevHasCursor(pDev))
         {
-            pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
+            pCursorInfo = MISPRITE(pDev);
             /*
              * Damage will take care of destination check
              */
@@ -522,7 +503,7 @@ miSpriteBlockHandler (i, blockData, pTim
     {
         if (DevHasCursor(pDev))
         {
-            pCursorInfo = &pPriv->pDevCursors[pDev->id];
+            pCursorInfo = MISPRITE(pDev);
             if (!pCursorInfo->isUp && pCursorInfo->shouldBeUp)
             {
                 SPRITE_DEBUG (("BlockHandler restore\n"));
@@ -534,7 +515,7 @@ miSpriteBlockHandler (i, blockData, pTim
     {
         if (DevHasCursor(pDev))
         {
-            pCursorInfo = &pPriv->pDevCursors[pDev->id];
+            pCursorInfo = MISPRITE(pDev);
             if (!pCursorInfo->isUp && pCursorInfo->shouldBeUp)
             {
                 SPRITE_DEBUG (("BlockHandler restore\n"));
@@ -550,9 +531,6 @@ miSpriteInstallColormap (pMap)
 {
     ScreenPtr		pScreen = pMap->pScreen;
     miSpriteScreenPtr	pPriv;
-    DeviceIntPtr            pDev = inputInfo.pointer;
-    miCursorInfoPtr         pCursorInfo;
-    int                     cursorIdx;
 
     pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
 
@@ -562,29 +540,23 @@ miSpriteInstallColormap (pMap)
 
     SCREEN_EPILOGUE(pScreen, InstallColormap);
 
-    /* InstallColormap is called before devices are initialized. We cannot
-     * just run through the device list, we need to go through all possible
-     * sprite structs.*/
-    for (cursorIdx = 0; cursorIdx < MAX_DEVICES; cursorIdx++)
-    {
-        pCursorInfo = &pPriv->pDevCursors[cursorIdx];
-        pCursorInfo->pInstalledMap = pMap;
-        if (pCursorInfo->pColormap != pMap)
+    /* InstallColormap can be called before devices are initialized. */
+    pPriv->pInstalledMap = pMap;
+    if (pPriv->pColormap != pMap)
+    {
+        DeviceIntPtr pDev;
+        miCursorInfoPtr     pCursorInfo;
+        for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
         {
-            pCursorInfo->checkPixels = TRUE;
-            if (pCursorInfo->isUp)
+            if (DevHasCursor(pDev))
             {
-                /* find matching device */
-                for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
-                {
-                    if (pDev->id == cursorIdx)
-                    {
-                        miSpriteRemoveCursor(pDev, pScreen);
-                        break;
-                    }
-                }
-            } 
-        } 
+                pCursorInfo = MISPRITE(pDev);
+                pCursorInfo->checkPixels = TRUE;
+                if (pCursorInfo->isUp)
+                    miSpriteRemoveCursor(pDev, pScreen);
+            }
+        }
+
     }
 }
 
@@ -599,8 +571,8 @@ miSpriteStoreColors (pMap, ndef, pdef)
     int			i;
     int			updated;
     VisualPtr		pVisual;
-    DeviceIntPtr            pDev = inputInfo.pointer;
-    miCursorInfoPtr         pCursorInfo;
+    DeviceIntPtr        pDev = inputInfo.pointer;
+    miCursorInfoPtr     pCursorInfo;
 
     pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
 
@@ -610,6 +582,14 @@ miSpriteStoreColors (pMap, ndef, pdef)
 
     SCREEN_EPILOGUE(pScreen, StoreColors);
 
+    if (pPriv->pColormap == pMap)
+    {
+        updated = 0;
+        pVisual = pMap->pVisual;
+        if (pVisual->class == DirectColor)
+        {
+            /* Direct color - match on any of the subfields */
+
 #define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask)))
 
 #define UpdateDAC(dev, plane,dac,mask) {\
@@ -624,48 +604,40 @@ miSpriteStoreColors (pMap, ndef, pdef)
 	    UpdateDAC(dev, plane,green,greenMask) \
 	    UpdateDAC(dev, plane,blue,blueMask)
 
-    for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
-    {
-        if (DevHasCursor(pDev))
+            for (i = 0; i < ndef; i++)
+            {
+                CheckDirect (pPriv, SOURCE_COLOR)
+                CheckDirect (pPriv, MASK_COLOR)
+            }
+        }
+        else
         {
-            pCursorInfo = &pPriv->pDevCursors[pDev->id];
-            if (pCursorInfo->pColormap == pMap)
+            /* PseudoColor/GrayScale - match on exact pixel */
+            for (i = 0; i < ndef; i++)
             {
-                updated = 0;
-                pVisual = pMap->pVisual;
-                if (pVisual->class == DirectColor)
+                if (pdef[i].pixel ==
+                        pPriv->colors[SOURCE_COLOR].pixel) 
                 {
-                    /* Direct color - match on any of the subfields */
-
-                    for (i = 0; i < ndef; i++)
-                    {
-                        CheckDirect (pCursorInfo, SOURCE_COLOR)
-                            CheckDirect (pCursorInfo, MASK_COLOR)
-                    }
+                    pPriv->colors[SOURCE_COLOR] = pdef[i];
+                    if (++updated == 2)
+                        break;
                 }
-                else
+                if (pdef[i].pixel ==
+                        pPriv->colors[MASK_COLOR].pixel) 
                 {
-                    /* PseudoColor/GrayScale - match on exact pixel */
-                    for (i = 0; i < ndef; i++)
-                    {
-                        if (pdef[i].pixel ==
-                                pCursorInfo->colors[SOURCE_COLOR].pixel) 
-                        {
-                            pCursorInfo->colors[SOURCE_COLOR] = pdef[i];
-                            if (++updated == 2)
-                                break;
-                        }
-                        if (pdef[i].pixel ==
-                                pCursorInfo->colors[MASK_COLOR].pixel) 
-                        {
-                            pCursorInfo->colors[MASK_COLOR] = pdef[i];
-                            if (++updated == 2)
-                                break;
-                        }
-                    }
+                    pPriv->colors[MASK_COLOR] = pdef[i];
+                    if (++updated == 2)
+                        break;
                 }
-                if (updated)
+            }
+        }
+        if (updated)
+        {
+            for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
+            {
+                if (DevHasCursor(pDev))
                 {
+                    pCursorInfo = MISPRITE(pDev);
                     pCursorInfo->checkPixels = TRUE;
                     if (pCursorInfo->isUp)
                         miSpriteRemoveCursor (pDev, pScreen);
@@ -673,19 +645,20 @@ miSpriteStoreColors (pMap, ndef, pdef)
             }
         }
     }
-
 }
 
 static void
 miSpriteFindColors (miCursorInfoPtr pDevCursor, ScreenPtr pScreen)
 {
+    miSpriteScreenPtr   pScreenPriv = (miSpriteScreenPtr)
+                               pScreen->devPrivates[miSpriteScreenIndex].ptr;
     CursorPtr		pCursor;
     xColorItem		*sourceColor, *maskColor;
 
     pCursor = pDevCursor->pCursor;
-    sourceColor = &pDevCursor->colors[SOURCE_COLOR];
-    maskColor = &pDevCursor->colors[MASK_COLOR];
-    if (pDevCursor->pColormap != pDevCursor->pInstalledMap ||
+    sourceColor = &pScreenPriv->colors[SOURCE_COLOR];
+    maskColor = &pScreenPriv->colors[MASK_COLOR];
+    if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap ||
 	!(pCursor->foreRed == sourceColor->red &&
 	  pCursor->foreGreen == sourceColor->green &&
           pCursor->foreBlue == sourceColor->blue &&
@@ -693,18 +666,18 @@ miSpriteFindColors (miCursorInfoPtr pDev
 	  pCursor->backGreen == maskColor->green &&
 	  pCursor->backBlue == maskColor->blue))
     {
-	pDevCursor->pColormap = pDevCursor->pInstalledMap;
+	pScreenPriv->pColormap = pScreenPriv->pInstalledMap;
 	sourceColor->red = pCursor->foreRed;
 	sourceColor->green = pCursor->foreGreen;
 	sourceColor->blue = pCursor->foreBlue;
-	FakeAllocColor (pDevCursor->pColormap, sourceColor);
+	FakeAllocColor (pScreenPriv->pColormap, sourceColor);
 	maskColor->red = pCursor->backRed;
 	maskColor->green = pCursor->backGreen;
 	maskColor->blue = pCursor->backBlue;
-	FakeAllocColor (pDevCursor->pColormap, maskColor);
+	FakeAllocColor (pScreenPriv->pColormap, maskColor);
 	/* "free" the pixels right away, don't let this confuse you */
-	FakeFreeColor(pDevCursor->pColormap, sourceColor->pixel);
-	FakeFreeColor(pDevCursor->pColormap, maskColor->pixel);
+	FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel);
+	FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel);
     }
 
     pDevCursor->checkPixels = FALSE;
@@ -737,7 +710,7 @@ miSpriteSaveDoomedAreas (pWin, pObscured
     {
         if(DevHasCursor(pDev))
         {
-            pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
+            pCursorInfo = MISPRITE(pDev);
             if (pCursorInfo->isUp)
             {
                 cursorBox = pCursorInfo->saved;
@@ -777,10 +750,7 @@ miSpriteRealizeCursor (pDev, pScreen, pC
     miCursorInfoPtr pCursorInfo;
 
     pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
-    pCursorInfo = pScreenPriv->cp;
-
-    if (DevHasCursor(pDev))
-        pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
+    pCursorInfo = MISPRITE(pDev);
 
     if (pCursor == pCursorInfo->pCursor)
 	pCursorInfo->checkPixels = TRUE;
@@ -811,10 +781,7 @@ miSpriteSetCursor (pDev, pScreen, pCurso
     miSpriteScreenPtr	pScreenPriv;
 
     pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
-    miCursorInfoPtr pPointer = pScreenPriv->cp;
-
-    if (DevHasCursor(pDev))
-        pPointer = &pScreenPriv->pDevCursors[pDev->id];
+    miCursorInfoPtr pPointer = MISPRITE(pDev);
 
     if (!pCursor)
     {
@@ -929,12 +896,74 @@ miSpriteMoveCursor (pDev, pScreen, x, y)
     CursorPtr pCursor;
 
     pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
-    pCursor = pScreenPriv->cp->pCursor;
+    pCursor = MISPRITE(pDev)->pCursor;
+
+    miSpriteSetCursor (pDev, pScreen, pCursor, x, y);
+}
+
+
+static Bool
+miSpriteDeviceCursorInitialize(pDev, pScreen)
+    DeviceIntPtr pDev;
+    ScreenPtr pScreen;
+{
+    miSpriteScreenPtr pScreenPriv;
+    miCursorInfoPtr pCursorInfo;
+    int ret = FALSE;
+
+    pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+    if (!AllocateDevicePrivate(pDev, miSpriteDevPrivatesIndex))
+        return FALSE;
+
+    pCursorInfo = 
+        pDev->devPrivates[miSpriteDevPrivatesIndex].ptr = 
+            xalloc(sizeof(miCursorInfoRec));
+    if (!pCursorInfo)
+        return FALSE;
+
+    pCursorInfo->pCursor = NULL;
+    pCursorInfo->x = 0;
+    pCursorInfo->y = 0;
+    pCursorInfo->isUp = FALSE;
+    pCursorInfo->shouldBeUp = FALSE;
+    pCursorInfo->pCacheWin = NullWindow;
+    pCursorInfo->isInCacheWin = FALSE;
+    pCursorInfo->checkPixels = TRUE;
+
+    ret = (*pScreenPriv->funcs->DeviceCursorInitialize)(pDev, pScreen);
+    if (!ret)
+    {
+        xfree(pCursorInfo);
+        pDev->devPrivates[miSpriteDevPrivatesIndex].ptr = NULL;
+    } 
+    return ret;
+}
 
+static void
+miSpriteDeviceCursorCleanup(pDev, pScreen)
+    DeviceIntPtr pDev;
+    ScreenPtr    pScreen;
+{
     if (DevHasCursor(pDev))
-        pCursor = pScreenPriv->pDevCursors[pDev->id].pCursor;
+    {
+        miSpriteScreenPtr pScreenPriv;
+        pScreenPriv = 
+            (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+        (*pScreenPriv->funcs->DeviceCursorCleanup)(pDev, pScreen);
+        pDev->devPrivates[miSpriteDevPrivatesIndex].ptr = NULL;
+        xfree(MISPRITE(pDev));
+    }
+}
 
-    miSpriteSetCursor (pDev, pScreen, pCursor, x, y);
+static void
+miSpriteUndisplayCursor(pDev, pScreen)
+    DeviceIntPtr pDev;
+    ScreenPtr    pScreen;
+{
+    if (MISPRITE(pDev)->isUp)
+        miSpriteRemoveCursor(pDev, pScreen);
 }
 
 /*
@@ -952,10 +981,7 @@ miSpriteRemoveCursor (pDev, pScreen)
 
     DamageDrawInternal (pScreen, TRUE);
     pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
-    pCursorInfo = pScreenPriv->cp;
-
-    if (DevHasCursor(pDev))
-        pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
+    pCursorInfo = MISPRITE(pDev);
 
     miSpriteIsUpFALSE (pCursorInfo, pScreen, pScreenPriv);
     pCursorInfo->pCacheWin = NullWindow;
@@ -992,10 +1018,7 @@ miSpriteSaveUnderCursor(pDev, pScreen)
 
     DamageDrawInternal (pScreen, TRUE);
     pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
-    pCursorInfo = pScreenPriv->cp;
-
-    if (DevHasCursor(pDev))
-        pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
+    pCursorInfo = MISPRITE(pDev);
 
     miSpriteComputeSaved (pDev, pScreen);
     pCursor = pCursorInfo->pCursor;
@@ -1035,10 +1058,7 @@ miSpriteRestoreCursor (pDev, pScreen)
 
     DamageDrawInternal (pScreen, TRUE);
     pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
-    pCursorInfo = pScreenPriv->cp;
-
-    if (DevHasCursor(pDev))
-        pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
+    pCursorInfo = MISPRITE(pDev);
 
     miSpriteComputeSaved (pDev, pScreen);
     pCursor = pCursorInfo->pCursor;
@@ -1051,8 +1071,8 @@ miSpriteRestoreCursor (pDev, pScreen)
         miSpriteFindColors (pCursorInfo, pScreen);
     if ((*pScreenPriv->funcs->PutUpCursor) (pDev, pScreen, 
                 pCursor, x, y,
-                pCursorInfo->colors[SOURCE_COLOR].pixel,
-                pCursorInfo->colors[MASK_COLOR].pixel))
+                pScreenPriv->colors[SOURCE_COLOR].pixel,
+                pScreenPriv->colors[MASK_COLOR].pixel))
     {
         miSpriteIsUpTRUE (pCursorInfo, pScreen, pScreenPriv);
     }
@@ -1076,10 +1096,7 @@ miSpriteComputeSaved (pDev, pScreen)
     miCursorInfoPtr pCursorInfo;
 
     pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
-    pCursorInfo = pScreenPriv->cp;
-
-    if (DevHasCursor(pDev))
-        pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
+    pCursorInfo = MISPRITE(pDev);
 
     pCursor = pCursorInfo->pCursor;
     x = pCursorInfo->x - (int)pCursor->bits->xhot;
diff --git a/mi/misprite.h b/mi/misprite.h
index 96d2d7d..72dc06f 100644
--- a/mi/misprite.h
+++ b/mi/misprite.h
@@ -89,6 +89,14 @@ typedef struct {
 		int /*dx*/,
 		int /*dy*/
 );
+    Bool	(*DeviceCursorInitialize)(
+                DeviceIntPtr /*pDev*/,
+		ScreenPtr /*pScreen*/
+);
+    void	(*DeviceCursorCleanup)(
+                DeviceIntPtr /*pDev*/,
+		ScreenPtr /*pScreen*/
+);
 
 } miSpriteCursorFuncRec, *miSpriteCursorFuncPtr;
 
diff --git a/mi/mispritest.h b/mi/mispritest.h
index 8cc2064..f4155b5 100644
--- a/mi/mispritest.h
+++ b/mi/mispritest.h
@@ -53,9 +53,6 @@ typedef struct {
     WindowPtr	    pCacheWin;		/* window the cursor last seen in */
     Bool	    isInCacheWin;
     Bool	    checkPixels;	/* check colormap collision */
-    xColorItem	    colors[2];
-    ColormapPtr	    pInstalledMap;
-    ColormapPtr	    pColormap;
 } miCursorInfoRec, *miCursorInfoPtr;
 
 /*
@@ -81,13 +78,17 @@ typedef struct {
     
     /* os layer procedures */
     ScreenBlockHandlerProcPtr		BlockHandler;
+    
+    /* device cursor procedures */
+    DeviceCursorInitializeProcPtr       DeviceCursorInitialize;
+    DeviceCursorCleanupProcPtr          DeviceCursorCleanup;
 
-    miCursorInfoPtr  cp;                 /* core pointer */
-
+    xColorItem	    colors[2];
+    ColormapPtr     pInstalledMap;
+    ColormapPtr     pColormap;
     VisualPtr	    pVisual;
     miSpriteCursorFuncPtr    funcs;
     DamagePtr	    pDamage;		/* damage tracking structure */
-    miCursorInfoPtr pDevCursors;         /* all cursors' info */
 } miSpriteScreenRec, *miSpriteScreenPtr;
 
 #define SOURCE_COLOR	0
diff-tree 7cef789fa13ae53bfba6dc7b5a7928b7362b2522 (from 6081b8c76f7d934bd4e9584a2f6d55636c5289d2)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Mon Apr 9 18:37:48 2007 +0930

    Close down virtual core devices when closing all devices.

diff --git a/dix/devices.c b/dix/devices.c
index 4794d6f..2b55679 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -605,6 +605,9 @@ CloseDownDevices()
 {
     DeviceIntPtr dev, next;
 
+    CloseDevice(inputInfo.keyboard);
+    CloseDevice(inputInfo.pointer);
+
     for (dev = inputInfo.devices; dev; dev = next)
     {
 	next = dev->next;
diff-tree 6081b8c76f7d934bd4e9584a2f6d55636c5289d2 (from 00b1d52f4103a07568dcebcdaa860b9b51f19b4d)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Mon Apr 9 18:35:47 2007 +0930

    Don't explicitly init sprite for VCP, EnableDevice() will take care of that.

diff --git a/dix/devices.c b/dix/devices.c
index a080535..4794d6f 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -424,7 +424,6 @@ InitCoreDevices()
         if (!AllocateDevicePrivate(dev, CoreDevicePrivatesIndex))
             FatalError("Couldn't allocate pointer devPrivates\n");
         dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
-        InitializeSprite(dev, NullWindow);
         (void)ActivateDevice(dev);
 
         /* Enable device, and then remove it from the device list. Virtual
diff-tree 00b1d52f4103a07568dcebcdaa860b9b51f19b4d (from aa77ffb510abe004802ab9acc6996e4c6fe3ebb2)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Mon Apr 9 18:32:00 2007 +0930

    Adding some comments to devices.c.

diff --git a/dix/devices.c b/dix/devices.c
index 30c2670..a080535 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -85,6 +85,9 @@ static int CoreDevicePrivatesGeneration 
 /* The client that is allowed to change pointer-keyboard pairings. */
 static ClientPtr pairingClient = NULL;
 
+/** 
+ * Alloc memory for new sprite, reset to default values 
+ */ 
 DeviceIntPtr
 AddInputDevice(DeviceProc deviceProc, Bool autoStart)
 {
@@ -163,6 +166,12 @@ AddInputDevice(DeviceProc deviceProc, Bo
     return dev;
 }
 
+/**
+ * Enable the device through the driver, initialize the DIX sprite or pair the
+ * device, add the device to the device list.
+ *
+ * After calling EnableDevice(), a device can and will send events.
+ */
 Bool
 EnableDevice(DeviceIntPtr dev)
 {
@@ -194,6 +203,9 @@ EnableDevice(DeviceIntPtr dev)
     return TRUE;
 }
 
+/**
+ * Shut device down through drivers, remove from device list.
+ */  
 Bool
 DisableDevice(DeviceIntPtr dev)
 {
@@ -341,6 +353,14 @@ CorePointerProc(DeviceIntPtr pDev, int w
     return Success;
 }
 
+/**
+ * Initialize a virtual core keyboard and a virtual core pointer. 
+ *
+ * Both devices are not tied to physical devices, but guarantee that there is
+ * always a keyboard and a pointer present and keep the protocol semantics.
+ * Both core devices are NOT part of the device list and act only as a
+ * fallback if no physical device is available.
+ */
 void
 InitCoreDevices()
 {
@@ -422,6 +442,13 @@ InitCoreDevices()
     }
 }
 
+/**
+ * Activate and enable all devices. 
+ *
+ * After InitAndStartDevices() all devices are finished with their setup
+ * routines and start emitting events.
+ * Each physical keyboard is paired with the first available unpaired pointer.
+ */
 int
 InitAndStartDevices()
 {
@@ -459,6 +486,9 @@ InitAndStartDevices()
     return Success;
 }
 
+/**
+ * Shut down device and free memory.
+ */
 static void
 CloseDevice(DeviceIntPtr dev)
 {
diff-tree aa77ffb510abe004802ab9acc6996e4c6fe3ebb2 (from 5c4deb71a1cb981ea7e2e25d2b3a1179f27efa5a)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Mon Apr 9 18:27:22 2007 +0930

    Fix: pick new ClientPointer when device is closed.

diff --git a/dix/devices.c b/dix/devices.c
index 411188d..30c2670 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -556,7 +556,10 @@ CloseDevice(DeviceIntPtr dev)
     for (j = 0; j < currentMaxClients; j++)
     {
         if (clients[j]->clientPtr == dev)
-            PickPointer(clients[j]);
+        {
+            clients[j]->clientPtr = NULL;
+            clients[j]->clientPtr = PickPointer(clients[j]);
+        }
     }
 
     if (dev->devPrivates)



More information about the xorg-commit mailing list