misprite.c revision 4642e01f
105b261ecSmrg/*
205b261ecSmrg * misprite.c
305b261ecSmrg *
405b261ecSmrg * machine independent software sprite routines
505b261ecSmrg */
605b261ecSmrg
705b261ecSmrg/*
805b261ecSmrg
905b261ecSmrgCopyright 1989, 1998  The Open Group
1005b261ecSmrg
1105b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its
1205b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that
1305b261ecSmrgthe above copyright notice appear in all copies and that both that
1405b261ecSmrgcopyright notice and this permission notice appear in supporting
1505b261ecSmrgdocumentation.
1605b261ecSmrg
1705b261ecSmrgThe above copyright notice and this permission notice shall be included in
1805b261ecSmrgall copies or substantial portions of the Software.
1905b261ecSmrg
2005b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2105b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2205b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
2305b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2405b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2505b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2605b261ecSmrg
2705b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be
2805b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings
2905b261ecSmrgin this Software without prior written authorization from The Open Group.
3005b261ecSmrg*/
3105b261ecSmrg
3205b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
3305b261ecSmrg#include <dix-config.h>
3405b261ecSmrg#endif
3505b261ecSmrg
3605b261ecSmrg# include   <X11/X.h>
3705b261ecSmrg# include   <X11/Xproto.h>
3805b261ecSmrg# include   "misc.h"
3905b261ecSmrg# include   "pixmapstr.h"
4005b261ecSmrg# include   "input.h"
4105b261ecSmrg# include   "mi.h"
4205b261ecSmrg# include   "cursorstr.h"
4305b261ecSmrg# include   <X11/fonts/font.h>
4405b261ecSmrg# include   "scrnintstr.h"
4505b261ecSmrg# include   "colormapst.h"
4605b261ecSmrg# include   "windowstr.h"
4705b261ecSmrg# include   "gcstruct.h"
4805b261ecSmrg# include   "mipointer.h"
4905b261ecSmrg# include   "mispritest.h"
5005b261ecSmrg# include   "dixfontstr.h"
5105b261ecSmrg# include   <X11/fonts/fontstruct.h>
524642e01fSmrg# include   "inputstr.h"
5305b261ecSmrg
5405b261ecSmrg#ifdef RENDER
5505b261ecSmrg# include   "mipict.h"
5605b261ecSmrg#endif
5705b261ecSmrg# include   "damage.h"
5805b261ecSmrg
594642e01fSmrg
604642e01fSmrg
6105b261ecSmrg#define SPRITE_DEBUG_ENABLE 0
6205b261ecSmrg#if SPRITE_DEBUG_ENABLE
6305b261ecSmrg#define SPRITE_DEBUG(x)	ErrorF x
6405b261ecSmrg#else
6505b261ecSmrg#define SPRITE_DEBUG(x)
6605b261ecSmrg#endif
6705b261ecSmrg
684642e01fSmrg
694642e01fSmrg#define MISPRITE(dev) \
704642e01fSmrg    ((DevHasCursor(dev)) ? \
714642e01fSmrg       (miCursorInfoPtr)dixLookupPrivate(&dev->devPrivates, miSpriteDevPrivatesKey) : \
724642e01fSmrg       (miCursorInfoPtr)dixLookupPrivate(&dev->u.master->devPrivates, miSpriteDevPrivatesKey))
734642e01fSmrg
744642e01fSmrgstatic int damageRegister = 0;
754642e01fSmrg
764642e01fSmrgstatic void
774642e01fSmrgmiSpriteDisableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv)
784642e01fSmrg{
794642e01fSmrg    if (damageRegister) {
804642e01fSmrg	DamageUnregister (&(pScreen->GetScreenPixmap(pScreen)->drawable),
814642e01fSmrg			  pScreenPriv->pDamage);
824642e01fSmrg	damageRegister = 0;
834642e01fSmrg    }
844642e01fSmrg}
854642e01fSmrg
864642e01fSmrgstatic void
874642e01fSmrgmiSpriteEnableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv)
884642e01fSmrg{
894642e01fSmrg    if (!damageRegister) {
904642e01fSmrg	damageRegister = 1;
914642e01fSmrg	DamageRegister (&(pScreen->GetScreenPixmap(pScreen)->drawable),
924642e01fSmrg			pScreenPriv->pDamage);
934642e01fSmrg    }
944642e01fSmrg}
954642e01fSmrg
964642e01fSmrgstatic void
974642e01fSmrgmiSpriteIsUp(miCursorInfoPtr pDevCursor)
984642e01fSmrg{
994642e01fSmrg    pDevCursor->isUp = TRUE;
1004642e01fSmrg}
1014642e01fSmrg
1024642e01fSmrgstatic void
1034642e01fSmrgmiSpriteIsDown(miCursorInfoPtr pDevCursor)
1044642e01fSmrg{
1054642e01fSmrg    pDevCursor->isUp = FALSE;
1064642e01fSmrg}
1074642e01fSmrg
10805b261ecSmrg/*
10905b261ecSmrg * screen wrappers
11005b261ecSmrg */
11105b261ecSmrg
1124642e01fSmrgstatic int miSpriteScreenKeyIndex;
1134642e01fSmrgstatic DevPrivateKey miSpriteScreenKey = &miSpriteScreenKeyIndex;
1144642e01fSmrgstatic int mmiSpriteDevPrivatesKeyIndex;
1154642e01fSmrgstatic DevPrivateKey miSpriteDevPrivatesKey = &mmiSpriteDevPrivatesKeyIndex;
11605b261ecSmrg
11705b261ecSmrgstatic Bool	    miSpriteCloseScreen(int i, ScreenPtr pScreen);
11805b261ecSmrgstatic void	    miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy,
11905b261ecSmrg				     int w, int h, unsigned int format,
12005b261ecSmrg				     unsigned long planemask, char *pdstLine);
12105b261ecSmrgstatic void	    miSpriteGetSpans(DrawablePtr pDrawable, int wMax,
12205b261ecSmrg				     DDXPointPtr ppt, int *pwidth, int nspans,
12305b261ecSmrg				     char *pdstStart);
12405b261ecSmrgstatic void	    miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y,
12505b261ecSmrg					   int width, int height);
12605b261ecSmrgstatic void	    miSpriteCopyWindow (WindowPtr pWindow,
12705b261ecSmrg					DDXPointRec ptOldOrg,
12805b261ecSmrg					RegionPtr prgnSrc);
12905b261ecSmrgstatic void	    miSpriteBlockHandler(int i, pointer blockData,
13005b261ecSmrg					 pointer pTimeout,
13105b261ecSmrg					 pointer pReadMask);
13205b261ecSmrgstatic void	    miSpriteInstallColormap(ColormapPtr pMap);
13305b261ecSmrgstatic void	    miSpriteStoreColors(ColormapPtr pMap, int ndef,
13405b261ecSmrg					xColorItem *pdef);
13505b261ecSmrg
1364642e01fSmrgstatic void	    miSpriteComputeSaved(DeviceIntPtr pDev,
1374642e01fSmrg                                         ScreenPtr pScreen);
13805b261ecSmrg
1394642e01fSmrgstatic Bool         miSpriteDeviceCursorInitialize(DeviceIntPtr pDev,
1404642e01fSmrg                                                   ScreenPtr pScreen);
1414642e01fSmrgstatic void         miSpriteDeviceCursorCleanup(DeviceIntPtr pDev,
1424642e01fSmrg                                                ScreenPtr pScreen);
14305b261ecSmrg
1444642e01fSmrg#define SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = \
1454642e01fSmrg   ((miSpriteScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, \
1464642e01fSmrg					miSpriteScreenKey))->field)
14705b261ecSmrg#define SCREEN_EPILOGUE(pScreen, field)\
14805b261ecSmrg    ((pScreen)->field = miSprite##field)
14905b261ecSmrg
15005b261ecSmrg/*
15105b261ecSmrg * pointer-sprite method table
15205b261ecSmrg */
15305b261ecSmrg
1544642e01fSmrgstatic Bool miSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
1554642e01fSmrg                                  CursorPtr pCursor);
1564642e01fSmrgstatic Bool miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
1574642e01fSmrg                                    CursorPtr pCursor);
1584642e01fSmrgstatic void miSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
1594642e01fSmrg                              CursorPtr pCursor, int x, int y);
1604642e01fSmrgstatic void miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
1614642e01fSmrg                               int x, int y);
16205b261ecSmrg
16305b261ecSmrg_X_EXPORT miPointerSpriteFuncRec miSpritePointerFuncs = {
16405b261ecSmrg    miSpriteRealizeCursor,
16505b261ecSmrg    miSpriteUnrealizeCursor,
16605b261ecSmrg    miSpriteSetCursor,
16705b261ecSmrg    miSpriteMoveCursor,
1684642e01fSmrg    miSpriteDeviceCursorInitialize,
1694642e01fSmrg    miSpriteDeviceCursorCleanup,
17005b261ecSmrg};
17105b261ecSmrg
17205b261ecSmrg/*
17305b261ecSmrg * other misc functions
17405b261ecSmrg */
17505b261ecSmrg
1764642e01fSmrgstatic void miSpriteRemoveCursor(DeviceIntPtr pDev,
1774642e01fSmrg                                 ScreenPtr pScreen);
1784642e01fSmrgstatic void miSpriteSaveUnderCursor(DeviceIntPtr pDev,
1794642e01fSmrg                                 ScreenPtr pScreen);
1804642e01fSmrgstatic void miSpriteRestoreCursor(DeviceIntPtr pDev,
1814642e01fSmrg                                 ScreenPtr pScreen);
18205b261ecSmrg
18305b261ecSmrgstatic void
18405b261ecSmrgmiSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
18505b261ecSmrg{
18605b261ecSmrg    ScreenPtr		    pScreen = closure;
18705b261ecSmrg    miSpriteScreenPtr	    pScreenPriv;
1884642e01fSmrg    miCursorInfoPtr         pCursorInfo;
1894642e01fSmrg    DeviceIntPtr            pDev;
1904642e01fSmrg
1914642e01fSmrg    pScreenPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
1924642e01fSmrg						      miSpriteScreenKey);
1934642e01fSmrg
1944642e01fSmrg    for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
19505b261ecSmrg    {
1964642e01fSmrg        if (DevHasCursor(pDev))
1974642e01fSmrg        {
1984642e01fSmrg            pCursorInfo = MISPRITE(pDev);
1994642e01fSmrg
2004642e01fSmrg            if (pCursorInfo->isUp &&
2014642e01fSmrg                pCursorInfo->pScreen == pScreen &&
2024642e01fSmrg                RECT_IN_REGION (pScreen, pRegion, &pCursorInfo->saved)
2034642e01fSmrg                         != rgnOUT)
2044642e01fSmrg            {
2054642e01fSmrg                SPRITE_DEBUG(("Damage remove\n"));
2064642e01fSmrg                miSpriteRemoveCursor (pDev, pScreen);
2074642e01fSmrg            }
2084642e01fSmrg        }
20905b261ecSmrg    }
21005b261ecSmrg}
21105b261ecSmrg
21205b261ecSmrg/*
21305b261ecSmrg * miSpriteInitialize -- called from device-dependent screen
21405b261ecSmrg * initialization proc after all of the function pointers have
21505b261ecSmrg * been stored in the screen structure.
21605b261ecSmrg */
21705b261ecSmrg
21805b261ecSmrgBool
2194642e01fSmrgmiSpriteInitialize (ScreenPtr               pScreen,
2204642e01fSmrg                    miSpriteCursorFuncPtr   cursorFuncs,
2214642e01fSmrg                    miPointerScreenFuncPtr  screenFuncs)
22205b261ecSmrg{
22305b261ecSmrg    miSpriteScreenPtr	pScreenPriv;
22405b261ecSmrg    VisualPtr		pVisual;
2254642e01fSmrg
22605b261ecSmrg    if (!DamageSetup (pScreen))
22705b261ecSmrg	return FALSE;
22805b261ecSmrg
22905b261ecSmrg    pScreenPriv = (miSpriteScreenPtr) xalloc (sizeof (miSpriteScreenRec));
23005b261ecSmrg    if (!pScreenPriv)
23105b261ecSmrg	return FALSE;
2324642e01fSmrg
23305b261ecSmrg    pScreenPriv->pDamage = DamageCreate (miSpriteReportDamage,
23405b261ecSmrg					 (DamageDestroyFunc) 0,
23505b261ecSmrg					 DamageReportRawRegion,
23605b261ecSmrg					 TRUE,
23705b261ecSmrg					 pScreen,
23805b261ecSmrg					 (void *) pScreen);
23905b261ecSmrg
24005b261ecSmrg    if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE))
24105b261ecSmrg    {
24205b261ecSmrg	xfree ((pointer) pScreenPriv);
24305b261ecSmrg	return FALSE;
24405b261ecSmrg    }
24505b261ecSmrg    for (pVisual = pScreen->visuals;
24605b261ecSmrg	 pVisual->vid != pScreen->rootVisual;
24705b261ecSmrg	 pVisual++)
24805b261ecSmrg	;
24905b261ecSmrg    pScreenPriv->pVisual = pVisual;
25005b261ecSmrg    pScreenPriv->CloseScreen = pScreen->CloseScreen;
25105b261ecSmrg    pScreenPriv->GetImage = pScreen->GetImage;
25205b261ecSmrg    pScreenPriv->GetSpans = pScreen->GetSpans;
25305b261ecSmrg    pScreenPriv->SourceValidate = pScreen->SourceValidate;
25405b261ecSmrg
25505b261ecSmrg    pScreenPriv->CopyWindow = pScreen->CopyWindow;
2564642e01fSmrg
25705b261ecSmrg    pScreenPriv->InstallColormap = pScreen->InstallColormap;
25805b261ecSmrg    pScreenPriv->StoreColors = pScreen->StoreColors;
2594642e01fSmrg
26005b261ecSmrg    pScreenPriv->BlockHandler = pScreen->BlockHandler;
2614642e01fSmrg
2624642e01fSmrg    pScreenPriv->DeviceCursorInitialize = pScreen->DeviceCursorInitialize;
2634642e01fSmrg    pScreenPriv->DeviceCursorCleanup = pScreen->DeviceCursorCleanup;
2644642e01fSmrg
26505b261ecSmrg    pScreenPriv->pInstalledMap = NULL;
26605b261ecSmrg    pScreenPriv->pColormap = NULL;
26705b261ecSmrg    pScreenPriv->funcs = cursorFuncs;
26805b261ecSmrg    pScreenPriv->colors[SOURCE_COLOR].red = 0;
26905b261ecSmrg    pScreenPriv->colors[SOURCE_COLOR].green = 0;
27005b261ecSmrg    pScreenPriv->colors[SOURCE_COLOR].blue = 0;
27105b261ecSmrg    pScreenPriv->colors[MASK_COLOR].red = 0;
27205b261ecSmrg    pScreenPriv->colors[MASK_COLOR].green = 0;
27305b261ecSmrg    pScreenPriv->colors[MASK_COLOR].blue = 0;
2744642e01fSmrg    dixSetPrivate(&pScreen->devPrivates, miSpriteScreenKey, pScreenPriv);
2754642e01fSmrg
27605b261ecSmrg    pScreen->CloseScreen = miSpriteCloseScreen;
27705b261ecSmrg    pScreen->GetImage = miSpriteGetImage;
27805b261ecSmrg    pScreen->GetSpans = miSpriteGetSpans;
27905b261ecSmrg    pScreen->SourceValidate = miSpriteSourceValidate;
2804642e01fSmrg
28105b261ecSmrg    pScreen->CopyWindow = miSpriteCopyWindow;
28205b261ecSmrg    pScreen->InstallColormap = miSpriteInstallColormap;
28305b261ecSmrg    pScreen->StoreColors = miSpriteStoreColors;
28405b261ecSmrg
28505b261ecSmrg    pScreen->BlockHandler = miSpriteBlockHandler;
2864642e01fSmrg
2874642e01fSmrg    damageRegister = 0;
2884642e01fSmrg
28905b261ecSmrg    return TRUE;
29005b261ecSmrg}
29105b261ecSmrg
29205b261ecSmrg/*
29305b261ecSmrg * Screen wrappers
29405b261ecSmrg */
29505b261ecSmrg
29605b261ecSmrg/*
29705b261ecSmrg * CloseScreen wrapper -- unwrap everything, free the private data
29805b261ecSmrg * and call the wrapped function
29905b261ecSmrg */
30005b261ecSmrg
30105b261ecSmrgstatic Bool
3024642e01fSmrgmiSpriteCloseScreen (int i, ScreenPtr pScreen)
30305b261ecSmrg{
30405b261ecSmrg    miSpriteScreenPtr   pScreenPriv;
30505b261ecSmrg
3064642e01fSmrg    pScreenPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
3074642e01fSmrg						      miSpriteScreenKey);
30805b261ecSmrg    pScreen->CloseScreen = pScreenPriv->CloseScreen;
30905b261ecSmrg    pScreen->GetImage = pScreenPriv->GetImage;
31005b261ecSmrg    pScreen->GetSpans = pScreenPriv->GetSpans;
31105b261ecSmrg    pScreen->SourceValidate = pScreenPriv->SourceValidate;
31205b261ecSmrg    pScreen->BlockHandler = pScreenPriv->BlockHandler;
31305b261ecSmrg    pScreen->InstallColormap = pScreenPriv->InstallColormap;
31405b261ecSmrg    pScreen->StoreColors = pScreenPriv->StoreColors;
31505b261ecSmrg
31605b261ecSmrg    DamageDestroy (pScreenPriv->pDamage);
3174642e01fSmrg
31805b261ecSmrg    xfree ((pointer) pScreenPriv);
31905b261ecSmrg
32005b261ecSmrg    return (*pScreen->CloseScreen) (i, pScreen);
32105b261ecSmrg}
32205b261ecSmrg
32305b261ecSmrgstatic void
3244642e01fSmrgmiSpriteGetImage (DrawablePtr pDrawable, int sx, int sy, int w, int h,
3254642e01fSmrg                  unsigned int format, unsigned long planemask,
3264642e01fSmrg                  char *pdstLine)
32705b261ecSmrg{
32805b261ecSmrg    ScreenPtr	    pScreen = pDrawable->pScreen;
32905b261ecSmrg    miSpriteScreenPtr    pScreenPriv;
3304642e01fSmrg    DeviceIntPtr    pDev = inputInfo.pointer;
3314642e01fSmrg    miCursorInfoPtr pCursorInfo;
33205b261ecSmrg
3334642e01fSmrg    SCREEN_PROLOGUE (pScreen, GetImage);
33405b261ecSmrg
3354642e01fSmrg    pScreenPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
3364642e01fSmrg						      miSpriteScreenKey);
3374642e01fSmrg    for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
33805b261ecSmrg    {
3394642e01fSmrg        if (DevHasCursor(pDev))
3404642e01fSmrg        {
3414642e01fSmrg             pCursorInfo = MISPRITE(pDev);
3424642e01fSmrg             if (pDrawable->type == DRAWABLE_WINDOW &&
3434642e01fSmrg                     pCursorInfo->isUp &&
3444642e01fSmrg                     pCursorInfo->pScreen == pScreen &&
3454642e01fSmrg                     ORG_OVERLAP(&pCursorInfo->saved,pDrawable->x,pDrawable->y,
3464642e01fSmrg                         sx, sy, w, h))
3474642e01fSmrg             {
3484642e01fSmrg                 SPRITE_DEBUG (("GetImage remove\n"));
3494642e01fSmrg                 miSpriteRemoveCursor (pDev, pScreen);
3504642e01fSmrg             }
3514642e01fSmrg        }
35205b261ecSmrg    }
35305b261ecSmrg
35405b261ecSmrg    (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
35505b261ecSmrg			  format, planemask, pdstLine);
35605b261ecSmrg
35705b261ecSmrg    SCREEN_EPILOGUE (pScreen, GetImage);
35805b261ecSmrg}
35905b261ecSmrg
36005b261ecSmrgstatic void
3614642e01fSmrgmiSpriteGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
3624642e01fSmrg                  int *pwidth, int nspans, char *pdstStart)
36305b261ecSmrg{
36405b261ecSmrg    ScreenPtr		    pScreen = pDrawable->pScreen;
36505b261ecSmrg    miSpriteScreenPtr	    pScreenPriv;
3664642e01fSmrg    DeviceIntPtr            pDev = inputInfo.pointer;
3674642e01fSmrg    miCursorInfoPtr         pCursorInfo;
3684642e01fSmrg
36905b261ecSmrg    SCREEN_PROLOGUE (pScreen, GetSpans);
37005b261ecSmrg
3714642e01fSmrg    pScreenPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
3724642e01fSmrg						      miSpriteScreenKey);
37305b261ecSmrg
3744642e01fSmrg    for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
37505b261ecSmrg    {
3764642e01fSmrg        if (DevHasCursor(pDev))
3774642e01fSmrg        {
3784642e01fSmrg            pCursorInfo = MISPRITE(pDev);
3794642e01fSmrg
3804642e01fSmrg            if (pDrawable->type == DRAWABLE_WINDOW &&
3814642e01fSmrg                    pCursorInfo->isUp &&
3824642e01fSmrg                    pCursorInfo->pScreen == pScreen)
3834642e01fSmrg            {
3844642e01fSmrg                DDXPointPtr    pts;
3854642e01fSmrg                int    	       *widths;
3864642e01fSmrg                int    	       nPts;
3874642e01fSmrg                int    	       xorg,
3884642e01fSmrg                               yorg;
3894642e01fSmrg
3904642e01fSmrg                xorg = pDrawable->x;
3914642e01fSmrg                yorg = pDrawable->y;
3924642e01fSmrg
3934642e01fSmrg                for (pts = ppt, widths = pwidth, nPts = nspans;
3944642e01fSmrg                        nPts--;
3954642e01fSmrg                        pts++, widths++)
3964642e01fSmrg                {
3974642e01fSmrg                    if (SPN_OVERLAP(&pCursorInfo->saved,pts->y+yorg,
3984642e01fSmrg                                pts->x+xorg,*widths))
3994642e01fSmrg                    {
4004642e01fSmrg                        SPRITE_DEBUG (("GetSpans remove\n"));
4014642e01fSmrg                        miSpriteRemoveCursor (pDev, pScreen);
4024642e01fSmrg                        break;
4034642e01fSmrg                    }
4044642e01fSmrg                }
4054642e01fSmrg            }
4064642e01fSmrg        }
40705b261ecSmrg    }
40805b261ecSmrg
40905b261ecSmrg    (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
41005b261ecSmrg
41105b261ecSmrg    SCREEN_EPILOGUE (pScreen, GetSpans);
41205b261ecSmrg}
41305b261ecSmrg
41405b261ecSmrgstatic void
4154642e01fSmrgmiSpriteSourceValidate (DrawablePtr pDrawable, int x, int y, int width,
4164642e01fSmrg                        int height)
41705b261ecSmrg{
41805b261ecSmrg    ScreenPtr		    pScreen = pDrawable->pScreen;
41905b261ecSmrg    miSpriteScreenPtr	    pScreenPriv;
4204642e01fSmrg    DeviceIntPtr            pDev = inputInfo.pointer;
4214642e01fSmrg    miCursorInfoPtr         pCursorInfo;
4224642e01fSmrg
42305b261ecSmrg    SCREEN_PROLOGUE (pScreen, SourceValidate);
42405b261ecSmrg
4254642e01fSmrg    pScreenPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
4264642e01fSmrg						      miSpriteScreenKey);
42705b261ecSmrg
4284642e01fSmrg    for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
42905b261ecSmrg    {
4304642e01fSmrg        if (DevHasCursor(pDev))
4314642e01fSmrg        {
4324642e01fSmrg            pCursorInfo = MISPRITE(pDev);
4334642e01fSmrg            if (pDrawable->type == DRAWABLE_WINDOW && pCursorInfo->isUp &&
4344642e01fSmrg                    pCursorInfo->pScreen == pScreen &&
4354642e01fSmrg                    ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y,
4364642e01fSmrg                        x, y, width, height))
4374642e01fSmrg            {
4384642e01fSmrg                SPRITE_DEBUG (("SourceValidate remove\n"));
4394642e01fSmrg                miSpriteRemoveCursor (pDev, pScreen);
4404642e01fSmrg            }
4414642e01fSmrg        }
44205b261ecSmrg    }
44305b261ecSmrg
44405b261ecSmrg    if (pScreen->SourceValidate)
44505b261ecSmrg	(*pScreen->SourceValidate) (pDrawable, x, y, width, height);
44605b261ecSmrg
44705b261ecSmrg    SCREEN_EPILOGUE (pScreen, SourceValidate);
44805b261ecSmrg}
44905b261ecSmrg
45005b261ecSmrgstatic void
45105b261ecSmrgmiSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
45205b261ecSmrg{
45305b261ecSmrg    ScreenPtr	pScreen = pWindow->drawable.pScreen;
45405b261ecSmrg    miSpriteScreenPtr	    pScreenPriv;
4554642e01fSmrg    DeviceIntPtr            pDev = inputInfo.pointer;
4564642e01fSmrg    miCursorInfoPtr         pCursorInfo;
4574642e01fSmrg
45805b261ecSmrg    SCREEN_PROLOGUE (pScreen, CopyWindow);
45905b261ecSmrg
4604642e01fSmrg    pScreenPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
4614642e01fSmrg						      miSpriteScreenKey);
4624642e01fSmrg
4634642e01fSmrg    for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
46405b261ecSmrg    {
4654642e01fSmrg        if (DevHasCursor(pDev))
4664642e01fSmrg        {
4674642e01fSmrg            pCursorInfo = MISPRITE(pDev);
4684642e01fSmrg            /*
4694642e01fSmrg             * Damage will take care of destination check
4704642e01fSmrg             */
4714642e01fSmrg            if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen &&
4724642e01fSmrg                    RECT_IN_REGION (pScreen, prgnSrc, &pCursorInfo->saved) != rgnOUT)
4734642e01fSmrg            {
4744642e01fSmrg                SPRITE_DEBUG (("CopyWindow remove\n"));
4754642e01fSmrg                miSpriteRemoveCursor (pDev, pScreen);
4764642e01fSmrg            }
4774642e01fSmrg        }
47805b261ecSmrg    }
47905b261ecSmrg
48005b261ecSmrg    (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
48105b261ecSmrg    SCREEN_EPILOGUE (pScreen, CopyWindow);
48205b261ecSmrg}
48305b261ecSmrg
48405b261ecSmrgstatic void
4854642e01fSmrgmiSpriteBlockHandler (int i, pointer blockData, pointer pTimeout,
4864642e01fSmrg                      pointer pReadmask)
48705b261ecSmrg{
48805b261ecSmrg    ScreenPtr		pScreen = screenInfo.screens[i];
48905b261ecSmrg    miSpriteScreenPtr	pPriv;
4904642e01fSmrg    DeviceIntPtr            pDev = inputInfo.pointer;
4914642e01fSmrg    miCursorInfoPtr         pCursorInfo;
49205b261ecSmrg
4934642e01fSmrg    pPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
4944642e01fSmrg						miSpriteScreenKey);
49505b261ecSmrg    SCREEN_PROLOGUE(pScreen, BlockHandler);
4964642e01fSmrg
49705b261ecSmrg    (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
49805b261ecSmrg
49905b261ecSmrg    SCREEN_EPILOGUE(pScreen, BlockHandler);
50005b261ecSmrg
5014642e01fSmrg    for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
5024642e01fSmrg    {
5034642e01fSmrg        if (DevHasCursor(pDev))
5044642e01fSmrg        {
5054642e01fSmrg            pCursorInfo = MISPRITE(pDev);
5064642e01fSmrg            if (pCursorInfo && !pCursorInfo->isUp
5074642e01fSmrg                    && pCursorInfo->pScreen == pScreen
5084642e01fSmrg                    && pCursorInfo->shouldBeUp)
5094642e01fSmrg            {
5104642e01fSmrg                SPRITE_DEBUG (("BlockHandler restore\n"));
5114642e01fSmrg                miSpriteSaveUnderCursor (pDev, pScreen);
5124642e01fSmrg            }
5134642e01fSmrg        }
5144642e01fSmrg    }
5154642e01fSmrg    for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
51605b261ecSmrg    {
5174642e01fSmrg        if (DevHasCursor(pDev))
5184642e01fSmrg        {
5194642e01fSmrg            pCursorInfo = MISPRITE(pDev);
5204642e01fSmrg            if (pCursorInfo && !pCursorInfo->isUp &&
5214642e01fSmrg                    pCursorInfo->pScreen == pScreen &&
5224642e01fSmrg                    pCursorInfo->shouldBeUp)
5234642e01fSmrg            {
5244642e01fSmrg                SPRITE_DEBUG (("BlockHandler restore\n"));
5254642e01fSmrg                miSpriteRestoreCursor (pDev, pScreen);
5264642e01fSmrg            }
5274642e01fSmrg        }
52805b261ecSmrg    }
52905b261ecSmrg}
53005b261ecSmrg
53105b261ecSmrgstatic void
5324642e01fSmrgmiSpriteInstallColormap (ColormapPtr pMap)
53305b261ecSmrg{
53405b261ecSmrg    ScreenPtr		pScreen = pMap->pScreen;
53505b261ecSmrg    miSpriteScreenPtr	pPriv;
53605b261ecSmrg
5374642e01fSmrg    pPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
5384642e01fSmrg						miSpriteScreenKey);
53905b261ecSmrg    SCREEN_PROLOGUE(pScreen, InstallColormap);
5404642e01fSmrg
54105b261ecSmrg    (*pScreen->InstallColormap) (pMap);
54205b261ecSmrg
54305b261ecSmrg    SCREEN_EPILOGUE(pScreen, InstallColormap);
54405b261ecSmrg
5454642e01fSmrg    /* InstallColormap can be called before devices are initialized. */
54605b261ecSmrg    pPriv->pInstalledMap = pMap;
54705b261ecSmrg    if (pPriv->pColormap != pMap)
54805b261ecSmrg    {
5494642e01fSmrg        DeviceIntPtr pDev;
5504642e01fSmrg        miCursorInfoPtr     pCursorInfo;
5514642e01fSmrg        for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
5524642e01fSmrg        {
5534642e01fSmrg            if (DevHasCursor(pDev))
5544642e01fSmrg            {
5554642e01fSmrg                pCursorInfo = MISPRITE(pDev);
5564642e01fSmrg                pCursorInfo->checkPixels = TRUE;
5574642e01fSmrg                if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
5584642e01fSmrg                    miSpriteRemoveCursor(pDev, pScreen);
5594642e01fSmrg            }
5604642e01fSmrg        }
5614642e01fSmrg
56205b261ecSmrg    }
56305b261ecSmrg}
56405b261ecSmrg
56505b261ecSmrgstatic void
5664642e01fSmrgmiSpriteStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef)
56705b261ecSmrg{
56805b261ecSmrg    ScreenPtr		pScreen = pMap->pScreen;
56905b261ecSmrg    miSpriteScreenPtr	pPriv;
57005b261ecSmrg    int			i;
57105b261ecSmrg    int			updated;
57205b261ecSmrg    VisualPtr		pVisual;
5734642e01fSmrg    DeviceIntPtr        pDev = inputInfo.pointer;
5744642e01fSmrg    miCursorInfoPtr     pCursorInfo;
57505b261ecSmrg
5764642e01fSmrg    pPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
5774642e01fSmrg						miSpriteScreenKey);
57805b261ecSmrg    SCREEN_PROLOGUE(pScreen, StoreColors);
5794642e01fSmrg
58005b261ecSmrg    (*pScreen->StoreColors) (pMap, ndef, pdef);
58105b261ecSmrg
58205b261ecSmrg    SCREEN_EPILOGUE(pScreen, StoreColors);
58305b261ecSmrg
58405b261ecSmrg    if (pPriv->pColormap == pMap)
58505b261ecSmrg    {
5864642e01fSmrg        updated = 0;
5874642e01fSmrg        pVisual = pMap->pVisual;
5884642e01fSmrg        if (pVisual->class == DirectColor)
5894642e01fSmrg        {
5904642e01fSmrg            /* Direct color - match on any of the subfields */
59105b261ecSmrg
59205b261ecSmrg#define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask)))
59305b261ecSmrg
5944642e01fSmrg#define UpdateDAC(dev, plane,dac,mask) {\
5954642e01fSmrg    if (MaskMatch (dev->colors[plane].pixel,pdef[i].pixel,mask)) {\
5964642e01fSmrg	dev->colors[plane].dac = pdef[i].dac; \
59705b261ecSmrg	updated = 1; \
59805b261ecSmrg    } \
59905b261ecSmrg}
60005b261ecSmrg
6014642e01fSmrg#define CheckDirect(dev, plane) \
6024642e01fSmrg	    UpdateDAC(dev, plane,red,redMask) \
6034642e01fSmrg	    UpdateDAC(dev, plane,green,greenMask) \
6044642e01fSmrg	    UpdateDAC(dev, plane,blue,blueMask)
6054642e01fSmrg
6064642e01fSmrg            for (i = 0; i < ndef; i++)
6074642e01fSmrg            {
6084642e01fSmrg                CheckDirect (pPriv, SOURCE_COLOR)
6094642e01fSmrg                CheckDirect (pPriv, MASK_COLOR)
6104642e01fSmrg            }
6114642e01fSmrg        }
6124642e01fSmrg        else
6134642e01fSmrg        {
6144642e01fSmrg            /* PseudoColor/GrayScale - match on exact pixel */
6154642e01fSmrg            for (i = 0; i < ndef; i++)
6164642e01fSmrg            {
6174642e01fSmrg                if (pdef[i].pixel ==
6184642e01fSmrg                        pPriv->colors[SOURCE_COLOR].pixel)
6194642e01fSmrg                {
6204642e01fSmrg                    pPriv->colors[SOURCE_COLOR] = pdef[i];
6214642e01fSmrg                    if (++updated == 2)
6224642e01fSmrg                        break;
6234642e01fSmrg                }
6244642e01fSmrg                if (pdef[i].pixel ==
6254642e01fSmrg                        pPriv->colors[MASK_COLOR].pixel)
6264642e01fSmrg                {
6274642e01fSmrg                    pPriv->colors[MASK_COLOR] = pdef[i];
6284642e01fSmrg                    if (++updated == 2)
6294642e01fSmrg                        break;
6304642e01fSmrg                }
6314642e01fSmrg            }
6324642e01fSmrg        }
6334642e01fSmrg        if (updated)
6344642e01fSmrg        {
6354642e01fSmrg            for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
6364642e01fSmrg            {
6374642e01fSmrg                if (DevHasCursor(pDev))
6384642e01fSmrg                {
6394642e01fSmrg                    pCursorInfo = MISPRITE(pDev);
6404642e01fSmrg                    pCursorInfo->checkPixels = TRUE;
6414642e01fSmrg                    if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
6424642e01fSmrg                        miSpriteRemoveCursor (pDev, pScreen);
6434642e01fSmrg                }
6444642e01fSmrg            }
6454642e01fSmrg        }
64605b261ecSmrg    }
64705b261ecSmrg}
64805b261ecSmrg
64905b261ecSmrgstatic void
6504642e01fSmrgmiSpriteFindColors (miCursorInfoPtr pDevCursor, ScreenPtr pScreen)
65105b261ecSmrg{
6524642e01fSmrg    miSpriteScreenPtr   pScreenPriv = (miSpriteScreenPtr)
6534642e01fSmrg	dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey);
65405b261ecSmrg    CursorPtr		pCursor;
65505b261ecSmrg    xColorItem		*sourceColor, *maskColor;
65605b261ecSmrg
6574642e01fSmrg    pCursor = pDevCursor->pCursor;
65805b261ecSmrg    sourceColor = &pScreenPriv->colors[SOURCE_COLOR];
65905b261ecSmrg    maskColor = &pScreenPriv->colors[MASK_COLOR];
66005b261ecSmrg    if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap ||
66105b261ecSmrg	!(pCursor->foreRed == sourceColor->red &&
66205b261ecSmrg	  pCursor->foreGreen == sourceColor->green &&
66305b261ecSmrg          pCursor->foreBlue == sourceColor->blue &&
66405b261ecSmrg	  pCursor->backRed == maskColor->red &&
66505b261ecSmrg	  pCursor->backGreen == maskColor->green &&
66605b261ecSmrg	  pCursor->backBlue == maskColor->blue))
66705b261ecSmrg    {
66805b261ecSmrg	pScreenPriv->pColormap = pScreenPriv->pInstalledMap;
66905b261ecSmrg	sourceColor->red = pCursor->foreRed;
67005b261ecSmrg	sourceColor->green = pCursor->foreGreen;
67105b261ecSmrg	sourceColor->blue = pCursor->foreBlue;
67205b261ecSmrg	FakeAllocColor (pScreenPriv->pColormap, sourceColor);
67305b261ecSmrg	maskColor->red = pCursor->backRed;
67405b261ecSmrg	maskColor->green = pCursor->backGreen;
67505b261ecSmrg	maskColor->blue = pCursor->backBlue;
67605b261ecSmrg	FakeAllocColor (pScreenPriv->pColormap, maskColor);
67705b261ecSmrg	/* "free" the pixels right away, don't let this confuse you */
67805b261ecSmrg	FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel);
67905b261ecSmrg	FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel);
68005b261ecSmrg    }
68105b261ecSmrg
6824642e01fSmrg    pDevCursor->checkPixels = FALSE;
68305b261ecSmrg
68405b261ecSmrg}
68505b261ecSmrg
68605b261ecSmrg/*
68705b261ecSmrg * miPointer interface routines
68805b261ecSmrg */
68905b261ecSmrg
69005b261ecSmrg#define SPRITE_PAD  8
69105b261ecSmrg
69205b261ecSmrgstatic Bool
6934642e01fSmrgmiSpriteRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
69405b261ecSmrg{
69505b261ecSmrg    miSpriteScreenPtr	pScreenPriv;
6964642e01fSmrg    miCursorInfoPtr pCursorInfo;
6974642e01fSmrg
6984642e01fSmrg    pScreenPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
6994642e01fSmrg						      miSpriteScreenKey);
7004642e01fSmrg    if (!pDev->isMaster && !pDev->u.master)
7014642e01fSmrg    {
7024642e01fSmrg        ErrorF("[mi] miSpriteRealizeCursor called for floating device.\n");
7034642e01fSmrg        return FALSE;
7044642e01fSmrg    }
7054642e01fSmrg    pCursorInfo = MISPRITE(pDev);
7064642e01fSmrg
7074642e01fSmrg    if (pCursor == pCursorInfo->pCursor)
7084642e01fSmrg	pCursorInfo->checkPixels = TRUE;
70905b261ecSmrg
71005b261ecSmrg    return (*pScreenPriv->funcs->RealizeCursor) (pScreen, pCursor);
71105b261ecSmrg}
71205b261ecSmrg
71305b261ecSmrgstatic Bool
7144642e01fSmrgmiSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
71505b261ecSmrg{
71605b261ecSmrg    miSpriteScreenPtr	pScreenPriv;
71705b261ecSmrg
7184642e01fSmrg    pScreenPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
7194642e01fSmrg						      miSpriteScreenKey);
72005b261ecSmrg    return (*pScreenPriv->funcs->UnrealizeCursor) (pScreen, pCursor);
72105b261ecSmrg}
72205b261ecSmrg
72305b261ecSmrgstatic void
7244642e01fSmrgmiSpriteSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
7254642e01fSmrg                   CursorPtr pCursor, int x, int y)
72605b261ecSmrg{
72705b261ecSmrg    miSpriteScreenPtr	pScreenPriv;
72805b261ecSmrg
7294642e01fSmrg    pScreenPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
7304642e01fSmrg						      miSpriteScreenKey);
7314642e01fSmrg    miCursorInfoPtr pPointer;
7324642e01fSmrg
7334642e01fSmrg    if (!pDev->isMaster && !pDev->u.master)
7344642e01fSmrg    {
7354642e01fSmrg        ErrorF("[mi] miSpriteSetCursor called for floating device.\n");
7364642e01fSmrg        return;
7374642e01fSmrg    }
7384642e01fSmrg    pPointer = MISPRITE(pDev);
7394642e01fSmrg
74005b261ecSmrg    if (!pCursor)
74105b261ecSmrg    {
7424642e01fSmrg    	pPointer->shouldBeUp = FALSE;
7434642e01fSmrg    	if (pPointer->isUp)
7444642e01fSmrg	    miSpriteRemoveCursor (pDev, pScreen);
7454642e01fSmrg	pPointer->pCursor = 0;
74605b261ecSmrg	return;
74705b261ecSmrg    }
7484642e01fSmrg    pPointer->shouldBeUp = TRUE;
7494642e01fSmrg    if (pPointer->x == x &&
7504642e01fSmrg	pPointer->y == y &&
7514642e01fSmrg	pPointer->pCursor == pCursor &&
7524642e01fSmrg	!pPointer->checkPixels)
75305b261ecSmrg    {
75405b261ecSmrg	return;
75505b261ecSmrg    }
7564642e01fSmrg    pPointer->x = x;
7574642e01fSmrg    pPointer->y = y;
7584642e01fSmrg    pPointer->pCacheWin = NullWindow;
7594642e01fSmrg    if (pPointer->checkPixels || pPointer->pCursor != pCursor)
76005b261ecSmrg    {
7614642e01fSmrg	pPointer->pCursor = pCursor;
7624642e01fSmrg	miSpriteFindColors (pPointer, pScreen);
76305b261ecSmrg    }
7644642e01fSmrg    if (pPointer->isUp) {
7654642e01fSmrg#if 0
7664642e01fSmrg        /* FIXME: Disabled for MPX, should be rewritten */
76705b261ecSmrg	int	sx, sy;
76805b261ecSmrg	/*
76905b261ecSmrg	 * check to see if the old saved region
77005b261ecSmrg	 * encloses the new sprite, in which case we use
77105b261ecSmrg	 * the flicker-free MoveCursor primitive.
77205b261ecSmrg	 */
7734642e01fSmrg	sx = pointer->x - (int)pCursor->bits->xhot;
7744642e01fSmrg	sy = pointer->y - (int)pCursor->bits->yhot;
7754642e01fSmrg	if (sx + (int) pCursor->bits->width >= pointer->saved.x1 &&
7764642e01fSmrg	    sx < pointer->saved.x2 &&
7774642e01fSmrg	    sy + (int) pCursor->bits->height >= pointer->saved.y1 &&
7784642e01fSmrg	    sy < pointer->saved.y2 &&
77905b261ecSmrg	    (int) pCursor->bits->width + (2 * SPRITE_PAD) ==
7804642e01fSmrg		pointer->saved.x2 - pointer->saved.x1 &&
78105b261ecSmrg	    (int) pCursor->bits->height + (2 * SPRITE_PAD) ==
7824642e01fSmrg		pointer->saved.y2 - pointer->saved.y1
78305b261ecSmrg	    )
78405b261ecSmrg	{
78505b261ecSmrg	    DamageDrawInternal (pScreen, TRUE);
7864642e01fSmrg	    miSpriteIsDown(pCursorInfo);
7874642e01fSmrg	    if (!(sx >= pointer->saved.x1 &&
7884642e01fSmrg                  sx + (int)pCursor->bits->width < pointer->saved.x2
7894642e01fSmrg                  && sy >= pointer->saved.y1 &&
7904642e01fSmrg                  sy + (int)pCursor->bits->height <
7914642e01fSmrg                                pointer->saved.y2))
7924642e01fSmrg            {
79305b261ecSmrg		int oldx1, oldy1, dx, dy;
79405b261ecSmrg
7954642e01fSmrg		oldx1 = pointer->saved.x1;
7964642e01fSmrg		oldy1 = pointer->saved.y1;
79705b261ecSmrg		dx = oldx1 - (sx - SPRITE_PAD);
79805b261ecSmrg		dy = oldy1 - (sy - SPRITE_PAD);
7994642e01fSmrg		pointer->saved.x1 -= dx;
8004642e01fSmrg		pointer->saved.y1 -= dy;
8014642e01fSmrg		pointer->saved.x2 -= dx;
8024642e01fSmrg		pointer->saved.y2 -= dy;
80305b261ecSmrg		(void) (*pScreenPriv->funcs->ChangeSave) (pScreen,
8044642e01fSmrg				pointer->saved.x1,
8054642e01fSmrg 				pointer->saved.y1,
8064642e01fSmrg                                pointer->saved.x2 -
8074642e01fSmrg                                pointer->saved.x1,
8084642e01fSmrg                                pointer->saved.y2 -
8094642e01fSmrg                                pointer->saved.y1,
81005b261ecSmrg				dx, dy);
81105b261ecSmrg	    }
81205b261ecSmrg	    (void) (*pScreenPriv->funcs->MoveCursor) (pScreen, pCursor,
8134642e01fSmrg				  pointer->saved.x1,
8144642e01fSmrg 				  pointer->saved.y1,
8154642e01fSmrg                                  pointer->saved.x2 -
8164642e01fSmrg                                  pointer->saved.x1,
8174642e01fSmrg                                  pointer->saved.y2 -
8184642e01fSmrg                                  pointer->saved.y1,
8194642e01fSmrg				  sx - pointer->saved.x1,
8204642e01fSmrg				  sy - pointer->saved.y1,
8214642e01fSmrg				  pointer->colors[SOURCE_COLOR].pixel,
8224642e01fSmrg				  pointer->colors[MASK_COLOR].pixel);
8234642e01fSmrg	    miSpriteIsUp(pCursorInfo);
82405b261ecSmrg	    DamageDrawInternal (pScreen, FALSE);
82505b261ecSmrg	}
82605b261ecSmrg	else
8274642e01fSmrg#endif
82805b261ecSmrg	{
8294642e01fSmrg	    SPRITE_DEBUG (("SetCursor remove %d\n", pDev->id));
8304642e01fSmrg	    miSpriteRemoveCursor (pDev, pScreen);
83105b261ecSmrg	}
83205b261ecSmrg    }
8334642e01fSmrg
8344642e01fSmrg    if (!pPointer->isUp && pPointer->pCursor)
83505b261ecSmrg    {
8364642e01fSmrg	SPRITE_DEBUG (("SetCursor restore %d\n", pDev->id));
8374642e01fSmrg        miSpriteSaveUnderCursor(pDev, pScreen);
8384642e01fSmrg	miSpriteRestoreCursor (pDev, pScreen);
83905b261ecSmrg    }
8404642e01fSmrg
84105b261ecSmrg}
84205b261ecSmrg
84305b261ecSmrgstatic void
8444642e01fSmrgmiSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
84505b261ecSmrg{
84605b261ecSmrg    miSpriteScreenPtr	pScreenPriv;
8474642e01fSmrg    CursorPtr pCursor;
84805b261ecSmrg
8494642e01fSmrg    pScreenPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
8504642e01fSmrg						      miSpriteScreenKey);
8514642e01fSmrg    if (!pDev->isMaster && !pDev->u.master)
8524642e01fSmrg    {
8534642e01fSmrg        ErrorF("[mi] miSpriteMoveCursor called for floating device.\n");
8544642e01fSmrg        return;
8554642e01fSmrg    }
8564642e01fSmrg    pCursor = MISPRITE(pDev)->pCursor;
8574642e01fSmrg
8584642e01fSmrg    miSpriteSetCursor (pDev, pScreen, pCursor, x, y);
8594642e01fSmrg}
8604642e01fSmrg
8614642e01fSmrg
8624642e01fSmrgstatic Bool
8634642e01fSmrgmiSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
8644642e01fSmrg{
8654642e01fSmrg    miSpriteScreenPtr pScreenPriv;
8664642e01fSmrg    miCursorInfoPtr pCursorInfo;
8674642e01fSmrg    int ret = FALSE;
8684642e01fSmrg
8694642e01fSmrg    pScreenPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
8704642e01fSmrg						      miSpriteScreenKey);
8714642e01fSmrg
8724642e01fSmrg    pCursorInfo = xalloc(sizeof(miCursorInfoRec));
8734642e01fSmrg    if (!pCursorInfo)
8744642e01fSmrg        return FALSE;
8754642e01fSmrg
8764642e01fSmrg    pCursorInfo->pCursor = NULL;
8774642e01fSmrg    pCursorInfo->x = 0;
8784642e01fSmrg    pCursorInfo->y = 0;
8794642e01fSmrg    pCursorInfo->isUp = FALSE;
8804642e01fSmrg    pCursorInfo->shouldBeUp = FALSE;
8814642e01fSmrg    pCursorInfo->pCacheWin = NullWindow;
8824642e01fSmrg    pCursorInfo->isInCacheWin = FALSE;
8834642e01fSmrg    pCursorInfo->checkPixels = TRUE;
8844642e01fSmrg    pCursorInfo->pScreen = FALSE;
8854642e01fSmrg
8864642e01fSmrg    ret = (*pScreenPriv->funcs->DeviceCursorInitialize)(pDev, pScreen);
8874642e01fSmrg    if (!ret)
8884642e01fSmrg    {
8894642e01fSmrg        xfree(pCursorInfo);
8904642e01fSmrg        pCursorInfo = NULL;
8914642e01fSmrg    }
8924642e01fSmrg    dixSetPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey, pCursorInfo);
8934642e01fSmrg    return ret;
8944642e01fSmrg}
8954642e01fSmrg
8964642e01fSmrgstatic void
8974642e01fSmrgmiSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
8984642e01fSmrg{
8994642e01fSmrg    if (DevHasCursor(pDev))
9004642e01fSmrg    {
9014642e01fSmrg        miSpriteScreenPtr pScreenPriv;
9024642e01fSmrg        pScreenPriv = (miSpriteScreenPtr)
9034642e01fSmrg                dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey);
9044642e01fSmrg
9054642e01fSmrg        (*pScreenPriv->funcs->DeviceCursorCleanup)(pDev, pScreen);
9064642e01fSmrg    }
90705b261ecSmrg}
90805b261ecSmrg
90905b261ecSmrg/*
91005b261ecSmrg * undraw/draw cursor
91105b261ecSmrg */
91205b261ecSmrg
91305b261ecSmrgstatic void
9144642e01fSmrgmiSpriteRemoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen)
91505b261ecSmrg{
91605b261ecSmrg    miSpriteScreenPtr   pScreenPriv;
9174642e01fSmrg    miCursorInfoPtr     pCursorInfo;
9184642e01fSmrg
91905b261ecSmrg
9204642e01fSmrg    if (!pDev->isMaster && !pDev->u.master)
9214642e01fSmrg    {
9224642e01fSmrg        ErrorF("[mi] miSpriteRemoveCursor called for floating device.\n");
9234642e01fSmrg        return;
9244642e01fSmrg    }
92505b261ecSmrg    DamageDrawInternal (pScreen, TRUE);
9264642e01fSmrg    pScreenPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
9274642e01fSmrg						      miSpriteScreenKey);
9284642e01fSmrg    pCursorInfo = MISPRITE(pDev);
9294642e01fSmrg
9304642e01fSmrg    miSpriteIsDown(pCursorInfo);
9314642e01fSmrg    pCursorInfo->pCacheWin = NullWindow;
9324642e01fSmrg    miSpriteDisableDamage(pScreen, pScreenPriv);
9334642e01fSmrg    if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pDev,
9344642e01fSmrg                                         pScreen,
9354642e01fSmrg					 pCursorInfo->saved.x1,
9364642e01fSmrg                                         pCursorInfo->saved.y1,
9374642e01fSmrg                                         pCursorInfo->saved.x2 -
9384642e01fSmrg                                         pCursorInfo->saved.x1,
9394642e01fSmrg                                         pCursorInfo->saved.y2 -
9404642e01fSmrg                                         pCursorInfo->saved.y1))
94105b261ecSmrg    {
9424642e01fSmrg	miSpriteIsUp(pCursorInfo);
94305b261ecSmrg    }
9444642e01fSmrg    miSpriteEnableDamage(pScreen, pScreenPriv);
94505b261ecSmrg    DamageDrawInternal (pScreen, FALSE);
94605b261ecSmrg}
94705b261ecSmrg
9484642e01fSmrg/*
9494642e01fSmrg * Called from the block handler, saves area under cursor
9504642e01fSmrg * before waiting for something to do.
9514642e01fSmrg */
9524642e01fSmrg
9534642e01fSmrgstatic void
9544642e01fSmrgmiSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen)
9554642e01fSmrg{
9564642e01fSmrg    miSpriteScreenPtr   pScreenPriv;
9574642e01fSmrg    int			x, y;
9584642e01fSmrg    CursorPtr		pCursor;
9594642e01fSmrg    miCursorInfoPtr     pCursorInfo;
9604642e01fSmrg
9614642e01fSmrg    if (!pDev->isMaster && !pDev->u.master)
9624642e01fSmrg    {
9634642e01fSmrg        ErrorF("[mi] miSpriteSaveUnderCursor called for floating device.\n");
9644642e01fSmrg        return;
9654642e01fSmrg    }
9664642e01fSmrg    DamageDrawInternal (pScreen, TRUE);
9674642e01fSmrg    pScreenPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
9684642e01fSmrg						      miSpriteScreenKey);
9694642e01fSmrg    pCursorInfo = MISPRITE(pDev);
9704642e01fSmrg
9714642e01fSmrg    miSpriteComputeSaved (pDev, pScreen);
9724642e01fSmrg    pCursor = pCursorInfo->pCursor;
9734642e01fSmrg
9744642e01fSmrg    x = pCursorInfo->x - (int)pCursor->bits->xhot;
9754642e01fSmrg    y = pCursorInfo->y - (int)pCursor->bits->yhot;
9764642e01fSmrg    miSpriteDisableDamage(pScreen, pScreenPriv);
9774642e01fSmrg
9784642e01fSmrg    (*pScreenPriv->funcs->SaveUnderCursor) (pDev,
9794642e01fSmrg                                      pScreen,
9804642e01fSmrg				      pCursorInfo->saved.x1,
9814642e01fSmrg				      pCursorInfo->saved.y1,
9824642e01fSmrg                                      pCursorInfo->saved.x2 -
9834642e01fSmrg                                      pCursorInfo->saved.x1,
9844642e01fSmrg                                      pCursorInfo->saved.y2 -
9854642e01fSmrg                                      pCursorInfo->saved.y1);
9864642e01fSmrg    SPRITE_DEBUG(("SaveUnderCursor %d\n", pDev->id));
9874642e01fSmrg    miSpriteEnableDamage(pScreen, pScreenPriv);
9884642e01fSmrg    DamageDrawInternal (pScreen, FALSE);
9894642e01fSmrg}
9904642e01fSmrg
9914642e01fSmrg
99205b261ecSmrg/*
99305b261ecSmrg * Called from the block handler, restores the cursor
99405b261ecSmrg * before waiting for something to do.
99505b261ecSmrg */
99605b261ecSmrg
99705b261ecSmrgstatic void
9984642e01fSmrgmiSpriteRestoreCursor (DeviceIntPtr pDev, ScreenPtr pScreen)
99905b261ecSmrg{
100005b261ecSmrg    miSpriteScreenPtr   pScreenPriv;
100105b261ecSmrg    int			x, y;
100205b261ecSmrg    CursorPtr		pCursor;
10034642e01fSmrg    miCursorInfoPtr     pCursorInfo;
10044642e01fSmrg
10054642e01fSmrg    if (!pDev->isMaster && !pDev->u.master)
10064642e01fSmrg    {
10074642e01fSmrg        ErrorF("[mi] miSpriteRestoreCursor called for floating device.\n");
10084642e01fSmrg        return;
10094642e01fSmrg    }
101005b261ecSmrg
101105b261ecSmrg    DamageDrawInternal (pScreen, TRUE);
10124642e01fSmrg    pScreenPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
10134642e01fSmrg						      miSpriteScreenKey);
10144642e01fSmrg    pCursorInfo = MISPRITE(pDev);
10154642e01fSmrg
10164642e01fSmrg    miSpriteComputeSaved (pDev, pScreen);
10174642e01fSmrg    pCursor = pCursorInfo->pCursor;
10184642e01fSmrg
10194642e01fSmrg    x = pCursorInfo->x - (int)pCursor->bits->xhot;
10204642e01fSmrg    y = pCursorInfo->y - (int)pCursor->bits->yhot;
10214642e01fSmrg    miSpriteDisableDamage(pScreen, pScreenPriv);
10224642e01fSmrg    SPRITE_DEBUG(("RestoreCursor %d\n", pDev->id));
10234642e01fSmrg    if (pCursorInfo->checkPixels)
10244642e01fSmrg        miSpriteFindColors (pCursorInfo, pScreen);
10254642e01fSmrg    if ((*pScreenPriv->funcs->PutUpCursor) (pDev, pScreen,
10264642e01fSmrg                pCursor, x, y,
10274642e01fSmrg                pScreenPriv->colors[SOURCE_COLOR].pixel,
10284642e01fSmrg                pScreenPriv->colors[MASK_COLOR].pixel))
102905b261ecSmrg    {
10304642e01fSmrg        miSpriteIsUp(pCursorInfo);
10314642e01fSmrg        pCursorInfo->pScreen = pScreen;
103205b261ecSmrg    }
10334642e01fSmrg    miSpriteEnableDamage(pScreen, pScreenPriv);
103405b261ecSmrg    DamageDrawInternal (pScreen, FALSE);
103505b261ecSmrg}
103605b261ecSmrg
103705b261ecSmrg/*
103805b261ecSmrg * compute the desired area of the screen to save
103905b261ecSmrg */
104005b261ecSmrg
104105b261ecSmrgstatic void
10424642e01fSmrgmiSpriteComputeSaved (DeviceIntPtr pDev, ScreenPtr pScreen)
104305b261ecSmrg{
104405b261ecSmrg    miSpriteScreenPtr   pScreenPriv;
104505b261ecSmrg    int		    x, y, w, h;
104605b261ecSmrg    int		    wpad, hpad;
104705b261ecSmrg    CursorPtr	    pCursor;
10484642e01fSmrg    miCursorInfoPtr pCursorInfo;
104905b261ecSmrg
10504642e01fSmrg    if (!pDev->isMaster && !pDev->u.master)
10514642e01fSmrg    {
10524642e01fSmrg        ErrorF("[mi] miSpriteComputeSaved called for floating device.\n");
10534642e01fSmrg        return;
10544642e01fSmrg    }
10554642e01fSmrg    pScreenPriv = (miSpriteScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
10564642e01fSmrg						      miSpriteScreenKey);
10574642e01fSmrg    pCursorInfo = MISPRITE(pDev);
10584642e01fSmrg
10594642e01fSmrg    pCursor = pCursorInfo->pCursor;
10604642e01fSmrg    x = pCursorInfo->x - (int)pCursor->bits->xhot;
10614642e01fSmrg    y = pCursorInfo->y - (int)pCursor->bits->yhot;
106205b261ecSmrg    w = pCursor->bits->width;
106305b261ecSmrg    h = pCursor->bits->height;
106405b261ecSmrg    wpad = SPRITE_PAD;
106505b261ecSmrg    hpad = SPRITE_PAD;
10664642e01fSmrg    pCursorInfo->saved.x1 = x - wpad;
10674642e01fSmrg    pCursorInfo->saved.y1 = y - hpad;
10684642e01fSmrg    pCursorInfo->saved.x2 = pCursorInfo->saved.x1 + w + wpad * 2;
10694642e01fSmrg    pCursorInfo->saved.y2 = pCursorInfo->saved.y1 + h + hpad * 2;
107005b261ecSmrg}
10714642e01fSmrg
1072