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 366747b715Smrg#include <X11/X.h> 376747b715Smrg#include <X11/Xproto.h> 386747b715Smrg#include "misc.h" 396747b715Smrg#include "pixmapstr.h" 406747b715Smrg#include "input.h" 416747b715Smrg#include "mi.h" 426747b715Smrg#include "cursorstr.h" 436747b715Smrg#include <X11/fonts/font.h> 446747b715Smrg#include "scrnintstr.h" 456747b715Smrg#include "colormapst.h" 466747b715Smrg#include "windowstr.h" 476747b715Smrg#include "gcstruct.h" 486747b715Smrg#include "mipointer.h" 496747b715Smrg#include "misprite.h" 506747b715Smrg#include "dixfontstr.h" 516747b715Smrg#include <X11/fonts/fontstruct.h> 526747b715Smrg#include "inputstr.h" 536747b715Smrg#include "damage.h" 546747b715Smrg 556747b715Smrgtypedef struct { 5635c4bbdfSmrg CursorPtr pCursor; 5735c4bbdfSmrg int x; /* cursor hotspot */ 5835c4bbdfSmrg int y; 5935c4bbdfSmrg BoxRec saved; /* saved area from the screen */ 6035c4bbdfSmrg Bool isUp; /* cursor in frame buffer */ 6135c4bbdfSmrg Bool shouldBeUp; /* cursor should be displayed */ 6235c4bbdfSmrg Bool checkPixels; /* check colormap collision */ 6335c4bbdfSmrg ScreenPtr pScreen; 646747b715Smrg} miCursorInfoRec, *miCursorInfoPtr; 656747b715Smrg 666747b715Smrg/* 676747b715Smrg * per screen information 686747b715Smrg */ 696747b715Smrg 706747b715Smrgtypedef struct { 716747b715Smrg /* screen procedures */ 7235c4bbdfSmrg CloseScreenProcPtr CloseScreen; 7335c4bbdfSmrg SourceValidateProcPtr SourceValidate; 7435c4bbdfSmrg 756747b715Smrg /* window procedures */ 7635c4bbdfSmrg CopyWindowProcPtr CopyWindow; 7735c4bbdfSmrg 786747b715Smrg /* colormap procedures */ 7935c4bbdfSmrg InstallColormapProcPtr InstallColormap; 8035c4bbdfSmrg StoreColorsProcPtr StoreColors; 8135c4bbdfSmrg 826747b715Smrg /* os layer procedures */ 8335c4bbdfSmrg ScreenBlockHandlerProcPtr BlockHandler; 8435c4bbdfSmrg 8535c4bbdfSmrg xColorItem colors[2]; 8635c4bbdfSmrg ColormapPtr pInstalledMap; 8735c4bbdfSmrg ColormapPtr pColormap; 8835c4bbdfSmrg VisualPtr pVisual; 8935c4bbdfSmrg DamagePtr pDamage; /* damage tracking structure */ 9035c4bbdfSmrg Bool damageRegistered; 9135c4bbdfSmrg int numberOfCursors; 926747b715Smrg} miSpriteScreenRec, *miSpriteScreenPtr; 936747b715Smrg 946747b715Smrg#define SOURCE_COLOR 0 956747b715Smrg#define MASK_COLOR 1 966747b715Smrg 976747b715Smrg/* 986747b715Smrg * Overlap BoxPtr and Box elements 996747b715Smrg */ 1006747b715Smrg#define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \ 1016747b715Smrg (((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \ 1026747b715Smrg ((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2)) 1036747b715Smrg 1046747b715Smrg/* 1056747b715Smrg * Overlap BoxPtr, origins, and rectangle 1066747b715Smrg */ 1076747b715Smrg#define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \ 1086747b715Smrg BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h)) 1096747b715Smrg 1106747b715Smrg/* 1116747b715Smrg * Overlap BoxPtr, origins and RectPtr 1126747b715Smrg */ 1136747b715Smrg#define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \ 1146747b715Smrg ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y, \ 1156747b715Smrg (int)((pRect)->width), (int)((pRect)->height)) 1166747b715Smrg/* 1176747b715Smrg * Overlap BoxPtr and horizontal span 1186747b715Smrg */ 1196747b715Smrg#define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y)) 12005b261ecSmrg 1216747b715Smrg#define LINE_SORT(x1,y1,x2,y2) \ 1226747b715Smrg{ int _t; \ 1236747b715Smrg if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \ 1246747b715Smrg if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } } 1256747b715Smrg 1266747b715Smrg#define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \ 1276747b715Smrg BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2)) 1284642e01fSmrg 12905b261ecSmrg#define SPRITE_DEBUG_ENABLE 0 13005b261ecSmrg#if SPRITE_DEBUG_ENABLE 13105b261ecSmrg#define SPRITE_DEBUG(x) ErrorF x 13205b261ecSmrg#else 13305b261ecSmrg#define SPRITE_DEBUG(x) 13405b261ecSmrg#endif 13505b261ecSmrg 1361b5d61b8Smrgstatic DevPrivateKeyRec miSpriteScreenKeyRec; 1371b5d61b8Smrgstatic DevPrivateKeyRec miSpriteDevPrivatesKeyRec; 1381b5d61b8Smrg 1391b5d61b8Smrgstatic miSpriteScreenPtr 1401b5d61b8SmrgGetSpriteScreen(ScreenPtr pScreen) 1411b5d61b8Smrg{ 1421b5d61b8Smrg return dixLookupPrivate(&pScreen->devPrivates, &miSpriteScreenKeyRec); 1431b5d61b8Smrg} 1441b5d61b8Smrg 1451b5d61b8Smrgstatic miCursorInfoPtr 1461b5d61b8SmrgGetSprite(DeviceIntPtr dev) 1471b5d61b8Smrg{ 1481b5d61b8Smrg if (IsFloating(dev)) 1491b5d61b8Smrg return dixLookupPrivate(&dev->devPrivates, &miSpriteDevPrivatesKeyRec); 1501b5d61b8Smrg 1511b5d61b8Smrg return dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, 1521b5d61b8Smrg &miSpriteDevPrivatesKeyRec); 1531b5d61b8Smrg} 1544642e01fSmrg 1554642e01fSmrgstatic void 1564642e01fSmrgmiSpriteDisableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 1574642e01fSmrg{ 1586747b715Smrg if (pScreenPriv->damageRegistered) { 15935c4bbdfSmrg DamageUnregister(pScreenPriv->pDamage); 16035c4bbdfSmrg pScreenPriv->damageRegistered = 0; 1614642e01fSmrg } 1624642e01fSmrg} 1634642e01fSmrg 1644642e01fSmrgstatic void 1654642e01fSmrgmiSpriteEnableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 1664642e01fSmrg{ 1676747b715Smrg if (!pScreenPriv->damageRegistered) { 16835c4bbdfSmrg pScreenPriv->damageRegistered = 1; 16935c4bbdfSmrg DamageRegister(&(pScreen->GetScreenPixmap(pScreen)->drawable), 17035c4bbdfSmrg pScreenPriv->pDamage); 1714642e01fSmrg } 1724642e01fSmrg} 1734642e01fSmrg 1744642e01fSmrgstatic void 1754642e01fSmrgmiSpriteIsUp(miCursorInfoPtr pDevCursor) 1764642e01fSmrg{ 1774642e01fSmrg pDevCursor->isUp = TRUE; 1784642e01fSmrg} 1794642e01fSmrg 1804642e01fSmrgstatic void 1814642e01fSmrgmiSpriteIsDown(miCursorInfoPtr pDevCursor) 1824642e01fSmrg{ 1834642e01fSmrg pDevCursor->isUp = FALSE; 1844642e01fSmrg} 1854642e01fSmrg 18605b261ecSmrg/* 18705b261ecSmrg * screen wrappers 18805b261ecSmrg */ 18905b261ecSmrg 19035c4bbdfSmrgstatic Bool miSpriteCloseScreen(ScreenPtr pScreen); 19135c4bbdfSmrgstatic void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, 19235c4bbdfSmrg int width, int height, 19335c4bbdfSmrg unsigned int subWindowMode); 19435c4bbdfSmrgstatic void miSpriteCopyWindow(WindowPtr pWindow, 19535c4bbdfSmrg DDXPointRec ptOldOrg, RegionPtr prgnSrc); 1961b5d61b8Smrgstatic void miSpriteBlockHandler(ScreenPtr pScreen, void *timeout); 19735c4bbdfSmrgstatic void miSpriteInstallColormap(ColormapPtr pMap); 19835c4bbdfSmrgstatic void miSpriteStoreColors(ColormapPtr pMap, int ndef, xColorItem * pdef); 19935c4bbdfSmrg 20035c4bbdfSmrgstatic void miSpriteComputeSaved(DeviceIntPtr pDev, ScreenPtr pScreen); 20135c4bbdfSmrg 20235c4bbdfSmrgstatic Bool miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, 20335c4bbdfSmrg ScreenPtr pScreen); 20435c4bbdfSmrgstatic void miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen); 20505b261ecSmrg 2069ace9065Smrg#define SCREEN_PROLOGUE(pPriv, pScreen, field) ((pScreen)->field = \ 2079ace9065Smrg (pPriv)->field) 2089ace9065Smrg#define SCREEN_EPILOGUE(pPriv, pScreen, field)\ 2099ace9065Smrg ((pPriv)->field = (pScreen)->field, (pScreen)->field = miSprite##field) 21005b261ecSmrg 21105b261ecSmrg/* 21205b261ecSmrg * pointer-sprite method table 21305b261ecSmrg */ 21405b261ecSmrg 2154642e01fSmrgstatic Bool miSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2164642e01fSmrg CursorPtr pCursor); 2174642e01fSmrgstatic Bool miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2184642e01fSmrg CursorPtr pCursor); 2194642e01fSmrgstatic void miSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2204642e01fSmrg CursorPtr pCursor, int x, int y); 2214642e01fSmrgstatic void miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2224642e01fSmrg int x, int y); 22305b261ecSmrg 2246747b715SmrgmiPointerSpriteFuncRec miSpritePointerFuncs = { 22505b261ecSmrg miSpriteRealizeCursor, 22605b261ecSmrg miSpriteUnrealizeCursor, 22705b261ecSmrg miSpriteSetCursor, 22805b261ecSmrg miSpriteMoveCursor, 2294642e01fSmrg miSpriteDeviceCursorInitialize, 2304642e01fSmrg miSpriteDeviceCursorCleanup, 23105b261ecSmrg}; 23205b261ecSmrg 23305b261ecSmrg/* 23405b261ecSmrg * other misc functions 23505b261ecSmrg */ 23605b261ecSmrg 23735c4bbdfSmrgstatic void miSpriteRemoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen); 23835c4bbdfSmrgstatic void miSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen); 23935c4bbdfSmrgstatic void miSpriteRestoreCursor(DeviceIntPtr pDev, ScreenPtr pScreen); 24005b261ecSmrg 2419ace9065Smrgstatic void 2429ace9065SmrgmiSpriteRegisterBlockHandler(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 2439ace9065Smrg{ 2449ace9065Smrg if (!pScreenPriv->BlockHandler) { 2459ace9065Smrg pScreenPriv->BlockHandler = pScreen->BlockHandler; 2469ace9065Smrg pScreen->BlockHandler = miSpriteBlockHandler; 2479ace9065Smrg } 2489ace9065Smrg} 2499ace9065Smrg 25005b261ecSmrgstatic void 25135c4bbdfSmrgmiSpriteReportDamage(DamagePtr pDamage, RegionPtr pRegion, void *closure) 25205b261ecSmrg{ 25335c4bbdfSmrg ScreenPtr pScreen = closure; 25435c4bbdfSmrg miCursorInfoPtr pCursorInfo; 25535c4bbdfSmrg DeviceIntPtr pDev; 25635c4bbdfSmrg 25735c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 25835c4bbdfSmrg if (DevHasCursor(pDev)) { 2591b5d61b8Smrg pCursorInfo = GetSprite(pDev); 2604642e01fSmrg 2614642e01fSmrg if (pCursorInfo->isUp && 2624642e01fSmrg pCursorInfo->pScreen == pScreen && 26335c4bbdfSmrg RegionContainsRect(pRegion, &pCursorInfo->saved) != rgnOUT) { 2644642e01fSmrg SPRITE_DEBUG(("Damage remove\n")); 26535c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 2664642e01fSmrg } 2674642e01fSmrg } 26805b261ecSmrg } 26905b261ecSmrg} 27005b261ecSmrg 27105b261ecSmrg/* 27205b261ecSmrg * miSpriteInitialize -- called from device-dependent screen 27305b261ecSmrg * initialization proc after all of the function pointers have 27405b261ecSmrg * been stored in the screen structure. 27505b261ecSmrg */ 27605b261ecSmrg 27705b261ecSmrgBool 27835c4bbdfSmrgmiSpriteInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs) 27905b261ecSmrg{ 28035c4bbdfSmrg miSpriteScreenPtr pScreenPriv; 28135c4bbdfSmrg VisualPtr pVisual; 2824642e01fSmrg 28335c4bbdfSmrg if (!DamageSetup(pScreen)) 28435c4bbdfSmrg return FALSE; 28505b261ecSmrg 2866747b715Smrg if (!dixRegisterPrivateKey(&miSpriteScreenKeyRec, PRIVATE_SCREEN, 0)) 28735c4bbdfSmrg return FALSE; 2886747b715Smrg 28935c4bbdfSmrg if (!dixRegisterPrivateKey 29035c4bbdfSmrg (&miSpriteDevPrivatesKeyRec, PRIVATE_DEVICE, sizeof(miCursorInfoRec))) 29135c4bbdfSmrg return FALSE; 2926747b715Smrg 29335c4bbdfSmrg pScreenPriv = malloc(sizeof(miSpriteScreenRec)); 29405b261ecSmrg if (!pScreenPriv) 29535c4bbdfSmrg return FALSE; 29635c4bbdfSmrg 29735c4bbdfSmrg pScreenPriv->pDamage = DamageCreate(miSpriteReportDamage, 29835c4bbdfSmrg NULL, 29935c4bbdfSmrg DamageReportRawRegion, 30035c4bbdfSmrg TRUE, pScreen, pScreen); 30135c4bbdfSmrg 30235c4bbdfSmrg if (!miPointerInitialize(pScreen, &miSpritePointerFuncs, screenFuncs, TRUE)) { 30335c4bbdfSmrg free(pScreenPriv); 30435c4bbdfSmrg return FALSE; 30505b261ecSmrg } 30605b261ecSmrg for (pVisual = pScreen->visuals; 30735c4bbdfSmrg pVisual->vid != pScreen->rootVisual; pVisual++); 30805b261ecSmrg pScreenPriv->pVisual = pVisual; 30905b261ecSmrg pScreenPriv->CloseScreen = pScreen->CloseScreen; 31005b261ecSmrg pScreenPriv->SourceValidate = pScreen->SourceValidate; 31105b261ecSmrg 31205b261ecSmrg pScreenPriv->CopyWindow = pScreen->CopyWindow; 3134642e01fSmrg 31405b261ecSmrg pScreenPriv->InstallColormap = pScreen->InstallColormap; 31505b261ecSmrg pScreenPriv->StoreColors = pScreen->StoreColors; 3164642e01fSmrg 3179ace9065Smrg pScreenPriv->BlockHandler = NULL; 3184642e01fSmrg 31905b261ecSmrg pScreenPriv->pInstalledMap = NULL; 32005b261ecSmrg pScreenPriv->pColormap = NULL; 32105b261ecSmrg pScreenPriv->colors[SOURCE_COLOR].red = 0; 32205b261ecSmrg pScreenPriv->colors[SOURCE_COLOR].green = 0; 32305b261ecSmrg pScreenPriv->colors[SOURCE_COLOR].blue = 0; 32405b261ecSmrg pScreenPriv->colors[MASK_COLOR].red = 0; 32505b261ecSmrg pScreenPriv->colors[MASK_COLOR].green = 0; 32605b261ecSmrg pScreenPriv->colors[MASK_COLOR].blue = 0; 3276747b715Smrg pScreenPriv->damageRegistered = 0; 3289ace9065Smrg pScreenPriv->numberOfCursors = 0; 3296747b715Smrg 3301b5d61b8Smrg dixSetPrivate(&pScreen->devPrivates, &miSpriteScreenKeyRec, pScreenPriv); 3314642e01fSmrg 33205b261ecSmrg pScreen->CloseScreen = miSpriteCloseScreen; 33305b261ecSmrg pScreen->SourceValidate = miSpriteSourceValidate; 3344642e01fSmrg 33505b261ecSmrg pScreen->CopyWindow = miSpriteCopyWindow; 33605b261ecSmrg pScreen->InstallColormap = miSpriteInstallColormap; 33705b261ecSmrg pScreen->StoreColors = miSpriteStoreColors; 33805b261ecSmrg 33905b261ecSmrg return TRUE; 34005b261ecSmrg} 34105b261ecSmrg 34205b261ecSmrg/* 34305b261ecSmrg * Screen wrappers 34405b261ecSmrg */ 34505b261ecSmrg 34605b261ecSmrg/* 34705b261ecSmrg * CloseScreen wrapper -- unwrap everything, free the private data 34805b261ecSmrg * and call the wrapped function 34905b261ecSmrg */ 35005b261ecSmrg 35105b261ecSmrgstatic Bool 35235c4bbdfSmrgmiSpriteCloseScreen(ScreenPtr pScreen) 35305b261ecSmrg{ 35435c4bbdfSmrg miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); 35505b261ecSmrg 35605b261ecSmrg pScreen->CloseScreen = pScreenPriv->CloseScreen; 35705b261ecSmrg pScreen->SourceValidate = pScreenPriv->SourceValidate; 35805b261ecSmrg pScreen->InstallColormap = pScreenPriv->InstallColormap; 35905b261ecSmrg pScreen->StoreColors = pScreenPriv->StoreColors; 36005b261ecSmrg 36135c4bbdfSmrg DamageDestroy(pScreenPriv->pDamage); 3624642e01fSmrg 3636747b715Smrg free(pScreenPriv); 36405b261ecSmrg 36535c4bbdfSmrg return (*pScreen->CloseScreen) (pScreen); 36605b261ecSmrg} 36705b261ecSmrg 36805b261ecSmrgstatic void 36935c4bbdfSmrgmiSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, int width, 37035c4bbdfSmrg int height, unsigned int subWindowMode) 37105b261ecSmrg{ 37235c4bbdfSmrg ScreenPtr pScreen = pDrawable->pScreen; 37335c4bbdfSmrg DeviceIntPtr pDev; 37435c4bbdfSmrg miCursorInfoPtr pCursorInfo; 37535c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 37635c4bbdfSmrg 37735c4bbdfSmrg SCREEN_PROLOGUE(pPriv, pScreen, SourceValidate); 37835c4bbdfSmrg 37935c4bbdfSmrg if (pDrawable->type == DRAWABLE_WINDOW) { 38035c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 38135c4bbdfSmrg if (DevHasCursor(pDev)) { 3821b5d61b8Smrg pCursorInfo = GetSprite(pDev); 38335c4bbdfSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 38435c4bbdfSmrg ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y, 38535c4bbdfSmrg x, y, width, height)) { 38635c4bbdfSmrg SPRITE_DEBUG(("SourceValidate remove\n")); 38735c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 38835c4bbdfSmrg } 38935c4bbdfSmrg } 39035c4bbdfSmrg } 39105b261ecSmrg } 39205b261ecSmrg 393ed6184dfSmrg (*pScreen->SourceValidate) (pDrawable, x, y, width, height, 394ed6184dfSmrg subWindowMode); 39505b261ecSmrg 39635c4bbdfSmrg SCREEN_EPILOGUE(pPriv, pScreen, SourceValidate); 39705b261ecSmrg} 39805b261ecSmrg 39905b261ecSmrgstatic void 40035c4bbdfSmrgmiSpriteCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) 40105b261ecSmrg{ 40235c4bbdfSmrg ScreenPtr pScreen = pWindow->drawable.pScreen; 40335c4bbdfSmrg DeviceIntPtr pDev; 40435c4bbdfSmrg miCursorInfoPtr pCursorInfo; 40535c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 4064642e01fSmrg 40735c4bbdfSmrg SCREEN_PROLOGUE(pPriv, pScreen, CopyWindow); 40805b261ecSmrg 40935c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 41035c4bbdfSmrg if (DevHasCursor(pDev)) { 4111b5d61b8Smrg pCursorInfo = GetSprite(pDev); 4124642e01fSmrg /* 4134642e01fSmrg * Damage will take care of destination check 4144642e01fSmrg */ 4154642e01fSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 41635c4bbdfSmrg RegionContainsRect(prgnSrc, &pCursorInfo->saved) != rgnOUT) { 41735c4bbdfSmrg SPRITE_DEBUG(("CopyWindow remove\n")); 41835c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 4194642e01fSmrg } 4204642e01fSmrg } 42105b261ecSmrg } 42205b261ecSmrg 42305b261ecSmrg (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc); 42435c4bbdfSmrg SCREEN_EPILOGUE(pPriv, pScreen, CopyWindow); 42505b261ecSmrg} 42605b261ecSmrg 42705b261ecSmrgstatic void 4281b5d61b8SmrgmiSpriteBlockHandler(ScreenPtr pScreen, void *timeout) 42905b261ecSmrg{ 43035c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 43135c4bbdfSmrg DeviceIntPtr pDev; 43235c4bbdfSmrg miCursorInfoPtr pCursorInfo; 43335c4bbdfSmrg Bool WorkToDo = FALSE; 43435c4bbdfSmrg 43535c4bbdfSmrg SCREEN_PROLOGUE(pPriv, pScreen, BlockHandler); 43635c4bbdfSmrg 43735c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 43835c4bbdfSmrg if (DevHasCursor(pDev)) { 4391b5d61b8Smrg pCursorInfo = GetSprite(pDev); 4404642e01fSmrg if (pCursorInfo && !pCursorInfo->isUp 44135c4bbdfSmrg && pCursorInfo->pScreen == pScreen && pCursorInfo->shouldBeUp) { 44235c4bbdfSmrg SPRITE_DEBUG(("BlockHandler save")); 44335c4bbdfSmrg miSpriteSaveUnderCursor(pDev, pScreen); 4444642e01fSmrg } 4454642e01fSmrg } 4464642e01fSmrg } 44735c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 44835c4bbdfSmrg if (DevHasCursor(pDev)) { 4491b5d61b8Smrg pCursorInfo = GetSprite(pDev); 4504642e01fSmrg if (pCursorInfo && !pCursorInfo->isUp && 45135c4bbdfSmrg pCursorInfo->pScreen == pScreen && pCursorInfo->shouldBeUp) { 45235c4bbdfSmrg SPRITE_DEBUG(("BlockHandler restore\n")); 45335c4bbdfSmrg miSpriteRestoreCursor(pDev, pScreen); 4549ace9065Smrg if (!pCursorInfo->isUp) 4559ace9065Smrg WorkToDo = TRUE; 4564642e01fSmrg } 4574642e01fSmrg } 45805b261ecSmrg } 4599ace9065Smrg 4601b5d61b8Smrg (*pScreen->BlockHandler) (pScreen, timeout); 4619ace9065Smrg 4629ace9065Smrg if (WorkToDo) 4639ace9065Smrg SCREEN_EPILOGUE(pPriv, pScreen, BlockHandler); 4649ace9065Smrg else 4659ace9065Smrg pPriv->BlockHandler = NULL; 46605b261ecSmrg} 46705b261ecSmrg 46805b261ecSmrgstatic void 46935c4bbdfSmrgmiSpriteInstallColormap(ColormapPtr pMap) 47005b261ecSmrg{ 47135c4bbdfSmrg ScreenPtr pScreen = pMap->pScreen; 47235c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 47305b261ecSmrg 4749ace9065Smrg SCREEN_PROLOGUE(pPriv, pScreen, InstallColormap); 4754642e01fSmrg 47605b261ecSmrg (*pScreen->InstallColormap) (pMap); 47705b261ecSmrg 4789ace9065Smrg SCREEN_EPILOGUE(pPriv, pScreen, InstallColormap); 47905b261ecSmrg 4804642e01fSmrg /* InstallColormap can be called before devices are initialized. */ 48105b261ecSmrg pPriv->pInstalledMap = pMap; 48235c4bbdfSmrg if (pPriv->pColormap != pMap) { 4834642e01fSmrg DeviceIntPtr pDev; 48435c4bbdfSmrg miCursorInfoPtr pCursorInfo; 48535c4bbdfSmrg 48635c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 48735c4bbdfSmrg if (DevHasCursor(pDev)) { 4881b5d61b8Smrg pCursorInfo = GetSprite(pDev); 4894642e01fSmrg pCursorInfo->checkPixels = TRUE; 4904642e01fSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) 4914642e01fSmrg miSpriteRemoveCursor(pDev, pScreen); 4924642e01fSmrg } 4934642e01fSmrg } 4944642e01fSmrg 49505b261ecSmrg } 49605b261ecSmrg} 49705b261ecSmrg 49805b261ecSmrgstatic void 49935c4bbdfSmrgmiSpriteStoreColors(ColormapPtr pMap, int ndef, xColorItem * pdef) 50005b261ecSmrg{ 50135c4bbdfSmrg ScreenPtr pScreen = pMap->pScreen; 50235c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 50335c4bbdfSmrg int i; 50435c4bbdfSmrg int updated; 50535c4bbdfSmrg VisualPtr pVisual; 50635c4bbdfSmrg DeviceIntPtr pDev; 50735c4bbdfSmrg miCursorInfoPtr pCursorInfo; 50805b261ecSmrg 5099ace9065Smrg SCREEN_PROLOGUE(pPriv, pScreen, StoreColors); 5104642e01fSmrg 51105b261ecSmrg (*pScreen->StoreColors) (pMap, ndef, pdef); 51205b261ecSmrg 5139ace9065Smrg SCREEN_EPILOGUE(pPriv, pScreen, StoreColors); 51405b261ecSmrg 51535c4bbdfSmrg if (pPriv->pColormap == pMap) { 5164642e01fSmrg updated = 0; 5174642e01fSmrg pVisual = pMap->pVisual; 51835c4bbdfSmrg if (pVisual->class == DirectColor) { 5194642e01fSmrg /* Direct color - match on any of the subfields */ 52005b261ecSmrg 52105b261ecSmrg#define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask))) 52205b261ecSmrg 5234642e01fSmrg#define UpdateDAC(dev, plane,dac,mask) {\ 5244642e01fSmrg if (MaskMatch (dev->colors[plane].pixel,pdef[i].pixel,mask)) {\ 5254642e01fSmrg dev->colors[plane].dac = pdef[i].dac; \ 52605b261ecSmrg updated = 1; \ 52705b261ecSmrg } \ 52805b261ecSmrg} 52905b261ecSmrg 5304642e01fSmrg#define CheckDirect(dev, plane) \ 5314642e01fSmrg UpdateDAC(dev, plane,red,redMask) \ 5324642e01fSmrg UpdateDAC(dev, plane,green,greenMask) \ 5334642e01fSmrg UpdateDAC(dev, plane,blue,blueMask) 5344642e01fSmrg 53535c4bbdfSmrg for (i = 0; i < ndef; i++) { 53635c4bbdfSmrg CheckDirect(pPriv, SOURCE_COLOR) 53735c4bbdfSmrg CheckDirect(pPriv, MASK_COLOR) 5384642e01fSmrg } 5394642e01fSmrg } 54035c4bbdfSmrg else { 5414642e01fSmrg /* PseudoColor/GrayScale - match on exact pixel */ 54235c4bbdfSmrg for (i = 0; i < ndef; i++) { 54335c4bbdfSmrg if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel) { 5444642e01fSmrg pPriv->colors[SOURCE_COLOR] = pdef[i]; 5454642e01fSmrg if (++updated == 2) 5464642e01fSmrg break; 5474642e01fSmrg } 54835c4bbdfSmrg if (pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel) { 5494642e01fSmrg pPriv->colors[MASK_COLOR] = pdef[i]; 5504642e01fSmrg if (++updated == 2) 5514642e01fSmrg break; 5524642e01fSmrg } 5534642e01fSmrg } 5544642e01fSmrg } 55535c4bbdfSmrg if (updated) { 55635c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 55735c4bbdfSmrg if (DevHasCursor(pDev)) { 5581b5d61b8Smrg pCursorInfo = GetSprite(pDev); 5594642e01fSmrg pCursorInfo->checkPixels = TRUE; 5604642e01fSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) 56135c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 5624642e01fSmrg } 5634642e01fSmrg } 5644642e01fSmrg } 56505b261ecSmrg } 56605b261ecSmrg} 56705b261ecSmrg 56805b261ecSmrgstatic void 56935c4bbdfSmrgmiSpriteFindColors(miCursorInfoPtr pDevCursor, ScreenPtr pScreen) 57005b261ecSmrg{ 57135c4bbdfSmrg miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); 57235c4bbdfSmrg CursorPtr pCursor; 57335c4bbdfSmrg xColorItem *sourceColor, *maskColor; 57405b261ecSmrg 5754642e01fSmrg pCursor = pDevCursor->pCursor; 57605b261ecSmrg sourceColor = &pScreenPriv->colors[SOURCE_COLOR]; 57705b261ecSmrg maskColor = &pScreenPriv->colors[MASK_COLOR]; 57805b261ecSmrg if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap || 57935c4bbdfSmrg !(pCursor->foreRed == sourceColor->red && 58035c4bbdfSmrg pCursor->foreGreen == sourceColor->green && 58105b261ecSmrg pCursor->foreBlue == sourceColor->blue && 58235c4bbdfSmrg pCursor->backRed == maskColor->red && 58335c4bbdfSmrg pCursor->backGreen == maskColor->green && 58435c4bbdfSmrg pCursor->backBlue == maskColor->blue)) { 58535c4bbdfSmrg pScreenPriv->pColormap = pScreenPriv->pInstalledMap; 58635c4bbdfSmrg sourceColor->red = pCursor->foreRed; 58735c4bbdfSmrg sourceColor->green = pCursor->foreGreen; 58835c4bbdfSmrg sourceColor->blue = pCursor->foreBlue; 58935c4bbdfSmrg FakeAllocColor(pScreenPriv->pColormap, sourceColor); 59035c4bbdfSmrg maskColor->red = pCursor->backRed; 59135c4bbdfSmrg maskColor->green = pCursor->backGreen; 59235c4bbdfSmrg maskColor->blue = pCursor->backBlue; 59335c4bbdfSmrg FakeAllocColor(pScreenPriv->pColormap, maskColor); 59435c4bbdfSmrg /* "free" the pixels right away, don't let this confuse you */ 59535c4bbdfSmrg FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel); 59635c4bbdfSmrg FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel); 59705b261ecSmrg } 59805b261ecSmrg 5994642e01fSmrg pDevCursor->checkPixels = FALSE; 60005b261ecSmrg 60105b261ecSmrg} 60205b261ecSmrg 60305b261ecSmrg/* 60405b261ecSmrg * miPointer interface routines 60505b261ecSmrg */ 60605b261ecSmrg 60705b261ecSmrg#define SPRITE_PAD 8 60805b261ecSmrg 60905b261ecSmrgstatic Bool 61035c4bbdfSmrgmiSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 61105b261ecSmrg{ 6124642e01fSmrg miCursorInfoPtr pCursorInfo; 6134642e01fSmrg 61435c4bbdfSmrg if (IsFloating(pDev)) 6154642e01fSmrg return FALSE; 6166747b715Smrg 6171b5d61b8Smrg pCursorInfo = GetSprite(pDev); 6184642e01fSmrg 6194642e01fSmrg if (pCursor == pCursorInfo->pCursor) 62035c4bbdfSmrg pCursorInfo->checkPixels = TRUE; 62105b261ecSmrg 6226747b715Smrg return miDCRealizeCursor(pScreen, pCursor); 62305b261ecSmrg} 62405b261ecSmrg 62505b261ecSmrgstatic Bool 6264642e01fSmrgmiSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 62705b261ecSmrg{ 6286747b715Smrg return miDCUnrealizeCursor(pScreen, pCursor); 62905b261ecSmrg} 63005b261ecSmrg 63105b261ecSmrgstatic void 63235c4bbdfSmrgmiSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 63335c4bbdfSmrg CursorPtr pCursor, int x, int y) 63405b261ecSmrg{ 63535c4bbdfSmrg miCursorInfoPtr pPointer; 63635c4bbdfSmrg miSpriteScreenPtr pScreenPriv; 6374642e01fSmrg 63835c4bbdfSmrg if (IsFloating(pDev)) 6394642e01fSmrg return; 6406747b715Smrg 6411b5d61b8Smrg pPointer = GetSprite(pDev); 6429ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 6434642e01fSmrg 64435c4bbdfSmrg if (!pCursor) { 64535c4bbdfSmrg if (pPointer->shouldBeUp) 64635c4bbdfSmrg --pScreenPriv->numberOfCursors; 64735c4bbdfSmrg pPointer->shouldBeUp = FALSE; 64835c4bbdfSmrg if (pPointer->isUp) 64935c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 65035c4bbdfSmrg if (pScreenPriv->numberOfCursors == 0) 65135c4bbdfSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 65235c4bbdfSmrg pPointer->pCursor = 0; 65335c4bbdfSmrg return; 65405b261ecSmrg } 6559ace9065Smrg if (!pPointer->shouldBeUp) 65635c4bbdfSmrg pScreenPriv->numberOfCursors++; 6574642e01fSmrg pPointer->shouldBeUp = TRUE; 6589ace9065Smrg if (!pPointer->isUp) 65935c4bbdfSmrg miSpriteRegisterBlockHandler(pScreen, pScreenPriv); 6604642e01fSmrg if (pPointer->x == x && 66135c4bbdfSmrg pPointer->y == y && 66235c4bbdfSmrg pPointer->pCursor == pCursor && !pPointer->checkPixels) { 66335c4bbdfSmrg return; 66405b261ecSmrg } 6654642e01fSmrg pPointer->x = x; 6664642e01fSmrg pPointer->y = y; 66735c4bbdfSmrg if (pPointer->checkPixels || pPointer->pCursor != pCursor) { 66835c4bbdfSmrg pPointer->pCursor = pCursor; 66935c4bbdfSmrg miSpriteFindColors(pPointer, pScreen); 67005b261ecSmrg } 6714642e01fSmrg if (pPointer->isUp) { 67235c4bbdfSmrg /* TODO: reimplement flicker-free MoveCursor */ 67335c4bbdfSmrg SPRITE_DEBUG(("SetCursor remove %d\n", pDev->id)); 67435c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 67505b261ecSmrg } 6764642e01fSmrg 67735c4bbdfSmrg if (!pPointer->isUp && pPointer->pCursor) { 67835c4bbdfSmrg SPRITE_DEBUG(("SetCursor restore %d\n", pDev->id)); 6794642e01fSmrg miSpriteSaveUnderCursor(pDev, pScreen); 68035c4bbdfSmrg miSpriteRestoreCursor(pDev, pScreen); 68105b261ecSmrg } 6824642e01fSmrg 68305b261ecSmrg} 68405b261ecSmrg 68505b261ecSmrgstatic void 68635c4bbdfSmrgmiSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 68705b261ecSmrg{ 6884642e01fSmrg CursorPtr pCursor; 68905b261ecSmrg 69035c4bbdfSmrg if (IsFloating(pDev)) 6914642e01fSmrg return; 6926747b715Smrg 6931b5d61b8Smrg pCursor = GetSprite(pDev)->pCursor; 6944642e01fSmrg 69535c4bbdfSmrg miSpriteSetCursor(pDev, pScreen, pCursor, x, y); 6964642e01fSmrg} 6974642e01fSmrg 6984642e01fSmrgstatic Bool 6994642e01fSmrgmiSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) 7004642e01fSmrg{ 70135c4bbdfSmrg int ret = miDCDeviceInitialize(pDev, pScreen); 70235c4bbdfSmrg 70335c4bbdfSmrg if (ret) { 70435c4bbdfSmrg miCursorInfoPtr pCursorInfo; 70535c4bbdfSmrg 70635c4bbdfSmrg pCursorInfo = 7071b5d61b8Smrg dixLookupPrivate(&pDev->devPrivates, &miSpriteDevPrivatesKeyRec); 70835c4bbdfSmrg pCursorInfo->pCursor = NULL; 70935c4bbdfSmrg pCursorInfo->x = 0; 71035c4bbdfSmrg pCursorInfo->y = 0; 71135c4bbdfSmrg pCursorInfo->isUp = FALSE; 71235c4bbdfSmrg pCursorInfo->shouldBeUp = FALSE; 71335c4bbdfSmrg pCursorInfo->checkPixels = TRUE; 71435c4bbdfSmrg pCursorInfo->pScreen = FALSE; 7154642e01fSmrg } 71635c4bbdfSmrg 7174642e01fSmrg return ret; 7184642e01fSmrg} 7194642e01fSmrg 7204642e01fSmrgstatic void 7214642e01fSmrgmiSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) 7224642e01fSmrg{ 72335c4bbdfSmrg miCursorInfoPtr pCursorInfo = 7241b5d61b8Smrg dixLookupPrivate(&pDev->devPrivates, &miSpriteDevPrivatesKeyRec); 72535c4bbdfSmrg 7264642e01fSmrg if (DevHasCursor(pDev)) 7276747b715Smrg miDCDeviceCleanup(pDev, pScreen); 72835c4bbdfSmrg 72935c4bbdfSmrg memset(pCursorInfo, 0, sizeof(miCursorInfoRec)); 73005b261ecSmrg} 73105b261ecSmrg 73205b261ecSmrg/* 73305b261ecSmrg * undraw/draw cursor 73405b261ecSmrg */ 73505b261ecSmrg 73605b261ecSmrgstatic void 73735c4bbdfSmrgmiSpriteRemoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen) 73805b261ecSmrg{ 73935c4bbdfSmrg miSpriteScreenPtr pScreenPriv; 74035c4bbdfSmrg miCursorInfoPtr pCursorInfo; 74105b261ecSmrg 74235c4bbdfSmrg if (IsFloating(pDev)) 7434642e01fSmrg return; 7446747b715Smrg 74535c4bbdfSmrg DamageDrawInternal(pScreen, TRUE); 7469ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 7471b5d61b8Smrg pCursorInfo = GetSprite(pDev); 7484642e01fSmrg 7494642e01fSmrg miSpriteIsDown(pCursorInfo); 7509ace9065Smrg miSpriteRegisterBlockHandler(pScreen, pScreenPriv); 7514642e01fSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 7526747b715Smrg if (!miDCRestoreUnderCursor(pDev, 7536747b715Smrg pScreen, 7546747b715Smrg pCursorInfo->saved.x1, 7556747b715Smrg pCursorInfo->saved.y1, 7566747b715Smrg pCursorInfo->saved.x2 - 7576747b715Smrg pCursorInfo->saved.x1, 7586747b715Smrg pCursorInfo->saved.y2 - 75935c4bbdfSmrg pCursorInfo->saved.y1)) { 7606747b715Smrg miSpriteIsUp(pCursorInfo); 76105b261ecSmrg } 7624642e01fSmrg miSpriteEnableDamage(pScreen, pScreenPriv); 76335c4bbdfSmrg DamageDrawInternal(pScreen, FALSE); 76405b261ecSmrg} 76505b261ecSmrg 7664642e01fSmrg/* 7674642e01fSmrg * Called from the block handler, saves area under cursor 7684642e01fSmrg * before waiting for something to do. 7694642e01fSmrg */ 7704642e01fSmrg 7714642e01fSmrgstatic void 7724642e01fSmrgmiSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen) 7734642e01fSmrg{ 77435c4bbdfSmrg miSpriteScreenPtr pScreenPriv; 77535c4bbdfSmrg miCursorInfoPtr pCursorInfo; 7764642e01fSmrg 77735c4bbdfSmrg if (IsFloating(pDev)) 7784642e01fSmrg return; 7796747b715Smrg 78035c4bbdfSmrg DamageDrawInternal(pScreen, TRUE); 7819ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 7821b5d61b8Smrg pCursorInfo = GetSprite(pDev); 7834642e01fSmrg 78435c4bbdfSmrg miSpriteComputeSaved(pDev, pScreen); 7854642e01fSmrg 7864642e01fSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 7874642e01fSmrg 7886747b715Smrg miDCSaveUnderCursor(pDev, 7896747b715Smrg pScreen, 7906747b715Smrg pCursorInfo->saved.x1, 7916747b715Smrg pCursorInfo->saved.y1, 7926747b715Smrg pCursorInfo->saved.x2 - 7936747b715Smrg pCursorInfo->saved.x1, 79435c4bbdfSmrg pCursorInfo->saved.y2 - pCursorInfo->saved.y1); 7954642e01fSmrg SPRITE_DEBUG(("SaveUnderCursor %d\n", pDev->id)); 7964642e01fSmrg miSpriteEnableDamage(pScreen, pScreenPriv); 79735c4bbdfSmrg DamageDrawInternal(pScreen, FALSE); 7984642e01fSmrg} 7994642e01fSmrg 80005b261ecSmrg/* 80105b261ecSmrg * Called from the block handler, restores the cursor 80205b261ecSmrg * before waiting for something to do. 80305b261ecSmrg */ 80405b261ecSmrg 80505b261ecSmrgstatic void 80635c4bbdfSmrgmiSpriteRestoreCursor(DeviceIntPtr pDev, ScreenPtr pScreen) 80705b261ecSmrg{ 80835c4bbdfSmrg miSpriteScreenPtr pScreenPriv; 80935c4bbdfSmrg int x, y; 81035c4bbdfSmrg CursorPtr pCursor; 81135c4bbdfSmrg miCursorInfoPtr pCursorInfo; 8124642e01fSmrg 81335c4bbdfSmrg if (IsFloating(pDev)) 8144642e01fSmrg return; 81505b261ecSmrg 81635c4bbdfSmrg DamageDrawInternal(pScreen, TRUE); 8179ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 8181b5d61b8Smrg pCursorInfo = GetSprite(pDev); 8194642e01fSmrg 82035c4bbdfSmrg miSpriteComputeSaved(pDev, pScreen); 8214642e01fSmrg pCursor = pCursorInfo->pCursor; 8224642e01fSmrg 82335c4bbdfSmrg x = pCursorInfo->x - (int) pCursor->bits->xhot; 82435c4bbdfSmrg y = pCursorInfo->y - (int) pCursor->bits->yhot; 8254642e01fSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 8264642e01fSmrg SPRITE_DEBUG(("RestoreCursor %d\n", pDev->id)); 8274642e01fSmrg if (pCursorInfo->checkPixels) 82835c4bbdfSmrg miSpriteFindColors(pCursorInfo, pScreen); 8296747b715Smrg if (miDCPutUpCursor(pDev, pScreen, 83035c4bbdfSmrg pCursor, x, y, 83135c4bbdfSmrg pScreenPriv->colors[SOURCE_COLOR].pixel, 83235c4bbdfSmrg pScreenPriv->colors[MASK_COLOR].pixel)) { 8334642e01fSmrg miSpriteIsUp(pCursorInfo); 8344642e01fSmrg pCursorInfo->pScreen = pScreen; 83505b261ecSmrg } 8364642e01fSmrg miSpriteEnableDamage(pScreen, pScreenPriv); 83735c4bbdfSmrg DamageDrawInternal(pScreen, FALSE); 83805b261ecSmrg} 83905b261ecSmrg 84005b261ecSmrg/* 84105b261ecSmrg * compute the desired area of the screen to save 84205b261ecSmrg */ 84305b261ecSmrg 84405b261ecSmrgstatic void 84535c4bbdfSmrgmiSpriteComputeSaved(DeviceIntPtr pDev, ScreenPtr pScreen) 84605b261ecSmrg{ 84735c4bbdfSmrg int x, y, w, h; 84835c4bbdfSmrg int wpad, hpad; 84935c4bbdfSmrg CursorPtr pCursor; 8504642e01fSmrg miCursorInfoPtr pCursorInfo; 85105b261ecSmrg 85235c4bbdfSmrg if (IsFloating(pDev)) 8534642e01fSmrg return; 8546747b715Smrg 8551b5d61b8Smrg pCursorInfo = GetSprite(pDev); 8564642e01fSmrg 8574642e01fSmrg pCursor = pCursorInfo->pCursor; 85835c4bbdfSmrg x = pCursorInfo->x - (int) pCursor->bits->xhot; 85935c4bbdfSmrg y = pCursorInfo->y - (int) pCursor->bits->yhot; 86005b261ecSmrg w = pCursor->bits->width; 86105b261ecSmrg h = pCursor->bits->height; 86205b261ecSmrg wpad = SPRITE_PAD; 86305b261ecSmrg hpad = SPRITE_PAD; 8644642e01fSmrg pCursorInfo->saved.x1 = x - wpad; 8654642e01fSmrg pCursorInfo->saved.y1 = y - hpad; 8664642e01fSmrg pCursorInfo->saved.x2 = pCursorInfo->saved.x1 + w + wpad * 2; 8674642e01fSmrg pCursorInfo->saved.y2 = pCursorInfo->saved.y1 + h + hpad * 2; 86805b261ecSmrg} 869