misprite.c revision 35c4bbdf
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 WindowPtr pCacheWin; /* window the cursor last seen in */ 6335c4bbdfSmrg Bool isInCacheWin; 6435c4bbdfSmrg Bool checkPixels; /* check colormap collision */ 6535c4bbdfSmrg ScreenPtr pScreen; 666747b715Smrg} miCursorInfoRec, *miCursorInfoPtr; 676747b715Smrg 686747b715Smrg/* 696747b715Smrg * per screen information 706747b715Smrg */ 716747b715Smrg 726747b715Smrgtypedef struct { 736747b715Smrg /* screen procedures */ 7435c4bbdfSmrg CloseScreenProcPtr CloseScreen; 7535c4bbdfSmrg GetImageProcPtr GetImage; 7635c4bbdfSmrg GetSpansProcPtr GetSpans; 7735c4bbdfSmrg SourceValidateProcPtr SourceValidate; 7835c4bbdfSmrg 796747b715Smrg /* window procedures */ 8035c4bbdfSmrg CopyWindowProcPtr CopyWindow; 8135c4bbdfSmrg 826747b715Smrg /* colormap procedures */ 8335c4bbdfSmrg InstallColormapProcPtr InstallColormap; 8435c4bbdfSmrg StoreColorsProcPtr StoreColors; 8535c4bbdfSmrg 866747b715Smrg /* os layer procedures */ 8735c4bbdfSmrg ScreenBlockHandlerProcPtr BlockHandler; 8835c4bbdfSmrg 8935c4bbdfSmrg xColorItem colors[2]; 9035c4bbdfSmrg ColormapPtr pInstalledMap; 9135c4bbdfSmrg ColormapPtr pColormap; 9235c4bbdfSmrg VisualPtr pVisual; 9335c4bbdfSmrg DamagePtr pDamage; /* damage tracking structure */ 9435c4bbdfSmrg Bool damageRegistered; 9535c4bbdfSmrg int numberOfCursors; 966747b715Smrg} miSpriteScreenRec, *miSpriteScreenPtr; 976747b715Smrg 986747b715Smrg#define SOURCE_COLOR 0 996747b715Smrg#define MASK_COLOR 1 1006747b715Smrg 1016747b715Smrg/* 1026747b715Smrg * Overlap BoxPtr and Box elements 1036747b715Smrg */ 1046747b715Smrg#define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \ 1056747b715Smrg (((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \ 1066747b715Smrg ((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2)) 1076747b715Smrg 1086747b715Smrg/* 1096747b715Smrg * Overlap BoxPtr, origins, and rectangle 1106747b715Smrg */ 1116747b715Smrg#define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \ 1126747b715Smrg BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h)) 1136747b715Smrg 1146747b715Smrg/* 1156747b715Smrg * Overlap BoxPtr, origins and RectPtr 1166747b715Smrg */ 1176747b715Smrg#define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \ 1186747b715Smrg ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y, \ 1196747b715Smrg (int)((pRect)->width), (int)((pRect)->height)) 1206747b715Smrg/* 1216747b715Smrg * Overlap BoxPtr and horizontal span 1226747b715Smrg */ 1236747b715Smrg#define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y)) 12405b261ecSmrg 1256747b715Smrg#define LINE_SORT(x1,y1,x2,y2) \ 1266747b715Smrg{ int _t; \ 1276747b715Smrg if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \ 1286747b715Smrg if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } } 1296747b715Smrg 1306747b715Smrg#define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \ 1316747b715Smrg BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2)) 1324642e01fSmrg 13305b261ecSmrg#define SPRITE_DEBUG_ENABLE 0 13405b261ecSmrg#if SPRITE_DEBUG_ENABLE 13505b261ecSmrg#define SPRITE_DEBUG(x) ErrorF x 13605b261ecSmrg#else 13705b261ecSmrg#define SPRITE_DEBUG(x) 13805b261ecSmrg#endif 13905b261ecSmrg 1404642e01fSmrg#define MISPRITE(dev) \ 14135c4bbdfSmrg (IsFloating(dev) ? \ 1424642e01fSmrg (miCursorInfoPtr)dixLookupPrivate(&dev->devPrivates, miSpriteDevPrivatesKey) : \ 1436747b715Smrg (miCursorInfoPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miSpriteDevPrivatesKey)) 1444642e01fSmrg 1454642e01fSmrgstatic void 1464642e01fSmrgmiSpriteDisableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 1474642e01fSmrg{ 1486747b715Smrg if (pScreenPriv->damageRegistered) { 14935c4bbdfSmrg DamageUnregister(pScreenPriv->pDamage); 15035c4bbdfSmrg pScreenPriv->damageRegistered = 0; 1514642e01fSmrg } 1524642e01fSmrg} 1534642e01fSmrg 1544642e01fSmrgstatic void 1554642e01fSmrgmiSpriteEnableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 1564642e01fSmrg{ 1576747b715Smrg if (!pScreenPriv->damageRegistered) { 15835c4bbdfSmrg pScreenPriv->damageRegistered = 1; 15935c4bbdfSmrg DamageRegister(&(pScreen->GetScreenPixmap(pScreen)->drawable), 16035c4bbdfSmrg pScreenPriv->pDamage); 1614642e01fSmrg } 1624642e01fSmrg} 1634642e01fSmrg 1644642e01fSmrgstatic void 1654642e01fSmrgmiSpriteIsUp(miCursorInfoPtr pDevCursor) 1664642e01fSmrg{ 1674642e01fSmrg pDevCursor->isUp = TRUE; 1684642e01fSmrg} 1694642e01fSmrg 1704642e01fSmrgstatic void 1714642e01fSmrgmiSpriteIsDown(miCursorInfoPtr pDevCursor) 1724642e01fSmrg{ 1734642e01fSmrg pDevCursor->isUp = FALSE; 1744642e01fSmrg} 1754642e01fSmrg 17605b261ecSmrg/* 17705b261ecSmrg * screen wrappers 17805b261ecSmrg */ 17905b261ecSmrg 1806747b715Smrgstatic DevPrivateKeyRec miSpriteScreenKeyRec; 18135c4bbdfSmrg 1826747b715Smrg#define miSpriteScreenKey (&miSpriteScreenKeyRec) 1839ace9065Smrg#define GetSpriteScreen(pScreen) \ 1849ace9065Smrg (dixLookupPrivate(&(pScreen)->devPrivates, miSpriteScreenKey)) 1856747b715Smrgstatic DevPrivateKeyRec miSpriteDevPrivatesKeyRec; 18635c4bbdfSmrg 1876747b715Smrg#define miSpriteDevPrivatesKey (&miSpriteDevPrivatesKeyRec) 18805b261ecSmrg 18935c4bbdfSmrgstatic Bool miSpriteCloseScreen(ScreenPtr pScreen); 19035c4bbdfSmrgstatic void miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy, 19135c4bbdfSmrg int w, int h, unsigned int format, 19235c4bbdfSmrg unsigned long planemask, char *pdstLine); 19335c4bbdfSmrgstatic void miSpriteGetSpans(DrawablePtr pDrawable, int wMax, 19435c4bbdfSmrg DDXPointPtr ppt, int *pwidth, int nspans, 19535c4bbdfSmrg char *pdstStart); 19635c4bbdfSmrgstatic void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, 19735c4bbdfSmrg int width, int height, 19835c4bbdfSmrg unsigned int subWindowMode); 19935c4bbdfSmrgstatic void miSpriteCopyWindow(WindowPtr pWindow, 20035c4bbdfSmrg DDXPointRec ptOldOrg, RegionPtr prgnSrc); 20135c4bbdfSmrgstatic void miSpriteBlockHandler(ScreenPtr pScreen, 20235c4bbdfSmrg void *pTimeout, void *pReadMask); 20335c4bbdfSmrgstatic void miSpriteInstallColormap(ColormapPtr pMap); 20435c4bbdfSmrgstatic void miSpriteStoreColors(ColormapPtr pMap, int ndef, xColorItem * pdef); 20535c4bbdfSmrg 20635c4bbdfSmrgstatic void miSpriteComputeSaved(DeviceIntPtr pDev, ScreenPtr pScreen); 20735c4bbdfSmrg 20835c4bbdfSmrgstatic Bool miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, 20935c4bbdfSmrg ScreenPtr pScreen); 21035c4bbdfSmrgstatic void miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen); 21105b261ecSmrg 2129ace9065Smrg#define SCREEN_PROLOGUE(pPriv, pScreen, field) ((pScreen)->field = \ 2139ace9065Smrg (pPriv)->field) 2149ace9065Smrg#define SCREEN_EPILOGUE(pPriv, pScreen, field)\ 2159ace9065Smrg ((pPriv)->field = (pScreen)->field, (pScreen)->field = miSprite##field) 21605b261ecSmrg 21705b261ecSmrg/* 21805b261ecSmrg * pointer-sprite method table 21905b261ecSmrg */ 22005b261ecSmrg 2214642e01fSmrgstatic Bool miSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2224642e01fSmrg CursorPtr pCursor); 2234642e01fSmrgstatic Bool miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2244642e01fSmrg CursorPtr pCursor); 2254642e01fSmrgstatic void miSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2264642e01fSmrg CursorPtr pCursor, int x, int y); 2274642e01fSmrgstatic void miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2284642e01fSmrg int x, int y); 22905b261ecSmrg 2306747b715SmrgmiPointerSpriteFuncRec miSpritePointerFuncs = { 23105b261ecSmrg miSpriteRealizeCursor, 23205b261ecSmrg miSpriteUnrealizeCursor, 23305b261ecSmrg miSpriteSetCursor, 23405b261ecSmrg miSpriteMoveCursor, 2354642e01fSmrg miSpriteDeviceCursorInitialize, 2364642e01fSmrg miSpriteDeviceCursorCleanup, 23705b261ecSmrg}; 23805b261ecSmrg 23905b261ecSmrg/* 24005b261ecSmrg * other misc functions 24105b261ecSmrg */ 24205b261ecSmrg 24335c4bbdfSmrgstatic void miSpriteRemoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen); 24435c4bbdfSmrgstatic void miSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen); 24535c4bbdfSmrgstatic void miSpriteRestoreCursor(DeviceIntPtr pDev, ScreenPtr pScreen); 24605b261ecSmrg 2479ace9065Smrgstatic void 2489ace9065SmrgmiSpriteRegisterBlockHandler(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 2499ace9065Smrg{ 2509ace9065Smrg if (!pScreenPriv->BlockHandler) { 2519ace9065Smrg pScreenPriv->BlockHandler = pScreen->BlockHandler; 2529ace9065Smrg pScreen->BlockHandler = miSpriteBlockHandler; 2539ace9065Smrg } 2549ace9065Smrg} 2559ace9065Smrg 25605b261ecSmrgstatic void 25735c4bbdfSmrgmiSpriteReportDamage(DamagePtr pDamage, RegionPtr pRegion, void *closure) 25805b261ecSmrg{ 25935c4bbdfSmrg ScreenPtr pScreen = closure; 26035c4bbdfSmrg miCursorInfoPtr pCursorInfo; 26135c4bbdfSmrg DeviceIntPtr pDev; 26235c4bbdfSmrg 26335c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 26435c4bbdfSmrg if (DevHasCursor(pDev)) { 2654642e01fSmrg pCursorInfo = MISPRITE(pDev); 2664642e01fSmrg 2674642e01fSmrg if (pCursorInfo->isUp && 2684642e01fSmrg pCursorInfo->pScreen == pScreen && 26935c4bbdfSmrg RegionContainsRect(pRegion, &pCursorInfo->saved) != rgnOUT) { 2704642e01fSmrg SPRITE_DEBUG(("Damage remove\n")); 27135c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 2724642e01fSmrg } 2734642e01fSmrg } 27405b261ecSmrg } 27505b261ecSmrg} 27605b261ecSmrg 27705b261ecSmrg/* 27805b261ecSmrg * miSpriteInitialize -- called from device-dependent screen 27905b261ecSmrg * initialization proc after all of the function pointers have 28005b261ecSmrg * been stored in the screen structure. 28105b261ecSmrg */ 28205b261ecSmrg 28305b261ecSmrgBool 28435c4bbdfSmrgmiSpriteInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs) 28505b261ecSmrg{ 28635c4bbdfSmrg miSpriteScreenPtr pScreenPriv; 28735c4bbdfSmrg VisualPtr pVisual; 2884642e01fSmrg 28935c4bbdfSmrg if (!DamageSetup(pScreen)) 29035c4bbdfSmrg return FALSE; 29105b261ecSmrg 2926747b715Smrg if (!dixRegisterPrivateKey(&miSpriteScreenKeyRec, PRIVATE_SCREEN, 0)) 29335c4bbdfSmrg return FALSE; 2946747b715Smrg 29535c4bbdfSmrg if (!dixRegisterPrivateKey 29635c4bbdfSmrg (&miSpriteDevPrivatesKeyRec, PRIVATE_DEVICE, sizeof(miCursorInfoRec))) 29735c4bbdfSmrg return FALSE; 2986747b715Smrg 29935c4bbdfSmrg pScreenPriv = malloc(sizeof(miSpriteScreenRec)); 30005b261ecSmrg if (!pScreenPriv) 30135c4bbdfSmrg return FALSE; 30235c4bbdfSmrg 30335c4bbdfSmrg pScreenPriv->pDamage = DamageCreate(miSpriteReportDamage, 30435c4bbdfSmrg NULL, 30535c4bbdfSmrg DamageReportRawRegion, 30635c4bbdfSmrg TRUE, pScreen, pScreen); 30735c4bbdfSmrg 30835c4bbdfSmrg if (!miPointerInitialize(pScreen, &miSpritePointerFuncs, screenFuncs, TRUE)) { 30935c4bbdfSmrg free(pScreenPriv); 31035c4bbdfSmrg return FALSE; 31105b261ecSmrg } 31205b261ecSmrg for (pVisual = pScreen->visuals; 31335c4bbdfSmrg pVisual->vid != pScreen->rootVisual; pVisual++); 31405b261ecSmrg pScreenPriv->pVisual = pVisual; 31505b261ecSmrg pScreenPriv->CloseScreen = pScreen->CloseScreen; 31605b261ecSmrg pScreenPriv->GetImage = pScreen->GetImage; 31705b261ecSmrg pScreenPriv->GetSpans = pScreen->GetSpans; 31805b261ecSmrg pScreenPriv->SourceValidate = pScreen->SourceValidate; 31905b261ecSmrg 32005b261ecSmrg pScreenPriv->CopyWindow = pScreen->CopyWindow; 3214642e01fSmrg 32205b261ecSmrg pScreenPriv->InstallColormap = pScreen->InstallColormap; 32305b261ecSmrg pScreenPriv->StoreColors = pScreen->StoreColors; 3244642e01fSmrg 3259ace9065Smrg pScreenPriv->BlockHandler = NULL; 3264642e01fSmrg 32705b261ecSmrg pScreenPriv->pInstalledMap = NULL; 32805b261ecSmrg pScreenPriv->pColormap = NULL; 32905b261ecSmrg pScreenPriv->colors[SOURCE_COLOR].red = 0; 33005b261ecSmrg pScreenPriv->colors[SOURCE_COLOR].green = 0; 33105b261ecSmrg pScreenPriv->colors[SOURCE_COLOR].blue = 0; 33205b261ecSmrg pScreenPriv->colors[MASK_COLOR].red = 0; 33305b261ecSmrg pScreenPriv->colors[MASK_COLOR].green = 0; 33405b261ecSmrg pScreenPriv->colors[MASK_COLOR].blue = 0; 3356747b715Smrg pScreenPriv->damageRegistered = 0; 3369ace9065Smrg pScreenPriv->numberOfCursors = 0; 3376747b715Smrg 3384642e01fSmrg dixSetPrivate(&pScreen->devPrivates, miSpriteScreenKey, pScreenPriv); 3394642e01fSmrg 34005b261ecSmrg pScreen->CloseScreen = miSpriteCloseScreen; 34105b261ecSmrg pScreen->GetImage = miSpriteGetImage; 34205b261ecSmrg pScreen->GetSpans = miSpriteGetSpans; 34305b261ecSmrg pScreen->SourceValidate = miSpriteSourceValidate; 3444642e01fSmrg 34505b261ecSmrg pScreen->CopyWindow = miSpriteCopyWindow; 34605b261ecSmrg pScreen->InstallColormap = miSpriteInstallColormap; 34705b261ecSmrg pScreen->StoreColors = miSpriteStoreColors; 34805b261ecSmrg 34905b261ecSmrg return TRUE; 35005b261ecSmrg} 35105b261ecSmrg 35205b261ecSmrg/* 35305b261ecSmrg * Screen wrappers 35405b261ecSmrg */ 35505b261ecSmrg 35605b261ecSmrg/* 35705b261ecSmrg * CloseScreen wrapper -- unwrap everything, free the private data 35805b261ecSmrg * and call the wrapped function 35905b261ecSmrg */ 36005b261ecSmrg 36105b261ecSmrgstatic Bool 36235c4bbdfSmrgmiSpriteCloseScreen(ScreenPtr pScreen) 36305b261ecSmrg{ 36435c4bbdfSmrg miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); 36505b261ecSmrg 36605b261ecSmrg pScreen->CloseScreen = pScreenPriv->CloseScreen; 36705b261ecSmrg pScreen->GetImage = pScreenPriv->GetImage; 36805b261ecSmrg pScreen->GetSpans = pScreenPriv->GetSpans; 36905b261ecSmrg pScreen->SourceValidate = pScreenPriv->SourceValidate; 37005b261ecSmrg pScreen->InstallColormap = pScreenPriv->InstallColormap; 37105b261ecSmrg pScreen->StoreColors = pScreenPriv->StoreColors; 37205b261ecSmrg 37335c4bbdfSmrg DamageDestroy(pScreenPriv->pDamage); 3744642e01fSmrg 3756747b715Smrg free(pScreenPriv); 37605b261ecSmrg 37735c4bbdfSmrg return (*pScreen->CloseScreen) (pScreen); 37805b261ecSmrg} 37905b261ecSmrg 38005b261ecSmrgstatic void 38135c4bbdfSmrgmiSpriteGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, 38235c4bbdfSmrg unsigned int format, unsigned long planemask, char *pdstLine) 38305b261ecSmrg{ 38435c4bbdfSmrg ScreenPtr pScreen = pDrawable->pScreen; 38535c4bbdfSmrg DeviceIntPtr pDev; 38635c4bbdfSmrg miCursorInfoPtr pCursorInfo; 38735c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 38835c4bbdfSmrg 38935c4bbdfSmrg SCREEN_PROLOGUE(pPriv, pScreen, GetImage); 39035c4bbdfSmrg 39135c4bbdfSmrg if (pDrawable->type == DRAWABLE_WINDOW) { 39235c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 39335c4bbdfSmrg if (DevHasCursor(pDev)) { 39435c4bbdfSmrg pCursorInfo = MISPRITE(pDev); 39535c4bbdfSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 39635c4bbdfSmrg ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y, 39735c4bbdfSmrg sx, sy, w, h)) { 39835c4bbdfSmrg SPRITE_DEBUG(("GetImage remove\n")); 39935c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 40035c4bbdfSmrg } 4016747b715Smrg } 4024642e01fSmrg } 40305b261ecSmrg } 40405b261ecSmrg 40535c4bbdfSmrg (*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine); 40605b261ecSmrg 40735c4bbdfSmrg SCREEN_EPILOGUE(pPriv, pScreen, GetImage); 40805b261ecSmrg} 40905b261ecSmrg 41005b261ecSmrgstatic void 41135c4bbdfSmrgmiSpriteGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, 41235c4bbdfSmrg int *pwidth, int nspans, char *pdstStart) 41305b261ecSmrg{ 41435c4bbdfSmrg ScreenPtr pScreen = pDrawable->pScreen; 41535c4bbdfSmrg DeviceIntPtr pDev; 41635c4bbdfSmrg miCursorInfoPtr pCursorInfo; 41735c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 41835c4bbdfSmrg 41935c4bbdfSmrg SCREEN_PROLOGUE(pPriv, pScreen, GetSpans); 42035c4bbdfSmrg 42135c4bbdfSmrg if (pDrawable->type == DRAWABLE_WINDOW) { 42235c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 42335c4bbdfSmrg if (DevHasCursor(pDev)) { 4246747b715Smrg pCursorInfo = MISPRITE(pDev); 4256747b715Smrg 42635c4bbdfSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) { 42735c4bbdfSmrg DDXPointPtr pts; 42835c4bbdfSmrg int *widths; 42935c4bbdfSmrg int nPts; 43035c4bbdfSmrg int xorg, yorg; 4316747b715Smrg 4326747b715Smrg xorg = pDrawable->x; 4336747b715Smrg yorg = pDrawable->y; 4346747b715Smrg 4356747b715Smrg for (pts = ppt, widths = pwidth, nPts = nspans; 43635c4bbdfSmrg nPts--; pts++, widths++) { 43735c4bbdfSmrg if (SPN_OVERLAP(&pCursorInfo->saved, pts->y + yorg, 43835c4bbdfSmrg pts->x + xorg, *widths)) { 43935c4bbdfSmrg SPRITE_DEBUG(("GetSpans remove\n")); 44035c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 4416747b715Smrg break; 4426747b715Smrg } 4434642e01fSmrg } 4444642e01fSmrg } 4454642e01fSmrg } 4464642e01fSmrg } 44705b261ecSmrg } 44805b261ecSmrg 44905b261ecSmrg (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); 45005b261ecSmrg 45135c4bbdfSmrg SCREEN_EPILOGUE(pPriv, pScreen, GetSpans); 45205b261ecSmrg} 45305b261ecSmrg 45405b261ecSmrgstatic void 45535c4bbdfSmrgmiSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, int width, 45635c4bbdfSmrg int height, unsigned int subWindowMode) 45705b261ecSmrg{ 45835c4bbdfSmrg ScreenPtr pScreen = pDrawable->pScreen; 45935c4bbdfSmrg DeviceIntPtr pDev; 46035c4bbdfSmrg miCursorInfoPtr pCursorInfo; 46135c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 46235c4bbdfSmrg 46335c4bbdfSmrg SCREEN_PROLOGUE(pPriv, pScreen, SourceValidate); 46435c4bbdfSmrg 46535c4bbdfSmrg if (pDrawable->type == DRAWABLE_WINDOW) { 46635c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 46735c4bbdfSmrg if (DevHasCursor(pDev)) { 46835c4bbdfSmrg pCursorInfo = MISPRITE(pDev); 46935c4bbdfSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 47035c4bbdfSmrg ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y, 47135c4bbdfSmrg x, y, width, height)) { 47235c4bbdfSmrg SPRITE_DEBUG(("SourceValidate remove\n")); 47335c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 47435c4bbdfSmrg } 47535c4bbdfSmrg } 47635c4bbdfSmrg } 47705b261ecSmrg } 47805b261ecSmrg 47905b261ecSmrg if (pScreen->SourceValidate) 48035c4bbdfSmrg (*pScreen->SourceValidate) (pDrawable, x, y, width, height, 48135c4bbdfSmrg subWindowMode); 48205b261ecSmrg 48335c4bbdfSmrg SCREEN_EPILOGUE(pPriv, pScreen, SourceValidate); 48405b261ecSmrg} 48505b261ecSmrg 48605b261ecSmrgstatic void 48735c4bbdfSmrgmiSpriteCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) 48805b261ecSmrg{ 48935c4bbdfSmrg ScreenPtr pScreen = pWindow->drawable.pScreen; 49035c4bbdfSmrg DeviceIntPtr pDev; 49135c4bbdfSmrg miCursorInfoPtr pCursorInfo; 49235c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 4934642e01fSmrg 49435c4bbdfSmrg SCREEN_PROLOGUE(pPriv, pScreen, CopyWindow); 49505b261ecSmrg 49635c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 49735c4bbdfSmrg if (DevHasCursor(pDev)) { 4984642e01fSmrg pCursorInfo = MISPRITE(pDev); 4994642e01fSmrg /* 5004642e01fSmrg * Damage will take care of destination check 5014642e01fSmrg */ 5024642e01fSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 50335c4bbdfSmrg RegionContainsRect(prgnSrc, &pCursorInfo->saved) != rgnOUT) { 50435c4bbdfSmrg SPRITE_DEBUG(("CopyWindow remove\n")); 50535c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 5064642e01fSmrg } 5074642e01fSmrg } 50805b261ecSmrg } 50905b261ecSmrg 51005b261ecSmrg (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc); 51135c4bbdfSmrg SCREEN_EPILOGUE(pPriv, pScreen, CopyWindow); 51205b261ecSmrg} 51305b261ecSmrg 51405b261ecSmrgstatic void 51535c4bbdfSmrgmiSpriteBlockHandler(ScreenPtr pScreen, void *pTimeout, 51635c4bbdfSmrg void *pReadmask) 51705b261ecSmrg{ 51835c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 51935c4bbdfSmrg DeviceIntPtr pDev; 52035c4bbdfSmrg miCursorInfoPtr pCursorInfo; 52135c4bbdfSmrg Bool WorkToDo = FALSE; 52235c4bbdfSmrg 52335c4bbdfSmrg SCREEN_PROLOGUE(pPriv, pScreen, BlockHandler); 52435c4bbdfSmrg 52535c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 52635c4bbdfSmrg if (DevHasCursor(pDev)) { 5274642e01fSmrg pCursorInfo = MISPRITE(pDev); 5284642e01fSmrg if (pCursorInfo && !pCursorInfo->isUp 52935c4bbdfSmrg && pCursorInfo->pScreen == pScreen && pCursorInfo->shouldBeUp) { 53035c4bbdfSmrg SPRITE_DEBUG(("BlockHandler save")); 53135c4bbdfSmrg miSpriteSaveUnderCursor(pDev, pScreen); 5324642e01fSmrg } 5334642e01fSmrg } 5344642e01fSmrg } 53535c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 53635c4bbdfSmrg if (DevHasCursor(pDev)) { 5374642e01fSmrg pCursorInfo = MISPRITE(pDev); 5384642e01fSmrg if (pCursorInfo && !pCursorInfo->isUp && 53935c4bbdfSmrg pCursorInfo->pScreen == pScreen && pCursorInfo->shouldBeUp) { 54035c4bbdfSmrg SPRITE_DEBUG(("BlockHandler restore\n")); 54135c4bbdfSmrg miSpriteRestoreCursor(pDev, pScreen); 5429ace9065Smrg if (!pCursorInfo->isUp) 5439ace9065Smrg WorkToDo = TRUE; 5444642e01fSmrg } 5454642e01fSmrg } 54605b261ecSmrg } 5479ace9065Smrg 54835c4bbdfSmrg (*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask); 5499ace9065Smrg 5509ace9065Smrg if (WorkToDo) 5519ace9065Smrg SCREEN_EPILOGUE(pPriv, pScreen, BlockHandler); 5529ace9065Smrg else 5539ace9065Smrg pPriv->BlockHandler = NULL; 55405b261ecSmrg} 55505b261ecSmrg 55605b261ecSmrgstatic void 55735c4bbdfSmrgmiSpriteInstallColormap(ColormapPtr pMap) 55805b261ecSmrg{ 55935c4bbdfSmrg ScreenPtr pScreen = pMap->pScreen; 56035c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 56105b261ecSmrg 5629ace9065Smrg SCREEN_PROLOGUE(pPriv, pScreen, InstallColormap); 5634642e01fSmrg 56405b261ecSmrg (*pScreen->InstallColormap) (pMap); 56505b261ecSmrg 5669ace9065Smrg SCREEN_EPILOGUE(pPriv, pScreen, InstallColormap); 56705b261ecSmrg 5684642e01fSmrg /* InstallColormap can be called before devices are initialized. */ 56905b261ecSmrg pPriv->pInstalledMap = pMap; 57035c4bbdfSmrg if (pPriv->pColormap != pMap) { 5714642e01fSmrg DeviceIntPtr pDev; 57235c4bbdfSmrg miCursorInfoPtr pCursorInfo; 57335c4bbdfSmrg 57435c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 57535c4bbdfSmrg if (DevHasCursor(pDev)) { 5764642e01fSmrg pCursorInfo = MISPRITE(pDev); 5774642e01fSmrg pCursorInfo->checkPixels = TRUE; 5784642e01fSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) 5794642e01fSmrg miSpriteRemoveCursor(pDev, pScreen); 5804642e01fSmrg } 5814642e01fSmrg } 5824642e01fSmrg 58305b261ecSmrg } 58405b261ecSmrg} 58505b261ecSmrg 58605b261ecSmrgstatic void 58735c4bbdfSmrgmiSpriteStoreColors(ColormapPtr pMap, int ndef, xColorItem * pdef) 58805b261ecSmrg{ 58935c4bbdfSmrg ScreenPtr pScreen = pMap->pScreen; 59035c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 59135c4bbdfSmrg int i; 59235c4bbdfSmrg int updated; 59335c4bbdfSmrg VisualPtr pVisual; 59435c4bbdfSmrg DeviceIntPtr pDev; 59535c4bbdfSmrg miCursorInfoPtr pCursorInfo; 59605b261ecSmrg 5979ace9065Smrg SCREEN_PROLOGUE(pPriv, pScreen, StoreColors); 5984642e01fSmrg 59905b261ecSmrg (*pScreen->StoreColors) (pMap, ndef, pdef); 60005b261ecSmrg 6019ace9065Smrg SCREEN_EPILOGUE(pPriv, pScreen, StoreColors); 60205b261ecSmrg 60335c4bbdfSmrg if (pPriv->pColormap == pMap) { 6044642e01fSmrg updated = 0; 6054642e01fSmrg pVisual = pMap->pVisual; 60635c4bbdfSmrg if (pVisual->class == DirectColor) { 6074642e01fSmrg /* Direct color - match on any of the subfields */ 60805b261ecSmrg 60905b261ecSmrg#define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask))) 61005b261ecSmrg 6114642e01fSmrg#define UpdateDAC(dev, plane,dac,mask) {\ 6124642e01fSmrg if (MaskMatch (dev->colors[plane].pixel,pdef[i].pixel,mask)) {\ 6134642e01fSmrg dev->colors[plane].dac = pdef[i].dac; \ 61405b261ecSmrg updated = 1; \ 61505b261ecSmrg } \ 61605b261ecSmrg} 61705b261ecSmrg 6184642e01fSmrg#define CheckDirect(dev, plane) \ 6194642e01fSmrg UpdateDAC(dev, plane,red,redMask) \ 6204642e01fSmrg UpdateDAC(dev, plane,green,greenMask) \ 6214642e01fSmrg UpdateDAC(dev, plane,blue,blueMask) 6224642e01fSmrg 62335c4bbdfSmrg for (i = 0; i < ndef; i++) { 62435c4bbdfSmrg CheckDirect(pPriv, SOURCE_COLOR) 62535c4bbdfSmrg CheckDirect(pPriv, MASK_COLOR) 6264642e01fSmrg } 6274642e01fSmrg } 62835c4bbdfSmrg else { 6294642e01fSmrg /* PseudoColor/GrayScale - match on exact pixel */ 63035c4bbdfSmrg for (i = 0; i < ndef; i++) { 63135c4bbdfSmrg if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel) { 6324642e01fSmrg pPriv->colors[SOURCE_COLOR] = pdef[i]; 6334642e01fSmrg if (++updated == 2) 6344642e01fSmrg break; 6354642e01fSmrg } 63635c4bbdfSmrg if (pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel) { 6374642e01fSmrg pPriv->colors[MASK_COLOR] = pdef[i]; 6384642e01fSmrg if (++updated == 2) 6394642e01fSmrg break; 6404642e01fSmrg } 6414642e01fSmrg } 6424642e01fSmrg } 64335c4bbdfSmrg if (updated) { 64435c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 64535c4bbdfSmrg if (DevHasCursor(pDev)) { 6464642e01fSmrg pCursorInfo = MISPRITE(pDev); 6474642e01fSmrg pCursorInfo->checkPixels = TRUE; 6484642e01fSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) 64935c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 6504642e01fSmrg } 6514642e01fSmrg } 6524642e01fSmrg } 65305b261ecSmrg } 65405b261ecSmrg} 65505b261ecSmrg 65605b261ecSmrgstatic void 65735c4bbdfSmrgmiSpriteFindColors(miCursorInfoPtr pDevCursor, ScreenPtr pScreen) 65805b261ecSmrg{ 65935c4bbdfSmrg miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); 66035c4bbdfSmrg CursorPtr pCursor; 66135c4bbdfSmrg xColorItem *sourceColor, *maskColor; 66205b261ecSmrg 6634642e01fSmrg pCursor = pDevCursor->pCursor; 66405b261ecSmrg sourceColor = &pScreenPriv->colors[SOURCE_COLOR]; 66505b261ecSmrg maskColor = &pScreenPriv->colors[MASK_COLOR]; 66605b261ecSmrg if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap || 66735c4bbdfSmrg !(pCursor->foreRed == sourceColor->red && 66835c4bbdfSmrg pCursor->foreGreen == sourceColor->green && 66905b261ecSmrg pCursor->foreBlue == sourceColor->blue && 67035c4bbdfSmrg pCursor->backRed == maskColor->red && 67135c4bbdfSmrg pCursor->backGreen == maskColor->green && 67235c4bbdfSmrg pCursor->backBlue == maskColor->blue)) { 67335c4bbdfSmrg pScreenPriv->pColormap = pScreenPriv->pInstalledMap; 67435c4bbdfSmrg sourceColor->red = pCursor->foreRed; 67535c4bbdfSmrg sourceColor->green = pCursor->foreGreen; 67635c4bbdfSmrg sourceColor->blue = pCursor->foreBlue; 67735c4bbdfSmrg FakeAllocColor(pScreenPriv->pColormap, sourceColor); 67835c4bbdfSmrg maskColor->red = pCursor->backRed; 67935c4bbdfSmrg maskColor->green = pCursor->backGreen; 68035c4bbdfSmrg maskColor->blue = pCursor->backBlue; 68135c4bbdfSmrg FakeAllocColor(pScreenPriv->pColormap, maskColor); 68235c4bbdfSmrg /* "free" the pixels right away, don't let this confuse you */ 68335c4bbdfSmrg FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel); 68435c4bbdfSmrg FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel); 68505b261ecSmrg } 68605b261ecSmrg 6874642e01fSmrg pDevCursor->checkPixels = FALSE; 68805b261ecSmrg 68905b261ecSmrg} 69005b261ecSmrg 69105b261ecSmrg/* 69205b261ecSmrg * miPointer interface routines 69305b261ecSmrg */ 69405b261ecSmrg 69505b261ecSmrg#define SPRITE_PAD 8 69605b261ecSmrg 69705b261ecSmrgstatic Bool 69835c4bbdfSmrgmiSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 69905b261ecSmrg{ 7004642e01fSmrg miCursorInfoPtr pCursorInfo; 7014642e01fSmrg 70235c4bbdfSmrg if (IsFloating(pDev)) 7034642e01fSmrg return FALSE; 7046747b715Smrg 7054642e01fSmrg pCursorInfo = MISPRITE(pDev); 7064642e01fSmrg 7074642e01fSmrg if (pCursor == pCursorInfo->pCursor) 70835c4bbdfSmrg pCursorInfo->checkPixels = TRUE; 70905b261ecSmrg 7106747b715Smrg return miDCRealizeCursor(pScreen, pCursor); 71105b261ecSmrg} 71205b261ecSmrg 71305b261ecSmrgstatic Bool 7144642e01fSmrgmiSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 71505b261ecSmrg{ 7166747b715Smrg return miDCUnrealizeCursor(pScreen, pCursor); 71705b261ecSmrg} 71805b261ecSmrg 71905b261ecSmrgstatic void 72035c4bbdfSmrgmiSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 72135c4bbdfSmrg CursorPtr pCursor, int x, int y) 72205b261ecSmrg{ 72335c4bbdfSmrg miCursorInfoPtr pPointer; 72435c4bbdfSmrg miSpriteScreenPtr pScreenPriv; 7254642e01fSmrg 72635c4bbdfSmrg if (IsFloating(pDev)) 7274642e01fSmrg return; 7286747b715Smrg 7294642e01fSmrg pPointer = MISPRITE(pDev); 7309ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 7314642e01fSmrg 73235c4bbdfSmrg if (!pCursor) { 73335c4bbdfSmrg if (pPointer->shouldBeUp) 73435c4bbdfSmrg --pScreenPriv->numberOfCursors; 73535c4bbdfSmrg pPointer->shouldBeUp = FALSE; 73635c4bbdfSmrg if (pPointer->isUp) 73735c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 73835c4bbdfSmrg if (pScreenPriv->numberOfCursors == 0) 73935c4bbdfSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 74035c4bbdfSmrg pPointer->pCursor = 0; 74135c4bbdfSmrg return; 74205b261ecSmrg } 7439ace9065Smrg if (!pPointer->shouldBeUp) 74435c4bbdfSmrg pScreenPriv->numberOfCursors++; 7454642e01fSmrg pPointer->shouldBeUp = TRUE; 7469ace9065Smrg if (!pPointer->isUp) 74735c4bbdfSmrg miSpriteRegisterBlockHandler(pScreen, pScreenPriv); 7484642e01fSmrg if (pPointer->x == x && 74935c4bbdfSmrg pPointer->y == y && 75035c4bbdfSmrg pPointer->pCursor == pCursor && !pPointer->checkPixels) { 75135c4bbdfSmrg return; 75205b261ecSmrg } 7534642e01fSmrg pPointer->x = x; 7544642e01fSmrg pPointer->y = y; 7554642e01fSmrg pPointer->pCacheWin = NullWindow; 75635c4bbdfSmrg if (pPointer->checkPixels || pPointer->pCursor != pCursor) { 75735c4bbdfSmrg pPointer->pCursor = pCursor; 75835c4bbdfSmrg miSpriteFindColors(pPointer, pScreen); 75905b261ecSmrg } 7604642e01fSmrg if (pPointer->isUp) { 76135c4bbdfSmrg /* TODO: reimplement flicker-free MoveCursor */ 76235c4bbdfSmrg SPRITE_DEBUG(("SetCursor remove %d\n", pDev->id)); 76335c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 76405b261ecSmrg } 7654642e01fSmrg 76635c4bbdfSmrg if (!pPointer->isUp && pPointer->pCursor) { 76735c4bbdfSmrg SPRITE_DEBUG(("SetCursor restore %d\n", pDev->id)); 7684642e01fSmrg miSpriteSaveUnderCursor(pDev, pScreen); 76935c4bbdfSmrg miSpriteRestoreCursor(pDev, pScreen); 77005b261ecSmrg } 7714642e01fSmrg 77205b261ecSmrg} 77305b261ecSmrg 77405b261ecSmrgstatic void 77535c4bbdfSmrgmiSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 77605b261ecSmrg{ 7774642e01fSmrg CursorPtr pCursor; 77805b261ecSmrg 77935c4bbdfSmrg if (IsFloating(pDev)) 7804642e01fSmrg return; 7816747b715Smrg 7824642e01fSmrg pCursor = MISPRITE(pDev)->pCursor; 7834642e01fSmrg 78435c4bbdfSmrg miSpriteSetCursor(pDev, pScreen, pCursor, x, y); 7854642e01fSmrg} 7864642e01fSmrg 7874642e01fSmrgstatic Bool 7884642e01fSmrgmiSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) 7894642e01fSmrg{ 79035c4bbdfSmrg int ret = miDCDeviceInitialize(pDev, pScreen); 79135c4bbdfSmrg 79235c4bbdfSmrg if (ret) { 79335c4bbdfSmrg miCursorInfoPtr pCursorInfo; 79435c4bbdfSmrg 79535c4bbdfSmrg pCursorInfo = 79635c4bbdfSmrg dixLookupPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey); 79735c4bbdfSmrg pCursorInfo->pCursor = NULL; 79835c4bbdfSmrg pCursorInfo->x = 0; 79935c4bbdfSmrg pCursorInfo->y = 0; 80035c4bbdfSmrg pCursorInfo->isUp = FALSE; 80135c4bbdfSmrg pCursorInfo->shouldBeUp = FALSE; 80235c4bbdfSmrg pCursorInfo->pCacheWin = NullWindow; 80335c4bbdfSmrg pCursorInfo->isInCacheWin = FALSE; 80435c4bbdfSmrg pCursorInfo->checkPixels = TRUE; 80535c4bbdfSmrg pCursorInfo->pScreen = FALSE; 8064642e01fSmrg } 80735c4bbdfSmrg 8084642e01fSmrg return ret; 8094642e01fSmrg} 8104642e01fSmrg 8114642e01fSmrgstatic void 8124642e01fSmrgmiSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) 8134642e01fSmrg{ 81435c4bbdfSmrg miCursorInfoPtr pCursorInfo = 81535c4bbdfSmrg dixLookupPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey); 81635c4bbdfSmrg 8174642e01fSmrg if (DevHasCursor(pDev)) 8186747b715Smrg miDCDeviceCleanup(pDev, pScreen); 81935c4bbdfSmrg 82035c4bbdfSmrg memset(pCursorInfo, 0, sizeof(miCursorInfoRec)); 82105b261ecSmrg} 82205b261ecSmrg 82305b261ecSmrg/* 82405b261ecSmrg * undraw/draw cursor 82505b261ecSmrg */ 82605b261ecSmrg 82705b261ecSmrgstatic void 82835c4bbdfSmrgmiSpriteRemoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen) 82905b261ecSmrg{ 83035c4bbdfSmrg miSpriteScreenPtr pScreenPriv; 83135c4bbdfSmrg miCursorInfoPtr pCursorInfo; 83205b261ecSmrg 83335c4bbdfSmrg if (IsFloating(pDev)) 8344642e01fSmrg return; 8356747b715Smrg 83635c4bbdfSmrg DamageDrawInternal(pScreen, TRUE); 8379ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 8384642e01fSmrg pCursorInfo = MISPRITE(pDev); 8394642e01fSmrg 8404642e01fSmrg miSpriteIsDown(pCursorInfo); 8419ace9065Smrg miSpriteRegisterBlockHandler(pScreen, pScreenPriv); 8424642e01fSmrg pCursorInfo->pCacheWin = NullWindow; 8434642e01fSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 8446747b715Smrg if (!miDCRestoreUnderCursor(pDev, 8456747b715Smrg pScreen, 8466747b715Smrg pCursorInfo->saved.x1, 8476747b715Smrg pCursorInfo->saved.y1, 8486747b715Smrg pCursorInfo->saved.x2 - 8496747b715Smrg pCursorInfo->saved.x1, 8506747b715Smrg pCursorInfo->saved.y2 - 85135c4bbdfSmrg pCursorInfo->saved.y1)) { 8526747b715Smrg miSpriteIsUp(pCursorInfo); 85305b261ecSmrg } 8544642e01fSmrg miSpriteEnableDamage(pScreen, pScreenPriv); 85535c4bbdfSmrg DamageDrawInternal(pScreen, FALSE); 85605b261ecSmrg} 85705b261ecSmrg 8584642e01fSmrg/* 8594642e01fSmrg * Called from the block handler, saves area under cursor 8604642e01fSmrg * before waiting for something to do. 8614642e01fSmrg */ 8624642e01fSmrg 8634642e01fSmrgstatic void 8644642e01fSmrgmiSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen) 8654642e01fSmrg{ 86635c4bbdfSmrg miSpriteScreenPtr pScreenPriv; 86735c4bbdfSmrg miCursorInfoPtr pCursorInfo; 8684642e01fSmrg 86935c4bbdfSmrg if (IsFloating(pDev)) 8704642e01fSmrg return; 8716747b715Smrg 87235c4bbdfSmrg DamageDrawInternal(pScreen, TRUE); 8739ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 8744642e01fSmrg pCursorInfo = MISPRITE(pDev); 8754642e01fSmrg 87635c4bbdfSmrg miSpriteComputeSaved(pDev, pScreen); 8774642e01fSmrg 8784642e01fSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 8794642e01fSmrg 8806747b715Smrg miDCSaveUnderCursor(pDev, 8816747b715Smrg pScreen, 8826747b715Smrg pCursorInfo->saved.x1, 8836747b715Smrg pCursorInfo->saved.y1, 8846747b715Smrg pCursorInfo->saved.x2 - 8856747b715Smrg pCursorInfo->saved.x1, 88635c4bbdfSmrg pCursorInfo->saved.y2 - pCursorInfo->saved.y1); 8874642e01fSmrg SPRITE_DEBUG(("SaveUnderCursor %d\n", pDev->id)); 8884642e01fSmrg miSpriteEnableDamage(pScreen, pScreenPriv); 88935c4bbdfSmrg DamageDrawInternal(pScreen, FALSE); 8904642e01fSmrg} 8914642e01fSmrg 89205b261ecSmrg/* 89305b261ecSmrg * Called from the block handler, restores the cursor 89405b261ecSmrg * before waiting for something to do. 89505b261ecSmrg */ 89605b261ecSmrg 89705b261ecSmrgstatic void 89835c4bbdfSmrgmiSpriteRestoreCursor(DeviceIntPtr pDev, ScreenPtr pScreen) 89905b261ecSmrg{ 90035c4bbdfSmrg miSpriteScreenPtr pScreenPriv; 90135c4bbdfSmrg int x, y; 90235c4bbdfSmrg CursorPtr pCursor; 90335c4bbdfSmrg miCursorInfoPtr pCursorInfo; 9044642e01fSmrg 90535c4bbdfSmrg if (IsFloating(pDev)) 9064642e01fSmrg return; 90705b261ecSmrg 90835c4bbdfSmrg DamageDrawInternal(pScreen, TRUE); 9099ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 9104642e01fSmrg pCursorInfo = MISPRITE(pDev); 9114642e01fSmrg 91235c4bbdfSmrg miSpriteComputeSaved(pDev, pScreen); 9134642e01fSmrg pCursor = pCursorInfo->pCursor; 9144642e01fSmrg 91535c4bbdfSmrg x = pCursorInfo->x - (int) pCursor->bits->xhot; 91635c4bbdfSmrg y = pCursorInfo->y - (int) pCursor->bits->yhot; 9174642e01fSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 9184642e01fSmrg SPRITE_DEBUG(("RestoreCursor %d\n", pDev->id)); 9194642e01fSmrg if (pCursorInfo->checkPixels) 92035c4bbdfSmrg miSpriteFindColors(pCursorInfo, pScreen); 9216747b715Smrg if (miDCPutUpCursor(pDev, pScreen, 92235c4bbdfSmrg pCursor, x, y, 92335c4bbdfSmrg pScreenPriv->colors[SOURCE_COLOR].pixel, 92435c4bbdfSmrg pScreenPriv->colors[MASK_COLOR].pixel)) { 9254642e01fSmrg miSpriteIsUp(pCursorInfo); 9264642e01fSmrg pCursorInfo->pScreen = pScreen; 92705b261ecSmrg } 9284642e01fSmrg miSpriteEnableDamage(pScreen, pScreenPriv); 92935c4bbdfSmrg DamageDrawInternal(pScreen, FALSE); 93005b261ecSmrg} 93105b261ecSmrg 93205b261ecSmrg/* 93305b261ecSmrg * compute the desired area of the screen to save 93405b261ecSmrg */ 93505b261ecSmrg 93605b261ecSmrgstatic void 93735c4bbdfSmrgmiSpriteComputeSaved(DeviceIntPtr pDev, ScreenPtr pScreen) 93805b261ecSmrg{ 93935c4bbdfSmrg int x, y, w, h; 94035c4bbdfSmrg int wpad, hpad; 94135c4bbdfSmrg CursorPtr pCursor; 9424642e01fSmrg miCursorInfoPtr pCursorInfo; 94305b261ecSmrg 94435c4bbdfSmrg if (IsFloating(pDev)) 9454642e01fSmrg return; 9466747b715Smrg 9474642e01fSmrg pCursorInfo = MISPRITE(pDev); 9484642e01fSmrg 9494642e01fSmrg pCursor = pCursorInfo->pCursor; 95035c4bbdfSmrg x = pCursorInfo->x - (int) pCursor->bits->xhot; 95135c4bbdfSmrg y = pCursorInfo->y - (int) pCursor->bits->yhot; 95205b261ecSmrg w = pCursor->bits->width; 95305b261ecSmrg h = pCursor->bits->height; 95405b261ecSmrg wpad = SPRITE_PAD; 95505b261ecSmrg hpad = SPRITE_PAD; 9564642e01fSmrg pCursorInfo->saved.x1 = x - wpad; 9574642e01fSmrg pCursorInfo->saved.y1 = y - hpad; 9584642e01fSmrg pCursorInfo->saved.x2 = pCursorInfo->saved.x1 + w + wpad * 2; 9594642e01fSmrg pCursorInfo->saved.y2 = pCursorInfo->saved.y1 + h + hpad * 2; 96005b261ecSmrg} 961