xserver: Branch 'mpx' - 2 commits

Peter Hutterer whot at kemper.freedesktop.org
Thu Apr 26 15:57:49 EEST 2007


 XTrap/xtrapdi.c                   |    6 +
 Xext/xevie.c                      |    2 
 Xext/xtest.c                      |    6 -
 Xi/exevents.c                     |    2 
 Xi/querydp.c                      |    2 
 dix/devices.c                     |   24 ++++--
 dix/events.c                      |  137 +++++++++++++++++++-------------------
 dix/main.c                        |    1 
 hw/xwin/winwin32rootlesswndproc.c |    8 +-
 include/dix.h                     |    2 
 include/inputstr.h                |   12 +++
 mi/mi.h                           |    1 
 mi/midispcur.c                    |   67 ++++++++++++++++++
 mi/mieq.c                         |   24 +++---
 mi/mipointer.c                    |    7 +
 mi/mipointer.h                    |    1 
 mi/misprite.c                     |   27 +++++--
 mi/mispritest.h                   |    1 
 randr/rrpointer.c                 |    8 +-
 19 files changed, 230 insertions(+), 108 deletions(-)

New commits:
diff-tree cfc01115af4136b2dad8218ba6b389513a356a2e (from 82f97e1c0cc15b050edc82a8f3b9a423d6cf5fe7)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Apr 26 22:18:35 2007 +0930

    Fix cursor rendering for multi-head.
    
    Before putting anything on the screen, check if the GC was made for the
    ScreenRec we want to render to. If not, toss the GC and create a new one. This
    is not the best solution but it does the job for now. Same thing for ARGB
    cursors except that it's even uglier.
    
    Also remember the screen the cursor was rendered to and check for the right
    screen in the BlockHandler, SourceValidate and a few others. Only remove or
    restore the cursor if we are rendering to the same screen, otherwise we get
    artefacts that are both funky and really annoying.

