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