diff --git a/mi/midispcur.c b/mi/midispcur.c
index d4471f9..d7a8964 100644
--- a/mi/midispcur.c
+++ b/mi/midispcur.c
@@ -488,6 +488,15 @@ miDCPutUpCursor (pDev, pScreen, pCursor,
 #ifdef ARGB_CURSOR
     if (pPriv->pPicture)
     {
+        /* see comment in miDCPutUpCursor */
+        if (pBuffer->pRootPicture && 
+                pBuffer->pRootPicture->pDrawable &&
+                pBuffer->pRootPicture->pDrawable->pScreen != pScreen)
+        {
+            tossPict(pBuffer->pRootPicture);
+            pBuffer->pRootPicture = NULL;
+        }
+
 	if (!EnsurePicture(pBuffer->pRootPicture, &pWin->drawable, pWin))
 	    return FALSE;
 	CompositePicture (PictOpOver,
@@ -502,6 +511,25 @@ miDCPutUpCursor (pDev, pScreen, pCursor,
     else
 #endif
     {
+        /**
+         * XXX: Before MPX, the sourceGC and maskGC were attached to the
+         * screen, and would switch as the screen switches.  With mpx we have
+         * the GC's attached to the device now, so each time we switch screen
+         * we need to make sure the GC's are allocated on the new screen.
+         * This is ... not optimal. (whot)
+         */
+        if (pBuffer->pSourceGC && pScreen != pBuffer->pSourceGC->pScreen)
+        {
+            tossGC(pBuffer->pSourceGC);
+            pBuffer->pSourceGC = NULL;
+        }
+
+        if (pBuffer->pMaskGC && pScreen != pBuffer->pMaskGC->pScreen)
+        {
+            tossGC(pBuffer->pMaskGC);
+            pBuffer->pMaskGC = NULL;
+        }
+
 	if (!EnsureGC(pBuffer->pSourceGC, pWin))
 	    return FALSE;
 	if (!EnsureGC(pBuffer->pMaskGC, pWin))
@@ -544,6 +572,12 @@ miDCSaveUnderCursor (pDev, pScreen, x, y
 	if (!pSave)
 	    return FALSE;
     }
+    /* see comment in miDCPutUpCursor */
+    if (pBuffer->pSaveGC && pBuffer->pSaveGC->pScreen != pScreen)
+    {
+        tossGC(pBuffer->pSaveGC);
+        pBuffer->pSaveGC = NULL;
+    }
     if (!EnsureGC(pBuffer->pSaveGC, pWin))
 	return FALSE;
     pGC = pBuffer->pSaveGC;
@@ -573,6 +607,12 @@ miDCRestoreUnderCursor (pDev, pScreen, x
     pWin = WindowTable[pScreen->myNum];
     if (!pSave)
 	return FALSE;
+    /* see comment in miDCPutUpCursor */
+    if (pBuffer->pRestoreGC && pBuffer->pRestoreGC->pScreen != pScreen)
+    {
+        tossGC(pBuffer->pRestoreGC);
+        pBuffer->pRestoreGC = NULL;
+    }
     if (!EnsureGC(pBuffer->pRestoreGC, pWin))
 	return FALSE;
     pGC = pBuffer->pRestoreGC;
@@ -606,6 +646,12 @@ miDCChangeSave (pDev, pScreen, x, y, w, 
      */
     if (!pSave)
 	return FALSE;
+    /* see comment in miDCPutUpCursor */
+    if (pBuffer->pRestoreGC && pBuffer->pRestoreGC->pScreen != pScreen)
+    {
+        tossGC(pBuffer->pRestoreGC);
+        pBuffer->pRestoreGC = NULL;
+    }
     if (!EnsureGC(pBuffer->pRestoreGC, pWin))
 	return FALSE;
     pGC = pBuffer->pRestoreGC;
@@ -646,6 +692,12 @@ miDCChangeSave (pDev, pScreen, x, y, w, 
 	(*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
 			       0, sourcey, -dx, copyh, x + dx, desty);
     }
+    /* see comment in miDCPutUpCursor */
+    if (pBuffer->pSaveGC && pBuffer->pSaveGC->pScreen != pScreen)
+    {
+        tossGC(pBuffer->pSaveGC);
+        pBuffer->pSaveGC = NULL;
+    }
     if (!EnsureGC(pBuffer->pSaveGC, pWin))
 	return FALSE;
     pGC = pBuffer->pSaveGC;
@@ -788,6 +840,15 @@ miDCMoveCursor (pDev, pScreen, pCursor, 
 #ifdef ARGB_CURSOR
     if (pPriv->pPicture)
     {
+        /* see comment in miDCPutUpCursor */
+        if (pBuffer->pTempPicture && 
+                pBuffer->pTempPicture->pDrawable &&
+                pBuffer->pTempPicture->pDrawable->pScreen != pScreen)
+        {
+            tossPict(pBuffer->pTempPicture);
+            pBuffer->pTempPicture = NULL;
+        }
+
 	if (!EnsurePicture(pBuffer->pTempPicture, &pTemp->drawable, pWin))
 	    return FALSE;
 	CompositePicture (PictOpOver,
@@ -822,6 +883,12 @@ miDCMoveCursor (pDev, pScreen, pCursor, 
 		     source, mask);
     }
 
+    /* see comment in miDCPutUpCursor */
+    if (pBuffer->pRestoreGC && pBuffer->pRestoreGC->pScreen != pScreen)
+    {
+        tossGC(pBuffer->pRestoreGC);
+        pBuffer->pRestoreGC = NULL;
+    }
     /*
      * copy the temporary pixmap onto the screen
      */
diff --git a/mi/misprite.c b/mi/misprite.c
index 60774b5..6e42152 100644
--- a/mi/misprite.c
+++ b/mi/misprite.c
@@ -79,6 +79,7 @@ static int miSpriteDevPrivatesIndex;
        (miCursorInfoPtr) dev->devPrivates[miSpriteDevPrivatesIndex].ptr : \
        (miCursorInfoPtr) inputInfo.pointer->devPrivates[miSpriteDevPrivatesIndex].ptr)
 
+
 /*
  * screen wrappers
  */
@@ -175,6 +176,7 @@ miSpriteReportDamage (DamagePtr pDamage,
             pCursorInfo = MISPRITE(pDev);
 
             if (pCursorInfo->isUp &&
+                pCursorInfo->pScreen == pScreen && 
                 RECT_IN_REGION (pScreen, pRegion, &pCursorInfo->saved) 
                          != rgnOUT) 
             {
@@ -277,7 +279,6 @@ miSpriteInitialize (pScreen, cursorFuncs
     damageRegister = 0;
     miSpriteDevPrivatesIndex = AllocateDevicePrivateIndex();
 
-
     return TRUE;
 }
 
@@ -340,6 +341,7 @@ miSpriteGetImage (pDrawable, sx, sy, w, 
              pCursorInfo = MISPRITE(pDev);
              if (pDrawable->type == DRAWABLE_WINDOW &&
                      pCursorInfo->isUp &&
+                     pCursorInfo->pScreen == pScreen &&
                      ORG_OVERLAP(&pCursorInfo->saved,pDrawable->x,pDrawable->y, 
                          sx, sy, w, h)) 
              {
@@ -379,7 +381,9 @@ miSpriteGetSpans (pDrawable, wMax, ppt, 
         {
             pCursorInfo = MISPRITE(pDev);
 
-            if (pDrawable->type == DRAWABLE_WINDOW && pCursorInfo->isUp)
+            if (pDrawable->type == DRAWABLE_WINDOW && 
+                    pCursorInfo->isUp && 
+                    pCursorInfo->pScreen == pScreen)
             {
                 DDXPointPtr    pts;
                 int    	       *widths;
@@ -431,6 +435,7 @@ miSpriteSourceValidate (pDrawable, x, y,
         {
             pCursorInfo = MISPRITE(pDev);
             if (pDrawable->type == DRAWABLE_WINDOW && pCursorInfo->isUp &&
+                    pCursorInfo->pScreen == pScreen && 
                     ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y,
                         x, y, width, height))
             {
@@ -466,7 +471,7 @@ miSpriteCopyWindow (WindowPtr pWindow, D
             /*
              * Damage will take care of destination check
              */
-            if (pCursorInfo->isUp &&
+            if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen &&
                     RECT_IN_REGION (pScreen, prgnSrc, &pCursorInfo->saved) != rgnOUT)
             {
                 SPRITE_DEBUG (("CopyWindow remove\n"));
@@ -504,7 +509,9 @@ miSpriteBlockHandler (i, blockData, pTim
         if (DevHasCursor(pDev))
         {
             pCursorInfo = MISPRITE(pDev);
-            if (!pCursorInfo->isUp && pCursorInfo->shouldBeUp)
+            if (!pCursorInfo->isUp 
+                    && pCursorInfo->pScreen == pScreen 
+                    && pCursorInfo->shouldBeUp)
             {
                 SPRITE_DEBUG (("BlockHandler restore\n"));
                 miSpriteSaveUnderCursor (pDev, pScreen);
@@ -516,7 +523,9 @@ miSpriteBlockHandler (i, blockData, pTim
         if (DevHasCursor(pDev))
         {
             pCursorInfo = MISPRITE(pDev);
-            if (!pCursorInfo->isUp && pCursorInfo->shouldBeUp)
+            if (!pCursorInfo->isUp && 
+                    pCursorInfo->pScreen == pScreen && 
+                    pCursorInfo->shouldBeUp)
             {
                 SPRITE_DEBUG (("BlockHandler restore\n"));
                 miSpriteRestoreCursor (pDev, pScreen);
@@ -552,7 +561,7 @@ miSpriteInstallColormap (pMap)
             {
                 pCursorInfo = MISPRITE(pDev);
                 pCursorInfo->checkPixels = TRUE;
-                if (pCursorInfo->isUp)
+                if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
                     miSpriteRemoveCursor(pDev, pScreen);
             }
         }
@@ -639,7 +648,7 @@ miSpriteStoreColors (pMap, ndef, pdef)
                 {
                     pCursorInfo = MISPRITE(pDev);
                     pCursorInfo->checkPixels = TRUE;
-                    if (pCursorInfo->isUp)
+                    if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
                         miSpriteRemoveCursor (pDev, pScreen);
                 }
             }
@@ -711,7 +720,7 @@ miSpriteSaveDoomedAreas (pWin, pObscured
         if(DevHasCursor(pDev))
         {
             pCursorInfo = MISPRITE(pDev);
-            if (pCursorInfo->isUp)
+            if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
             {
                 cursorBox = pCursorInfo->saved;
 
@@ -930,6 +939,7 @@ miSpriteDeviceCursorInitialize(pDev, pSc
     pCursorInfo->pCacheWin = NullWindow;
     pCursorInfo->isInCacheWin = FALSE;
     pCursorInfo->checkPixels = TRUE;
+    pCursorInfo->pScreen = FALSE;
 
     ret = (*pScreenPriv->funcs->DeviceCursorInitialize)(pDev, pScreen);
     if (!ret)
@@ -1075,6 +1085,7 @@ miSpriteRestoreCursor (pDev, pScreen)
                 pScreenPriv->colors[MASK_COLOR].pixel))
     {
         miSpriteIsUpTRUE (pCursorInfo, pScreen, pScreenPriv);
+        pCursorInfo->pScreen = pScreen;
     }
     miSpriteEnableDamage(pScreen, pScreenPriv);
     DamageDrawInternal (pScreen, FALSE);
diff --git a/mi/mispritest.h b/mi/mispritest.h
index f4155b5..81efa44 100644
--- a/mi/mispritest.h
+++ b/mi/mispritest.h
@@ -53,6 +53,7 @@ typedef struct {
     WindowPtr	    pCacheWin;		/* window the cursor last seen in */
     Bool	    isInCacheWin;
     Bool	    checkPixels;	/* check colormap collision */
+    ScreenPtr       pScreen;
 } miCursorInfoRec, *miCursorInfoPtr;
 
 /*
diff-tree 82f97e1c0cc15b050edc82a8f3b9a423d6cf5fe7 (from d61ed6c8a2823a3532439d5cb9f355129c93f523)
Author: Paulo Ricardo Zanoni <prz05 at c3sl.ufpr.br>
Date:   Thu Apr 26 15:58:50 2007 +0930

    Enable event delivery for multiple heads.
    
    Requires moving the spriteTrace into the DeviceIntRec and adjusting a few
    functions to take in device argument, most notably XYToWindow().
    
    Cursor rendering on the second screen is busted.

diff --git a/XTrap/xtrapdi.c b/XTrap/xtrapdi.c
index bc15bbd..0b70d7b 100644
--- a/XTrap/xtrapdi.c
+++ b/XTrap/xtrapdi.c
@@ -102,7 +102,7 @@ globalref int_function XETrapProcVector[
 #ifndef VECTORED_EVENTS
 globalref int_function EventProcVector[XETrapCoreEvents];
 #else
-extern WindowPtr GetCurrentRootWindow();
+extern WindowPtr GetCurrentRootWindow(DeviceIntPtr);
 globalref int_function EventProcVector[128L];
 #endif
 static int_function keybd_process_inp = NULL;  /* Used for VECTORED_EVENTS */
@@ -1620,7 +1620,9 @@ int XETrapEventVector(ClientPtr client, 
                 (x_event->u.u.type <= MotionNotify) && 
                 (!x_event->u.keyButtonPointer.sameScreen)))
             {   /* we've moved/warped to another screen */
-                WindowPtr root_win = GetCurrentRootWindow();
+		/* XXX: we're getting the client's pointer root window.
+		 * is this correct?  Should it be the client's keyboard? */
+                WindowPtr root_win = GetCurrentRootWindow(PickPointer(client));
                 current_screen = root_win->drawable.pScreen->myNum;
             }
             data.hdr.screen = current_screen;
diff --git a/Xext/xevie.c b/Xext/xevie.c
index 7922913..0feb4d7 100644
--- a/Xext/xevie.c
+++ b/Xext/xevie.c
@@ -463,7 +463,7 @@ XevieKbdProcessInputProc(xEvent *xE, Dev
             xevieModifiersOn = TRUE;
 
         xE->u.keyButtonPointer.event = xeviewin->drawable.id;
-        xE->u.keyButtonPointer.root = GetCurrentRootWindow()->drawable.id;
+        xE->u.keyButtonPointer.root = GetCurrentRootWindow(dev)->drawable.id;
         xE->u.keyButtonPointer.child = (xeviewin->firstChild)
             ? xeviewin->firstChild->drawable.id:0;
         xE->u.keyButtonPointer.rootX = xeviehot.x;
diff --git a/Xext/xtest.c b/Xext/xtest.c
index 93e88c4..963029c 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -363,7 +363,7 @@ ProcXTestFakeInput(client)
         if (!dev)
             dev = PickPointer(client);
 	if (ev->u.keyButtonPointer.root == None)
-	    root = GetCurrentRootWindow();
+	    root = GetCurrentRootWindow(dev);
 	else
 	{
 	    rc = dixLookupWindow(&root, ev->u.keyButtonPointer.root, client,
@@ -428,10 +428,10 @@ ProcXTestFakeInput(client)
 	if ((!noPanoramiXExtension
 	     && root->drawable.pScreen->myNum 
                 != XineramaGetCursorScreen(dev))
-	    || (noPanoramiXExtension && root != GetCurrentRootWindow()))
+	    || (noPanoramiXExtension && root != GetCurrentRootWindow(dev)))
 
 #else
-	if (root != GetCurrentRootWindow())
+	if (root != GetCurrentRootWindow(dev))
 #endif
 	{
 	    NewCurrentScreen(dev, root->drawable.pScreen,
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 26f3640..d00dc29 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -835,7 +835,7 @@ SendEvent(ClientPtr client, DeviceIntPtr
 	/* If the input focus is PointerRootWin, send the event to where
 	 * the pointer is if possible, then perhaps propogate up to root. */
 	if (inputFocus == PointerRootWin)
-	    inputFocus = GetCurrentRootWindow();
+	    inputFocus = GetCurrentRootWindow(d);
 
 	if (IsParent(inputFocus, spriteWin)) {
 	    effectiveFocus = inputFocus;
diff --git a/Xi/querydp.c b/Xi/querydp.c
index d2ed0b8..6224f13 100644
--- a/Xi/querydp.c
+++ b/Xi/querydp.c
@@ -107,7 +107,7 @@ ProcXQueryDevicePointer(ClientPtr client
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
     rep.mask = pDev->button->state | inputInfo.keyboard->key->state;
-    rep.root = (GetCurrentRootWindow())->drawable.id;
+    rep.root = (GetCurrentRootWindow(pDev))->drawable.id;
     rep.rootX = pSprite->hot.x;
     rep.rootY = pSprite->hot.y;
     rep.child = None;
diff --git a/dix/devices.c b/dix/devices.c
index 9e48c0b..cf6090d 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -194,6 +194,14 @@ EnableDevice(DeviceIntPtr dev)
 	 *prev && (*prev != dev);
 	 prev = &(*prev)->next)
 	;
+
+    /* Sprites will be initialized with their 'windows' just when inside the
+     * DefineInitialRootWindow function! */
+    if (IsPointerDevice(dev) && dev->spriteInfo->spriteOwner)
+        InitializeSprite(dev, NullWindow);
+    else
+        PairDevices(NULL, inputInfo.pointer, dev);
+
     if ((*prev != dev) || !dev->inited ||
 	((ret = (*dev->deviceProc)(dev, DEVICE_ON)) != Success)) {
         ErrorF("couldn't enable device %d\n", dev->id);
@@ -202,11 +210,6 @@ EnableDevice(DeviceIntPtr dev)
     dev->enabled = TRUE;
     *prev = dev->next;
 
-    if (IsPointerDevice(dev) && dev->spriteInfo->spriteOwner)
-        InitializeSprite(dev, GetCurrentRootWindow());
-    else
-        PairDevices(NULL, inputInfo.pointer, dev);
-
     for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next)
         ;
     *prev = dev;
@@ -272,6 +275,11 @@ ActivateDevice(DeviceIntPtr dev)
     return ret;
 }
 
+int
+DeactivateDevice(DeviceIntPtr dev)
+{
+}
+
 static void
 CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
 {
@@ -614,8 +622,10 @@ CloseDevice(DeviceIntPtr dev)
 	XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource);
 #endif
     
-    if (DevHasCursor(dev))
-        xfree((pointer)dev->spriteInfo->sprite);
+    if (DevHasCursor(dev)) {
+        xfree(dev->spriteInfo->sprite->spriteTrace);
+        xfree(dev->spriteInfo->sprite);
+    }
 
     /* a client may have the device set as client pointer */
     for (j = 0; j < currentMaxClients; j++)
diff --git a/dix/events.c b/dix/events.c
index 1733e2d..a751e3c 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -230,15 +230,7 @@ static struct {
     TimeStamp		time;
 } syncEvents;
 
-/*
- * The window trace information is used to avoid having to compute all the
- * windows between the root and the current pointer window each time a button
- * or key goes down. The grabs on each of those windows must be checked.
- */
-static WindowPtr *spriteTrace = (WindowPtr *)NULL;
-#define ROOT spriteTrace[0]
-static int spriteTraceSize = 0;
-static int spriteTraceGood;
+#define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0]
 
 /** 
  * True if device owns a cursor, false if device shares a cursor sprite with
@@ -284,6 +276,7 @@ static void DoEnterLeaveEvents(
 ); 
 
 static WindowPtr XYToWindow(
+    DeviceIntPtr pDev,
     int x,
     int y
 );
@@ -607,7 +600,7 @@ XineramaCheckMotion(xEvent *xE, DeviceIn
     xeviehot.y = pSprite->hot.y;
     xeviewin =
 #endif
-    pSprite->win = XYToWindow(pSprite->hot.x, pSprite->hot.y);
+    pSprite->win = XYToWindow(pDev, pSprite->hot.x, pSprite->hot.y);
 
     if (pSprite->win != prevSpriteWin)
     {
@@ -858,7 +851,7 @@ CheckVirtualMotion(
     xeviehot.x = pSprite->hot.x;
     xeviehot.y = pSprite->hot.y;
 #endif
-    ROOT = WindowTable[pSprite->hot.pScreen->myNum];
+    RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum];
 }
 
 static void
@@ -973,10 +966,15 @@ PostNewCursor(DeviceIntPtr pDev)
     }
 }
 
+
+/**
+ * @param dev device which you want to know its current root window
+ * @return root window where dev's sprite is located
+ */
 _X_EXPORT WindowPtr
-GetCurrentRootWindow(void)
+GetCurrentRootWindow(DeviceIntPtr dev)
 {
-    return ROOT;
+    return RootWindow(dev);
 }
 
 _X_EXPORT WindowPtr
@@ -1201,10 +1199,11 @@ ComputeFreezes(void)
 	count = replayDev->coreGrab.sync.evcount;
 	syncEvents.replayDev = (DeviceIntPtr)NULL;
 
-        w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
-	for (i = 0; i < spriteTraceGood; i++)
+        w = XYToWindow(replayDev, XE_KBPTR.rootX, XE_KBPTR.rootY);
+	for (i = 0; i < replayDev->spriteInfo->sprite->spriteTraceGood; i++)
 	{
-	    if (syncEvents.replayWin == spriteTrace[i])
+	    if (syncEvents.replayWin ==
+		replayDev->spriteInfo->sprite->spriteTrace[i])
 	    {
 		if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
 		    if (replayDev->focus)
@@ -1365,7 +1364,7 @@ DeactivatePointerGrab(DeviceIntPtr mouse
     DoEnterLeaveEvents(mouse, grab->window, 
                        mouse->spriteInfo->sprite->win, NotifyUngrab);
     if (grab->confineTo)
-	ConfineCursorToWindow(mouse, ROOT, FALSE, FALSE);
+	ConfineCursorToWindow(mouse, RootWindow(mouse), FALSE, FALSE);
     PostNewCursor(mouse);
     if (grab->cursor)
 	FreeCursor(grab->cursor, (Cursor)0);
@@ -1888,7 +1887,7 @@ FixUpEventFromWindow(
 
     if (calcChild)
     {
-        WindowPtr w=spriteTrace[spriteTraceGood-1];
+        WindowPtr w= pSprite->spriteTrace[pSprite->spriteTraceGood-1];
 	/* If the search ends up past the root should the child field be 
 	 	set to none or should the value in the argument be passed 
 		through. It probably doesn't matter since everyone calls 
@@ -1913,7 +1912,7 @@ FixUpEventFromWindow(
  	    w = w->parent;
         } 	    
     }
-    XE_KBPTR.root = ROOT->drawable.id;
+    XE_KBPTR.root = RootWindow(pDev)->drawable.id;
     XE_KBPTR.event = pWin->drawable.id;
     if (pSprite->hot.pScreen == pWin->drawable.pScreen)
     {
@@ -2064,13 +2063,15 @@ PointInBorderSize(WindowPtr pWin, int x,
 }
 
 static WindowPtr 
-XYToWindow(int x, int y)
+XYToWindow(DeviceIntPtr pDev, int x, int y)
 {
     WindowPtr  pWin;
     BoxRec		box;
+    SpritePtr pSprite;
 
-    spriteTraceGood = 1;	/* root window still there */
-    pWin = ROOT->firstChild;
+    pSprite = pDev->spriteInfo->sprite;
+    pSprite->spriteTraceGood = 1;	/* root window still there */
+    pWin = RootWindow(pDev)->firstChild;
     while (pWin)
     {
 	if ((pWin->mapped) &&
@@ -2094,21 +2095,22 @@ XYToWindow(int x, int y)
 #endif
 	    )
 	{
-	    if (spriteTraceGood >= spriteTraceSize)
+	    if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
 	    {
-		spriteTraceSize += 10;
+		pSprite->spriteTraceSize += 10;
 		Must_have_memory = TRUE; /* XXX */
-		spriteTrace = (WindowPtr *)xrealloc(
-		    spriteTrace, spriteTraceSize*sizeof(WindowPtr));
+		pSprite->spriteTrace = (WindowPtr *)xrealloc(
+		                    pSprite->spriteTrace,
+		                    pSprite->spriteTraceSize*sizeof(WindowPtr));
 		Must_have_memory = FALSE; /* XXX */
 	    }
-	    spriteTrace[spriteTraceGood++] = pWin;
+	    pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
 	    pWin = pWin->firstChild;
 	}
 	else
 	    pWin = pWin->nextSib;
     }
-    return spriteTrace[spriteTraceGood-1];
+    return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
 }
 
 Bool
@@ -2129,7 +2131,7 @@ CheckMotion(xEvent *xE, DeviceIntPtr pDe
 	if (pSprite->hot.pScreen != pSprite->hotPhys.pScreen)
 	{
 	    pSprite->hot.pScreen = pSprite->hotPhys.pScreen;
-	    ROOT = WindowTable[pSprite->hot.pScreen->myNum];
+	    RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum];
 	}
 	pSprite->hot.x = XE_KBPTR.rootX;
 	pSprite->hot.y = XE_KBPTR.rootY;
@@ -2166,7 +2168,7 @@ CheckMotion(xEvent *xE, DeviceIntPtr pDe
 #ifdef XEVIE
     xeviewin =
 #endif
-    pSprite->win = XYToWindow(pSprite->hot.x, pSprite->hot.y);
+    pSprite->win = XYToWindow(pDev, pSprite->hot.x, pSprite->hot.y);
 #ifdef notyet
     if (!(pSprite->win->deliverableEvents &
 	  Motion_Filter(pDev->button))
@@ -2263,7 +2265,6 @@ DefineInitialRootWindow(WindowPtr win)
 #ifdef XEVIE
     xeviewin = win;
 #endif
-    ROOT = win;
 
     InitializeSprite(inputInfo.pointer, win);
 
@@ -2312,8 +2313,25 @@ InitializeSprite(DeviceIntPtr pDev, Wind
     {
         pSprite->current = wCursor(pWin);
         pSprite->current->refcnt++;
-    } else
+ 	pSprite->spriteTrace = (WindowPtr *)xcalloc(1, 32*sizeof(WindowPtr));
+	if (!pSprite->spriteTrace)
+	    FatalError("Failed to allocate spriteTrace");
+	pSprite->spriteTraceSize = 32;
+
+	RootWindow(pDev) = pWin;
+	pSprite->spriteTraceGood = 1;
+
+	pSprite->pEnqueueScreen = pScreen;
+	pSprite->pDequeueScreen = pSprite->pEnqueueScreen;
+
+    } else {
         pSprite->current = NullCursor;
+	pSprite->spriteTrace = NULL;
+	pSprite->spriteTraceSize = 0;
+	pSprite->spriteTraceGood = 0;
+	pSprite->pEnqueueScreen = screenInfo.screens[0];
+	pSprite->pDequeueScreen = pSprite->pEnqueueScreen;
+    }
 
     if (pScreen)
     {
@@ -2768,14 +2786,15 @@ CheckDeviceGrabs(DeviceIntPtr device, xE
 	}
   
 	if ((focus->win == NoneWin) ||
-	    (i >= spriteTraceGood) ||
-	    ((i > checkFirst) && (pWin != spriteTrace[i-1])))
+	    (i >= device->spriteInfo->sprite->spriteTraceGood) ||
+	    ((i > checkFirst) &&
+             (pWin != device->spriteInfo->sprite->spriteTrace[i-1])))
 	    return FALSE;
     }
 
-    for (; i < spriteTraceGood; i++)
+    for (; i < device->spriteInfo->sprite->spriteTraceGood; i++)
     {
-	pWin = spriteTrace[i];
+	pWin = device->spriteInfo->sprite->spriteTrace[i];
 	if (pWin->optional &&
 	    CheckPassiveGrabsOnWindow(pWin, device, xE, count))
 	    return TRUE;
@@ -2946,7 +2965,7 @@ ProcessKeyboardEvent (xEvent *xE, Device
         {
           xeviekb = keybd;
           if(!rootWin) {
-	      rootWin = GetCurrentRootWindow()->drawable.id;
+	      rootWin = GetCurrentRootWindow(keybd)->drawable.id;
           }
           xE->u.keyButtonPointer.event = xeviewin->drawable.id;
           xE->u.keyButtonPointer.root = rootWin;
@@ -3806,8 +3825,8 @@ DoFocusEvents(DeviceIntPtr dev, WindowPt
 	if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
    	{
 	    if (fromWin == PointerRootWin)
-                FocusOutEvents(dev, pSprite->win, ROOT, mode,
-                        NotifyPointer, TRUE);
+                FocusOutEvents(dev, pSprite->win, RootWindow(dev), mode,
+                               NotifyPointer, TRUE);
 	    /* Notify all the roots */
 #ifdef PANORAMIX
  	    if ( !noPanoramiXExtension )
@@ -3836,16 +3855,16 @@ DoFocusEvents(DeviceIntPtr dev, WindowPt
 	    for (i=0; i<screenInfo.numScreens; i++)
 	        FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
 	if (toWin == PointerRootWin)
-	    (void)FocusInEvents(dev, ROOT, pSprite->win, NullWindow, mode,
-				NotifyPointer, TRUE);
+	    (void)FocusInEvents(dev, RootWindow(dev), pSprite->win,
+				NullWindow, mode, NotifyPointer, TRUE);
     }
     else
     {
 	if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
 	{
 	    if (fromWin == PointerRootWin)
-		FocusOutEvents(dev, pSprite->win, ROOT, mode, NotifyPointer,
-			       TRUE);
+		FocusOutEvents(dev, pSprite->win, RootWindow(dev), mode,
+			       NotifyPointer, TRUE);
 #ifdef PANORAMIX
  	    if ( !noPanoramiXExtension )
 	        FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
@@ -3854,7 +3873,7 @@ DoFocusEvents(DeviceIntPtr dev, WindowPt
 	        for (i=0; i<screenInfo.numScreens; i++)
 	            FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
 	    if (toWin->parent != NullWindow)
-	      (void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
+	      (void)FocusInEvents(dev, RootWindow(dev), toWin, toWin, mode,
 				  NotifyNonlinearVirtual, TRUE);
 	    FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
 	    if (IsParent(toWin, pSprite->win))
@@ -4130,7 +4149,7 @@ ProcGrabPointer(ClientPtr client)
 	if (grab)
  	{
 	    if (grab->confineTo && !confineTo)
-		ConfineCursorToWindow(device, ROOT, FALSE, FALSE);
+		ConfineCursorToWindow(device, RootWindow(device), FALSE, FALSE);
 	    oldCursor = grab->cursor;
 	}
 	tempGrab.cursor = cursor;
@@ -4351,7 +4370,7 @@ ProcQueryPointer(ClientPtr client)
     rep.sequenceNumber = client->sequence;
     rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
     rep.length = 0;
-    rep.root = (ROOT)->drawable.id;
+    rep.root = (RootWindow(mouse))->drawable.id;
     rep.rootX = pSprite->hot.x;
     rep.rootY = pSprite->hot.y;
     rep.child = None;
@@ -4400,19 +4419,6 @@ InitEvents(void)
     inputInfo.off_devices = (DeviceIntPtr)NULL;
     inputInfo.keyboard = (DeviceIntPtr)NULL;
     inputInfo.pointer = (DeviceIntPtr)NULL;
-    if (spriteTraceSize == 0)
-    {
-	spriteTraceSize = 32;
-	spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
-        /* FIXME: spriteTrace[0] needs to be NULL, otherwise
-         * GetCurrentRootWindow() in EnableDevice() may return a invalid
-         * value. (whot)
-         */
-        memset(spriteTrace, 0, 32 * sizeof(WindowPtr));
-	if (!spriteTrace)
-	    FatalError("failed to allocate spriteTrace");
-    }
-    spriteTraceGood = 0;
     lastEventMask = OwnerGrabButtonMask;
     filters[MotionNotify] = PointerMotionMask;
 #ifdef XEVIE
@@ -4441,13 +4447,14 @@ InitEvents(void)
     }
 }
 
-
-void
+/**
+ * This function is deprecated! It shouldn't be used anymore. It used to free
+ * the spriteTraces, but now they are freed when the SpriteRec is freed.
+ */
+_X_DEPRECATED void
 CloseDownEvents(void)
 {
-  xfree(spriteTrace);
-  spriteTrace = NULL;
-  spriteTraceSize = 0;
+
 }
 
 int
@@ -4497,7 +4504,7 @@ ProcSendEvent(ClientPtr client)
 	/* If the input focus is PointerRootWin, send the event to where
 	the pointer is if possible, then perhaps propogate up to root. */
    	if (inputFocus == PointerRootWin)
-	    inputFocus = ROOT;
+	    inputFocus = pSprite->spriteTrace[0]; /* Root window! */
 
 	if (IsParent(inputFocus, pSprite->win))
 	{
diff --git a/dix/main.c b/dix/main.c
index f5b89ba..2f064a9 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -498,7 +498,6 @@ main(int argc, char *argv[], char *envp[
 	    FreeScreen(screenInfo.screens[i]);
 	    screenInfo.numScreens = i;
 	}
-  	CloseDownEvents();
 	xfree(WindowTable);
 	WindowTable = NULL;
 	FreeFonts();
diff --git a/hw/xwin/winwin32rootlesswndproc.c b/hw/xwin/winwin32rootlesswndproc.c
index ffa8493..54df889 100755
--- a/hw/xwin/winwin32rootlesswndproc.c
+++ b/hw/xwin/winwin32rootlesswndproc.c
@@ -299,7 +299,9 @@ IsRaiseOnClick (WindowPtr pWin)
 
   struct _Window	*pwin;
   struct _Property	*prop;  
-  WindowPtr		pRoot = GetCurrentRootWindow ();
+  /* XXX We're getting inputInfo.poniter here, but this might be really wrong.
+   * Which pointer's current window do we want? */
+  WindowPtr		pRoot = GetCurrentRootWindow (inputInfo.pointer);
 
   if (!pWin)
     {
@@ -352,7 +354,9 @@ IsMouseActive (WindowPtr pWin)
 
   struct _Window	*pwin;
   struct _Property	*prop;
-  WindowPtr		pRoot = GetCurrentRootWindow ();
+  /* XXX We're getting inputInfo.poniter here, but this might be really wrong.
+   * Which pointer's current window do we want? */
+  WindowPtr		pRoot = GetCurrentRootWindow (inputInfo.pointer);
 
   if (!pWin)
     {
diff --git a/include/dix.h b/include/dix.h
index 385f56c..9da265d 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -357,7 +357,7 @@ extern Bool IsParent(
     WindowPtr /* maybeparent */,
     WindowPtr /* child */);
 
-extern WindowPtr GetCurrentRootWindow(void);
+extern WindowPtr GetCurrentRootWindow(DeviceIntPtr pDev);
 
 extern WindowPtr GetSpriteWindow(DeviceIntPtr pDev);
 
diff --git a/include/inputstr.h b/include/inputstr.h
index bdb7518..4924cb1 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -287,6 +287,18 @@ typedef struct {
     WindowPtr   windows[MAXSCREENS];
     WindowPtr	confineWin;	/* confine window */ 
 #endif
+    /* The window trace information is used at dix/events.c to avoid having
+     * to compute all the windows between the root and the current pointer
+     * window each time a button or key goes down. The grabs on each of those
+     * windows must be checked.
+     * spriteTraces should only be used at dix/events.c! */
+    WindowPtr *spriteTrace;
+    int spriteTraceSize;
+    int spriteTraceGood;
+
+    ScreenPtr pEnqueueScreen; /* screen events are being delivered to */
+    ScreenPtr pDequeueScreen; /* screen events are being dispatched to */
+
 } SpriteRec, *SpritePtr;
 
 /* states for devices */
diff --git a/mi/mi.h b/mi/mi.h
index fad2d19..f83c42b 100644
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -158,6 +158,7 @@ extern void mieqEnqueue(
 );
 
 extern void mieqSwitchScreen(
+    DeviceIntPtr /* pDev */,
     ScreenPtr /*pScreen*/,
     Bool /*fromDIX*/
 );
diff --git a/mi/mieq.c b/mi/mieq.c
index 143a94f..2eeb21e 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -67,6 +67,9 @@ in this Software without prior written a
 
 #define QUEUE_SIZE  512
 
+#define EnqueueScreen(dev) dev->spriteInfo->sprite->pEnqueueScreen
+#define DequeueScreen(dev) dev->spriteInfo->sprite->pDequeueScreen
+
 typedef struct _Event {
     xEvent          event[7];
     int             nevents;
@@ -79,8 +82,6 @@ typedef struct _EventQueue {
     CARD32           lastEventTime;      /* to avoid time running backwards */
     int              lastMotion;         /* device ID if last event motion? */
     EventRec         events[QUEUE_SIZE]; /* static allocation for signals */
-    ScreenPtr        pEnqueueScreen;     /* screen events are being delivered to */
-    ScreenPtr        pDequeueScreen;     /* screen events are being dispatched to */
     mieqHandler      handlers[128];      /* custom event handler */
 } EventQueueRec, *EventQueuePtr;
 
@@ -94,8 +95,6 @@ mieqInit(void)
     miEventQueue.head = miEventQueue.tail = 0;
     miEventQueue.lastEventTime = GetTimeInMillis ();
     miEventQueue.lastMotion = FALSE;
-    miEventQueue.pEnqueueScreen = screenInfo.screens[0];
-    miEventQueue.pDequeueScreen = miEventQueue.pEnqueueScreen;
     for (i = 0; i < 128; i++)
         miEventQueue.handlers[i] = NULL;
     SetInputCheck(&miEventQueue.head, &miEventQueue.tail);
@@ -179,18 +178,18 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e
 
     miEventQueue.lastEventTime =
 	miEventQueue.events[oldtail].event[0].u.keyButtonPointer.time;
-    miEventQueue.events[oldtail].pScreen = miEventQueue.pEnqueueScreen;
+    miEventQueue.events[oldtail].pScreen = EnqueueScreen(pDev);
     miEventQueue.events[oldtail].pDev = pDev;
 
     miEventQueue.lastMotion = isMotion;
 }
 
 void
-mieqSwitchScreen(ScreenPtr pScreen, Bool fromDIX)
+mieqSwitchScreen(DeviceIntPtr pDev, ScreenPtr pScreen, Bool fromDIX)
 {
-    miEventQueue.pEnqueueScreen = pScreen;
+    EnqueueScreen(pDev) = pScreen;
     if (fromDIX)
-	miEventQueue.pDequeueScreen = pScreen;
+	DequeueScreen(pDev) = pScreen;
 }
 
 void
@@ -224,15 +223,15 @@ mieqProcessInputEvents(void)
 
         e = &miEventQueue.events[miEventQueue.head];
         /* Assumption - screen switching can only occur on motion events. */
-        if (e->pScreen != miEventQueue.pDequeueScreen) {
-            miEventQueue.pDequeueScreen = e->pScreen;
+        if (e->pScreen != DequeueScreen(e->pDev)) {
+            DequeueScreen(e->pDev) = e->pScreen;
             x = e->event[0].u.keyButtonPointer.rootX;
             y = e->event[0].u.keyButtonPointer.rootY;
             if (miEventQueue.head == QUEUE_SIZE - 1)
                 miEventQueue.head = 0;
             else
                 ++miEventQueue.head;
-            NewCurrentScreen (e->pDev, miEventQueue.pDequeueScreen, x, y);
+            NewCurrentScreen (e->pDev, DequeueScreen(e->pDev), x, y);
         }
         else {
             if (miEventQueue.head == QUEUE_SIZE - 1)
@@ -243,7 +242,8 @@ mieqProcessInputEvents(void)
             /* If someone's registered a custom event handler, let them
              * steal it. */
             if (miEventQueue.handlers[e->event->u.u.type]) {
-                miEventQueue.handlers[e->event->u.u.type](miEventQueue.pDequeueScreen->myNum,
+                miEventQueue.handlers[e->event->u.u.type](
+						  DequeueScreen(e->pDev)->myNum,
                                                           e->event, dev,
                                                           e->nevents);
                 return;
diff --git a/mi/mipointer.c b/mi/mipointer.c
index b06a0be..b14c2c7 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -351,7 +351,7 @@ miPointerWarpCursor (pDev, pScreen, x, y
     SetupScreen (pScreen);
 
     if (pPointer->pScreen != pScreen)
-	(*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, TRUE);
+	(*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, TRUE);
 
     if (GenerateEvent)
     {
@@ -492,7 +492,7 @@ miPointerSetScreen(DeviceIntPtr pDev, in
 
 	pScreen = screenInfo.screens[screen_no];
 	pScreenPriv = GetScreenPrivate (pScreen);
-	(*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, FALSE);
+	(*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE);
 	NewCurrentScreen (pDev, pScreen, x, y);
 
         pPointer->limits.x2 = pScreen->width;
@@ -570,7 +570,8 @@ miPointerSetPosition(DeviceIntPtr pDev, 
 	    if (newScreen != pScreen)
 	    {
 		pScreen = newScreen;
-		(*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, FALSE);
+		(*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen,
+							     FALSE);
 		pScreenPriv = GetScreenPrivate (pScreen);
 	    	/* Smash the confine to the new screen */
                 pPointer->limits.x2 = pScreen->width;
diff --git a/mi/mipointer.h b/mi/mipointer.h
index 666a6eb..cc9c037 100644
--- a/mi/mipointer.h
+++ b/mi/mipointer.h
@@ -88,6 +88,7 @@ typedef struct _miPointerScreenFuncRec {
                     xEventPtr /* event */
                     );
     void	(*NewEventScreen)(
+		    DeviceIntPtr /* pDev */,
                     ScreenPtr /* pScr */,
 		    Bool /* fromDIX */
                     );
diff --git a/randr/rrpointer.c b/randr/rrpointer.c
index fec5d45..722b22c 100644
--- a/randr/rrpointer.c
+++ b/randr/rrpointer.c
@@ -135,10 +135,16 @@ RRPointerMoved (ScreenPtr pScreen, int x
 void
 RRPointerScreenConfigured (ScreenPtr pScreen)
 {
-    WindowPtr	pRoot = GetCurrentRootWindow ();
+    WindowPtr	pRoot = GetCurrentRootWindow (inputInfo.pointer);
     ScreenPtr	pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL;
     int		x, y;
 
+    /* XXX: GetCurrentRootWindow revices an argument, It is inputInfo.pointer,
+     * but I really think this is wrong...  What do we do here? This was made so
+     * that it can compile, but I don't think randr should assume there is just
+     * one pointer. There might be more than one pointer on the screen! So, what
+     * to do? What happens? */
+
     if (pScreen != pCurrentScreen)
 	return;
     GetSpritePosition(inputInfo.pointer, &x, &y);



More information about the xorg-commit mailing list