misprite.c revision 8223e2f2
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 { 566747b715Smrg CursorPtr pCursor; 576747b715Smrg int x; /* cursor hotspot */ 586747b715Smrg int y; 596747b715Smrg BoxRec saved; /* saved area from the screen */ 606747b715Smrg Bool isUp; /* cursor in frame buffer */ 616747b715Smrg Bool shouldBeUp; /* cursor should be displayed */ 626747b715Smrg WindowPtr pCacheWin; /* window the cursor last seen in */ 636747b715Smrg Bool isInCacheWin; 646747b715Smrg Bool checkPixels; /* check colormap collision */ 656747b715Smrg ScreenPtr pScreen; 666747b715Smrg} miCursorInfoRec, *miCursorInfoPtr; 676747b715Smrg 686747b715Smrg/* 696747b715Smrg * per screen information 706747b715Smrg */ 716747b715Smrg 726747b715Smrgtypedef struct { 736747b715Smrg /* screen procedures */ 746747b715Smrg CloseScreenProcPtr CloseScreen; 756747b715Smrg GetImageProcPtr GetImage; 766747b715Smrg GetSpansProcPtr GetSpans; 776747b715Smrg SourceValidateProcPtr SourceValidate; 786747b715Smrg 796747b715Smrg /* window procedures */ 806747b715Smrg CopyWindowProcPtr CopyWindow; 816747b715Smrg 826747b715Smrg /* colormap procedures */ 836747b715Smrg InstallColormapProcPtr InstallColormap; 846747b715Smrg StoreColorsProcPtr StoreColors; 856747b715Smrg 866747b715Smrg /* os layer procedures */ 876747b715Smrg ScreenBlockHandlerProcPtr BlockHandler; 886747b715Smrg 896747b715Smrg /* device cursor procedures */ 906747b715Smrg DeviceCursorInitializeProcPtr DeviceCursorInitialize; 916747b715Smrg DeviceCursorCleanupProcPtr DeviceCursorCleanup; 926747b715Smrg 936747b715Smrg xColorItem colors[2]; 946747b715Smrg ColormapPtr pInstalledMap; 956747b715Smrg ColormapPtr pColormap; 966747b715Smrg VisualPtr pVisual; 976747b715Smrg DamagePtr pDamage; /* damage tracking structure */ 986747b715Smrg Bool damageRegistered; 996747b715Smrg} miSpriteScreenRec, *miSpriteScreenPtr; 1006747b715Smrg 1016747b715Smrg#define SOURCE_COLOR 0 1026747b715Smrg#define MASK_COLOR 1 1036747b715Smrg 1046747b715Smrg/* 1056747b715Smrg * Overlap BoxPtr and Box elements 1066747b715Smrg */ 1076747b715Smrg#define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \ 1086747b715Smrg (((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \ 1096747b715Smrg ((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2)) 1106747b715Smrg 1116747b715Smrg/* 1126747b715Smrg * Overlap BoxPtr, origins, and rectangle 1136747b715Smrg */ 1146747b715Smrg#define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \ 1156747b715Smrg BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h)) 1166747b715Smrg 1176747b715Smrg/* 1186747b715Smrg * Overlap BoxPtr, origins and RectPtr 1196747b715Smrg */ 1206747b715Smrg#define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \ 1216747b715Smrg ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y, \ 1226747b715Smrg (int)((pRect)->width), (int)((pRect)->height)) 1236747b715Smrg/* 1246747b715Smrg * Overlap BoxPtr and horizontal span 1256747b715Smrg */ 1266747b715Smrg#define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y)) 12705b261ecSmrg 1286747b715Smrg#define LINE_SORT(x1,y1,x2,y2) \ 1296747b715Smrg{ int _t; \ 1306747b715Smrg if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \ 1316747b715Smrg if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } } 1326747b715Smrg 1336747b715Smrg#define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \ 1346747b715Smrg BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2)) 1354642e01fSmrg 1364642e01fSmrg 13705b261ecSmrg#define SPRITE_DEBUG_ENABLE 0 13805b261ecSmrg#if SPRITE_DEBUG_ENABLE 13905b261ecSmrg#define SPRITE_DEBUG(x) ErrorF x 14005b261ecSmrg#else 14105b261ecSmrg#define SPRITE_DEBUG(x) 14205b261ecSmrg#endif 14305b261ecSmrg 1444642e01fSmrg#define MISPRITE(dev) \ 1456747b715Smrg ((!IsMaster(dev) && !dev->u.master) ? \ 1464642e01fSmrg (miCursorInfoPtr)dixLookupPrivate(&dev->devPrivates, miSpriteDevPrivatesKey) : \ 1476747b715Smrg (miCursorInfoPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miSpriteDevPrivatesKey)) 1484642e01fSmrg 1494642e01fSmrgstatic void 1504642e01fSmrgmiSpriteDisableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 1514642e01fSmrg{ 1526747b715Smrg if (pScreenPriv->damageRegistered) { 1534642e01fSmrg DamageUnregister (&(pScreen->GetScreenPixmap(pScreen)->drawable), 1544642e01fSmrg pScreenPriv->pDamage); 1556747b715Smrg pScreenPriv->damageRegistered = 0; 1564642e01fSmrg } 1574642e01fSmrg} 1584642e01fSmrg 1594642e01fSmrgstatic void 1604642e01fSmrgmiSpriteEnableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 1614642e01fSmrg{ 1626747b715Smrg if (!pScreenPriv->damageRegistered) { 1636747b715Smrg pScreenPriv->damageRegistered = 1; 1644642e01fSmrg DamageRegister (&(pScreen->GetScreenPixmap(pScreen)->drawable), 1654642e01fSmrg pScreenPriv->pDamage); 1664642e01fSmrg } 1674642e01fSmrg} 1684642e01fSmrg 1694642e01fSmrgstatic void 1704642e01fSmrgmiSpriteIsUp(miCursorInfoPtr pDevCursor) 1714642e01fSmrg{ 1724642e01fSmrg pDevCursor->isUp = TRUE; 1734642e01fSmrg} 1744642e01fSmrg 1754642e01fSmrgstatic void 1764642e01fSmrgmiSpriteIsDown(miCursorInfoPtr pDevCursor) 1774642e01fSmrg{ 1784642e01fSmrg pDevCursor->isUp = FALSE; 1794642e01fSmrg} 1804642e01fSmrg 18105b261ecSmrg/* 18205b261ecSmrg * screen wrappers 18305b261ecSmrg */ 18405b261ecSmrg 1856747b715Smrgstatic DevPrivateKeyRec miSpriteScreenKeyRec; 1866747b715Smrg#define miSpriteScreenKey (&miSpriteScreenKeyRec) 1876747b715Smrgstatic DevPrivateKeyRec miSpriteDevPrivatesKeyRec; 1886747b715Smrg#define miSpriteDevPrivatesKey (&miSpriteDevPrivatesKeyRec) 18905b261ecSmrg 19005b261ecSmrgstatic Bool miSpriteCloseScreen(int i, ScreenPtr pScreen); 19105b261ecSmrgstatic void miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy, 19205b261ecSmrg int w, int h, unsigned int format, 19305b261ecSmrg unsigned long planemask, char *pdstLine); 19405b261ecSmrgstatic void miSpriteGetSpans(DrawablePtr pDrawable, int wMax, 19505b261ecSmrg DDXPointPtr ppt, int *pwidth, int nspans, 19605b261ecSmrg char *pdstStart); 19705b261ecSmrgstatic void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, 19805b261ecSmrg int width, int height); 19905b261ecSmrgstatic void miSpriteCopyWindow (WindowPtr pWindow, 20005b261ecSmrg DDXPointRec ptOldOrg, 20105b261ecSmrg RegionPtr prgnSrc); 20205b261ecSmrgstatic void miSpriteBlockHandler(int i, pointer blockData, 20305b261ecSmrg pointer pTimeout, 20405b261ecSmrg pointer pReadMask); 20505b261ecSmrgstatic void miSpriteInstallColormap(ColormapPtr pMap); 20605b261ecSmrgstatic void miSpriteStoreColors(ColormapPtr pMap, int ndef, 20705b261ecSmrg xColorItem *pdef); 20805b261ecSmrg 2094642e01fSmrgstatic void miSpriteComputeSaved(DeviceIntPtr pDev, 2104642e01fSmrg ScreenPtr pScreen); 21105b261ecSmrg 2124642e01fSmrgstatic Bool miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, 2134642e01fSmrg ScreenPtr pScreen); 2144642e01fSmrgstatic void miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, 2154642e01fSmrg ScreenPtr pScreen); 21605b261ecSmrg 2174642e01fSmrg#define SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = \ 2184642e01fSmrg ((miSpriteScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, \ 2194642e01fSmrg miSpriteScreenKey))->field) 22005b261ecSmrg#define SCREEN_EPILOGUE(pScreen, field)\ 22105b261ecSmrg ((pScreen)->field = miSprite##field) 22205b261ecSmrg 22305b261ecSmrg/* 22405b261ecSmrg * pointer-sprite method table 22505b261ecSmrg */ 22605b261ecSmrg 2274642e01fSmrgstatic Bool miSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2284642e01fSmrg CursorPtr pCursor); 2294642e01fSmrgstatic Bool miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2304642e01fSmrg CursorPtr pCursor); 2314642e01fSmrgstatic void miSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2324642e01fSmrg CursorPtr pCursor, int x, int y); 2334642e01fSmrgstatic void miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2344642e01fSmrg int x, int y); 23505b261ecSmrg 2366747b715SmrgmiPointerSpriteFuncRec miSpritePointerFuncs = { 23705b261ecSmrg miSpriteRealizeCursor, 23805b261ecSmrg miSpriteUnrealizeCursor, 23905b261ecSmrg miSpriteSetCursor, 24005b261ecSmrg miSpriteMoveCursor, 2414642e01fSmrg miSpriteDeviceCursorInitialize, 2424642e01fSmrg miSpriteDeviceCursorCleanup, 24305b261ecSmrg}; 24405b261ecSmrg 24505b261ecSmrg/* 24605b261ecSmrg * other misc functions 24705b261ecSmrg */ 24805b261ecSmrg 2494642e01fSmrgstatic void miSpriteRemoveCursor(DeviceIntPtr pDev, 2504642e01fSmrg ScreenPtr pScreen); 2514642e01fSmrgstatic void miSpriteSaveUnderCursor(DeviceIntPtr pDev, 2524642e01fSmrg ScreenPtr pScreen); 2534642e01fSmrgstatic void miSpriteRestoreCursor(DeviceIntPtr pDev, 2544642e01fSmrg ScreenPtr pScreen); 25505b261ecSmrg 25605b261ecSmrgstatic void 25705b261ecSmrgmiSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure) 25805b261ecSmrg{ 25905b261ecSmrg ScreenPtr pScreen = closure; 2604642e01fSmrg miCursorInfoPtr pCursorInfo; 2614642e01fSmrg DeviceIntPtr pDev; 2624642e01fSmrg 2634642e01fSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) 26405b261ecSmrg { 2654642e01fSmrg if (DevHasCursor(pDev)) 2664642e01fSmrg { 2674642e01fSmrg pCursorInfo = MISPRITE(pDev); 2684642e01fSmrg 2694642e01fSmrg if (pCursorInfo->isUp && 2704642e01fSmrg pCursorInfo->pScreen == pScreen && 2716747b715Smrg RegionContainsRect(pRegion, &pCursorInfo->saved) != rgnOUT) 2724642e01fSmrg { 2734642e01fSmrg SPRITE_DEBUG(("Damage remove\n")); 2744642e01fSmrg miSpriteRemoveCursor (pDev, pScreen); 2754642e01fSmrg } 2764642e01fSmrg } 27705b261ecSmrg } 27805b261ecSmrg} 27905b261ecSmrg 28005b261ecSmrg/* 28105b261ecSmrg * miSpriteInitialize -- called from device-dependent screen 28205b261ecSmrg * initialization proc after all of the function pointers have 28305b261ecSmrg * been stored in the screen structure. 28405b261ecSmrg */ 28505b261ecSmrg 28605b261ecSmrgBool 2874642e01fSmrgmiSpriteInitialize (ScreenPtr pScreen, 2884642e01fSmrg miPointerScreenFuncPtr screenFuncs) 28905b261ecSmrg{ 29005b261ecSmrg miSpriteScreenPtr pScreenPriv; 29105b261ecSmrg VisualPtr pVisual; 2924642e01fSmrg 29305b261ecSmrg if (!DamageSetup (pScreen)) 29405b261ecSmrg return FALSE; 29505b261ecSmrg 2966747b715Smrg if (!dixRegisterPrivateKey(&miSpriteScreenKeyRec, PRIVATE_SCREEN, 0)) 2976747b715Smrg return FALSE; 2986747b715Smrg 2996747b715Smrg if (!dixRegisterPrivateKey(&miSpriteDevPrivatesKeyRec, PRIVATE_DEVICE, 0)) 3006747b715Smrg return FALSE; 3016747b715Smrg 3026747b715Smrg pScreenPriv = malloc(sizeof (miSpriteScreenRec)); 30305b261ecSmrg if (!pScreenPriv) 30405b261ecSmrg return FALSE; 3054642e01fSmrg 30605b261ecSmrg pScreenPriv->pDamage = DamageCreate (miSpriteReportDamage, 3076747b715Smrg NULL, 30805b261ecSmrg DamageReportRawRegion, 30905b261ecSmrg TRUE, 31005b261ecSmrg pScreen, 3116747b715Smrg pScreen); 31205b261ecSmrg 31305b261ecSmrg if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE)) 31405b261ecSmrg { 3156747b715Smrg free(pScreenPriv); 31605b261ecSmrg return FALSE; 31705b261ecSmrg } 31805b261ecSmrg for (pVisual = pScreen->visuals; 31905b261ecSmrg pVisual->vid != pScreen->rootVisual; 32005b261ecSmrg pVisual++) 32105b261ecSmrg ; 32205b261ecSmrg pScreenPriv->pVisual = pVisual; 32305b261ecSmrg pScreenPriv->CloseScreen = pScreen->CloseScreen; 32405b261ecSmrg pScreenPriv->GetImage = pScreen->GetImage; 32505b261ecSmrg pScreenPriv->GetSpans = pScreen->GetSpans; 32605b261ecSmrg pScreenPriv->SourceValidate = pScreen->SourceValidate; 32705b261ecSmrg 32805b261ecSmrg pScreenPriv->CopyWindow = pScreen->CopyWindow; 3294642e01fSmrg 33005b261ecSmrg pScreenPriv->InstallColormap = pScreen->InstallColormap; 33105b261ecSmrg pScreenPriv->StoreColors = pScreen->StoreColors; 3324642e01fSmrg 33305b261ecSmrg pScreenPriv->BlockHandler = pScreen->BlockHandler; 3344642e01fSmrg 3354642e01fSmrg pScreenPriv->DeviceCursorInitialize = pScreen->DeviceCursorInitialize; 3364642e01fSmrg pScreenPriv->DeviceCursorCleanup = pScreen->DeviceCursorCleanup; 3374642e01fSmrg 33805b261ecSmrg pScreenPriv->pInstalledMap = NULL; 33905b261ecSmrg pScreenPriv->pColormap = NULL; 34005b261ecSmrg pScreenPriv->colors[SOURCE_COLOR].red = 0; 34105b261ecSmrg pScreenPriv->colors[SOURCE_COLOR].green = 0; 34205b261ecSmrg pScreenPriv->colors[SOURCE_COLOR].blue = 0; 34305b261ecSmrg pScreenPriv->colors[MASK_COLOR].red = 0; 34405b261ecSmrg pScreenPriv->colors[MASK_COLOR].green = 0; 34505b261ecSmrg pScreenPriv->colors[MASK_COLOR].blue = 0; 3466747b715Smrg pScreenPriv->damageRegistered = 0; 3476747b715Smrg 3484642e01fSmrg dixSetPrivate(&pScreen->devPrivates, miSpriteScreenKey, pScreenPriv); 3494642e01fSmrg 35005b261ecSmrg pScreen->CloseScreen = miSpriteCloseScreen; 35105b261ecSmrg pScreen->GetImage = miSpriteGetImage; 35205b261ecSmrg pScreen->GetSpans = miSpriteGetSpans; 35305b261ecSmrg pScreen->SourceValidate = miSpriteSourceValidate; 3544642e01fSmrg 35505b261ecSmrg pScreen->CopyWindow = miSpriteCopyWindow; 35605b261ecSmrg pScreen->InstallColormap = miSpriteInstallColormap; 35705b261ecSmrg pScreen->StoreColors = miSpriteStoreColors; 35805b261ecSmrg 35905b261ecSmrg pScreen->BlockHandler = miSpriteBlockHandler; 3604642e01fSmrg 36105b261ecSmrg return TRUE; 36205b261ecSmrg} 36305b261ecSmrg 36405b261ecSmrg/* 36505b261ecSmrg * Screen wrappers 36605b261ecSmrg */ 36705b261ecSmrg 36805b261ecSmrg/* 36905b261ecSmrg * CloseScreen wrapper -- unwrap everything, free the private data 37005b261ecSmrg * and call the wrapped function 37105b261ecSmrg */ 37205b261ecSmrg 37305b261ecSmrgstatic Bool 3744642e01fSmrgmiSpriteCloseScreen (int i, ScreenPtr pScreen) 37505b261ecSmrg{ 37605b261ecSmrg miSpriteScreenPtr pScreenPriv; 37705b261ecSmrg 3786747b715Smrg pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey); 37905b261ecSmrg pScreen->CloseScreen = pScreenPriv->CloseScreen; 38005b261ecSmrg pScreen->GetImage = pScreenPriv->GetImage; 38105b261ecSmrg pScreen->GetSpans = pScreenPriv->GetSpans; 38205b261ecSmrg pScreen->SourceValidate = pScreenPriv->SourceValidate; 38305b261ecSmrg pScreen->BlockHandler = pScreenPriv->BlockHandler; 38405b261ecSmrg pScreen->InstallColormap = pScreenPriv->InstallColormap; 38505b261ecSmrg pScreen->StoreColors = pScreenPriv->StoreColors; 38605b261ecSmrg 38705b261ecSmrg DamageDestroy (pScreenPriv->pDamage); 3884642e01fSmrg 3896747b715Smrg free(pScreenPriv); 39005b261ecSmrg 39105b261ecSmrg return (*pScreen->CloseScreen) (i, pScreen); 39205b261ecSmrg} 39305b261ecSmrg 39405b261ecSmrgstatic void 3954642e01fSmrgmiSpriteGetImage (DrawablePtr pDrawable, int sx, int sy, int w, int h, 3964642e01fSmrg unsigned int format, unsigned long planemask, 3974642e01fSmrg char *pdstLine) 39805b261ecSmrg{ 39905b261ecSmrg ScreenPtr pScreen = pDrawable->pScreen; 4006747b715Smrg DeviceIntPtr pDev; 4014642e01fSmrg miCursorInfoPtr pCursorInfo; 40205b261ecSmrg 4034642e01fSmrg SCREEN_PROLOGUE (pScreen, GetImage); 40405b261ecSmrg 4056747b715Smrg if (pDrawable->type == DRAWABLE_WINDOW) 40605b261ecSmrg { 4076747b715Smrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 4084642e01fSmrg { 4096747b715Smrg if (DevHasCursor(pDev)) 4106747b715Smrg { 4116747b715Smrg pCursorInfo = MISPRITE(pDev); 4126747b715Smrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 4136747b715Smrg ORG_OVERLAP(&pCursorInfo->saved,pDrawable->x,pDrawable->y, 4146747b715Smrg sx, sy, w, h)) 4156747b715Smrg { 4166747b715Smrg SPRITE_DEBUG (("GetImage remove\n")); 4176747b715Smrg miSpriteRemoveCursor (pDev, pScreen); 4186747b715Smrg } 4196747b715Smrg } 4204642e01fSmrg } 42105b261ecSmrg } 42205b261ecSmrg 42305b261ecSmrg (*pScreen->GetImage) (pDrawable, sx, sy, w, h, 42405b261ecSmrg format, planemask, pdstLine); 42505b261ecSmrg 42605b261ecSmrg SCREEN_EPILOGUE (pScreen, GetImage); 42705b261ecSmrg} 42805b261ecSmrg 42905b261ecSmrgstatic void 4304642e01fSmrgmiSpriteGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, 4314642e01fSmrg int *pwidth, int nspans, char *pdstStart) 43205b261ecSmrg{ 43305b261ecSmrg ScreenPtr pScreen = pDrawable->pScreen; 4346747b715Smrg DeviceIntPtr pDev; 4354642e01fSmrg miCursorInfoPtr pCursorInfo; 4364642e01fSmrg 43705b261ecSmrg SCREEN_PROLOGUE (pScreen, GetSpans); 43805b261ecSmrg 4396747b715Smrg if (pDrawable->type == DRAWABLE_WINDOW) 44005b261ecSmrg { 4416747b715Smrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 4424642e01fSmrg { 4436747b715Smrg if (DevHasCursor(pDev)) 4444642e01fSmrg { 4456747b715Smrg pCursorInfo = MISPRITE(pDev); 4466747b715Smrg 4476747b715Smrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) 4484642e01fSmrg { 4496747b715Smrg DDXPointPtr pts; 4506747b715Smrg int *widths; 4516747b715Smrg int nPts; 4526747b715Smrg int xorg, 4536747b715Smrg yorg; 4546747b715Smrg 4556747b715Smrg xorg = pDrawable->x; 4566747b715Smrg yorg = pDrawable->y; 4576747b715Smrg 4586747b715Smrg for (pts = ppt, widths = pwidth, nPts = nspans; 4596747b715Smrg nPts--; 4606747b715Smrg pts++, widths++) 4614642e01fSmrg { 4626747b715Smrg if (SPN_OVERLAP(&pCursorInfo->saved,pts->y+yorg, 4636747b715Smrg pts->x+xorg,*widths)) 4646747b715Smrg { 4656747b715Smrg SPRITE_DEBUG (("GetSpans remove\n")); 4666747b715Smrg miSpriteRemoveCursor (pDev, pScreen); 4676747b715Smrg break; 4686747b715Smrg } 4694642e01fSmrg } 4704642e01fSmrg } 4714642e01fSmrg } 4724642e01fSmrg } 47305b261ecSmrg } 47405b261ecSmrg 47505b261ecSmrg (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); 47605b261ecSmrg 47705b261ecSmrg SCREEN_EPILOGUE (pScreen, GetSpans); 47805b261ecSmrg} 47905b261ecSmrg 48005b261ecSmrgstatic void 4814642e01fSmrgmiSpriteSourceValidate (DrawablePtr pDrawable, int x, int y, int width, 4824642e01fSmrg int height) 48305b261ecSmrg{ 48405b261ecSmrg ScreenPtr pScreen = pDrawable->pScreen; 4856747b715Smrg DeviceIntPtr pDev; 4864642e01fSmrg miCursorInfoPtr pCursorInfo; 4874642e01fSmrg 48805b261ecSmrg SCREEN_PROLOGUE (pScreen, SourceValidate); 48905b261ecSmrg 4906747b715Smrg if (pDrawable->type == DRAWABLE_WINDOW) 49105b261ecSmrg { 4926747b715Smrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 4936747b715Smrg { 4946747b715Smrg if (DevHasCursor(pDev)) 4956747b715Smrg { 4966747b715Smrg pCursorInfo = MISPRITE(pDev); 4976747b715Smrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 4986747b715Smrg ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y, 4996747b715Smrg x, y, width, height)) 5006747b715Smrg { 5016747b715Smrg SPRITE_DEBUG (("SourceValidate remove\n")); 5026747b715Smrg miSpriteRemoveCursor (pDev, pScreen); 5036747b715Smrg } 5046747b715Smrg } 5056747b715Smrg } 50605b261ecSmrg } 50705b261ecSmrg 50805b261ecSmrg if (pScreen->SourceValidate) 50905b261ecSmrg (*pScreen->SourceValidate) (pDrawable, x, y, width, height); 51005b261ecSmrg 51105b261ecSmrg SCREEN_EPILOGUE (pScreen, SourceValidate); 51205b261ecSmrg} 51305b261ecSmrg 51405b261ecSmrgstatic void 51505b261ecSmrgmiSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) 51605b261ecSmrg{ 51705b261ecSmrg ScreenPtr pScreen = pWindow->drawable.pScreen; 5186747b715Smrg DeviceIntPtr pDev; 5194642e01fSmrg miCursorInfoPtr pCursorInfo; 5204642e01fSmrg 52105b261ecSmrg SCREEN_PROLOGUE (pScreen, CopyWindow); 52205b261ecSmrg 5234642e01fSmrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 52405b261ecSmrg { 5254642e01fSmrg if (DevHasCursor(pDev)) 5264642e01fSmrg { 5274642e01fSmrg pCursorInfo = MISPRITE(pDev); 5284642e01fSmrg /* 5294642e01fSmrg * Damage will take care of destination check 5304642e01fSmrg */ 5314642e01fSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 5326747b715Smrg RegionContainsRect(prgnSrc, &pCursorInfo->saved) != rgnOUT) 5334642e01fSmrg { 5344642e01fSmrg SPRITE_DEBUG (("CopyWindow remove\n")); 5354642e01fSmrg miSpriteRemoveCursor (pDev, pScreen); 5364642e01fSmrg } 5374642e01fSmrg } 53805b261ecSmrg } 53905b261ecSmrg 54005b261ecSmrg (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc); 54105b261ecSmrg SCREEN_EPILOGUE (pScreen, CopyWindow); 54205b261ecSmrg} 54305b261ecSmrg 54405b261ecSmrgstatic void 5454642e01fSmrgmiSpriteBlockHandler (int i, pointer blockData, pointer pTimeout, 5464642e01fSmrg pointer pReadmask) 54705b261ecSmrg{ 54805b261ecSmrg ScreenPtr pScreen = screenInfo.screens[i]; 54905b261ecSmrg miSpriteScreenPtr pPriv; 5506747b715Smrg DeviceIntPtr pDev; 5514642e01fSmrg miCursorInfoPtr pCursorInfo; 55205b261ecSmrg 5536747b715Smrg pPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey); 55405b261ecSmrg SCREEN_PROLOGUE(pScreen, BlockHandler); 5554642e01fSmrg 55605b261ecSmrg (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 55705b261ecSmrg 55805b261ecSmrg SCREEN_EPILOGUE(pScreen, BlockHandler); 55905b261ecSmrg 5604642e01fSmrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 5614642e01fSmrg { 5624642e01fSmrg if (DevHasCursor(pDev)) 5634642e01fSmrg { 5644642e01fSmrg pCursorInfo = MISPRITE(pDev); 5654642e01fSmrg if (pCursorInfo && !pCursorInfo->isUp 5664642e01fSmrg && pCursorInfo->pScreen == pScreen 5674642e01fSmrg && pCursorInfo->shouldBeUp) 5684642e01fSmrg { 5698223e2f2Smrg SPRITE_DEBUG (("BlockHandler save")); 5704642e01fSmrg miSpriteSaveUnderCursor (pDev, pScreen); 5714642e01fSmrg } 5724642e01fSmrg } 5734642e01fSmrg } 5744642e01fSmrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 57505b261ecSmrg { 5764642e01fSmrg if (DevHasCursor(pDev)) 5774642e01fSmrg { 5784642e01fSmrg pCursorInfo = MISPRITE(pDev); 5794642e01fSmrg if (pCursorInfo && !pCursorInfo->isUp && 5804642e01fSmrg pCursorInfo->pScreen == pScreen && 5814642e01fSmrg pCursorInfo->shouldBeUp) 5824642e01fSmrg { 5834642e01fSmrg SPRITE_DEBUG (("BlockHandler restore\n")); 5844642e01fSmrg miSpriteRestoreCursor (pDev, pScreen); 5854642e01fSmrg } 5864642e01fSmrg } 58705b261ecSmrg } 58805b261ecSmrg} 58905b261ecSmrg 59005b261ecSmrgstatic void 5914642e01fSmrgmiSpriteInstallColormap (ColormapPtr pMap) 59205b261ecSmrg{ 59305b261ecSmrg ScreenPtr pScreen = pMap->pScreen; 59405b261ecSmrg miSpriteScreenPtr pPriv; 59505b261ecSmrg 5966747b715Smrg pPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey); 59705b261ecSmrg SCREEN_PROLOGUE(pScreen, InstallColormap); 5984642e01fSmrg 59905b261ecSmrg (*pScreen->InstallColormap) (pMap); 60005b261ecSmrg 60105b261ecSmrg SCREEN_EPILOGUE(pScreen, InstallColormap); 60205b261ecSmrg 6034642e01fSmrg /* InstallColormap can be called before devices are initialized. */ 60405b261ecSmrg pPriv->pInstalledMap = pMap; 60505b261ecSmrg if (pPriv->pColormap != pMap) 60605b261ecSmrg { 6074642e01fSmrg DeviceIntPtr pDev; 6084642e01fSmrg miCursorInfoPtr pCursorInfo; 6094642e01fSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) 6104642e01fSmrg { 6114642e01fSmrg if (DevHasCursor(pDev)) 6124642e01fSmrg { 6134642e01fSmrg pCursorInfo = MISPRITE(pDev); 6144642e01fSmrg pCursorInfo->checkPixels = TRUE; 6154642e01fSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) 6164642e01fSmrg miSpriteRemoveCursor(pDev, pScreen); 6174642e01fSmrg } 6184642e01fSmrg } 6194642e01fSmrg 62005b261ecSmrg } 62105b261ecSmrg} 62205b261ecSmrg 62305b261ecSmrgstatic void 6244642e01fSmrgmiSpriteStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef) 62505b261ecSmrg{ 62605b261ecSmrg ScreenPtr pScreen = pMap->pScreen; 62705b261ecSmrg miSpriteScreenPtr pPriv; 62805b261ecSmrg int i; 62905b261ecSmrg int updated; 63005b261ecSmrg VisualPtr pVisual; 6316747b715Smrg DeviceIntPtr pDev; 6324642e01fSmrg miCursorInfoPtr pCursorInfo; 63305b261ecSmrg 6346747b715Smrg pPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey); 63505b261ecSmrg SCREEN_PROLOGUE(pScreen, StoreColors); 6364642e01fSmrg 63705b261ecSmrg (*pScreen->StoreColors) (pMap, ndef, pdef); 63805b261ecSmrg 63905b261ecSmrg SCREEN_EPILOGUE(pScreen, StoreColors); 64005b261ecSmrg 64105b261ecSmrg if (pPriv->pColormap == pMap) 64205b261ecSmrg { 6434642e01fSmrg updated = 0; 6444642e01fSmrg pVisual = pMap->pVisual; 6454642e01fSmrg if (pVisual->class == DirectColor) 6464642e01fSmrg { 6474642e01fSmrg /* Direct color - match on any of the subfields */ 64805b261ecSmrg 64905b261ecSmrg#define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask))) 65005b261ecSmrg 6514642e01fSmrg#define UpdateDAC(dev, plane,dac,mask) {\ 6524642e01fSmrg if (MaskMatch (dev->colors[plane].pixel,pdef[i].pixel,mask)) {\ 6534642e01fSmrg dev->colors[plane].dac = pdef[i].dac; \ 65405b261ecSmrg updated = 1; \ 65505b261ecSmrg } \ 65605b261ecSmrg} 65705b261ecSmrg 6584642e01fSmrg#define CheckDirect(dev, plane) \ 6594642e01fSmrg UpdateDAC(dev, plane,red,redMask) \ 6604642e01fSmrg UpdateDAC(dev, plane,green,greenMask) \ 6614642e01fSmrg UpdateDAC(dev, plane,blue,blueMask) 6624642e01fSmrg 6634642e01fSmrg for (i = 0; i < ndef; i++) 6644642e01fSmrg { 6654642e01fSmrg CheckDirect (pPriv, SOURCE_COLOR) 6664642e01fSmrg CheckDirect (pPriv, MASK_COLOR) 6674642e01fSmrg } 6684642e01fSmrg } 6694642e01fSmrg else 6704642e01fSmrg { 6714642e01fSmrg /* PseudoColor/GrayScale - match on exact pixel */ 6724642e01fSmrg for (i = 0; i < ndef; i++) 6734642e01fSmrg { 6744642e01fSmrg if (pdef[i].pixel == 6754642e01fSmrg pPriv->colors[SOURCE_COLOR].pixel) 6764642e01fSmrg { 6774642e01fSmrg pPriv->colors[SOURCE_COLOR] = pdef[i]; 6784642e01fSmrg if (++updated == 2) 6794642e01fSmrg break; 6804642e01fSmrg } 6814642e01fSmrg if (pdef[i].pixel == 6824642e01fSmrg pPriv->colors[MASK_COLOR].pixel) 6834642e01fSmrg { 6844642e01fSmrg pPriv->colors[MASK_COLOR] = pdef[i]; 6854642e01fSmrg if (++updated == 2) 6864642e01fSmrg break; 6874642e01fSmrg } 6884642e01fSmrg } 6894642e01fSmrg } 6904642e01fSmrg if (updated) 6914642e01fSmrg { 6924642e01fSmrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 6934642e01fSmrg { 6944642e01fSmrg if (DevHasCursor(pDev)) 6954642e01fSmrg { 6964642e01fSmrg pCursorInfo = MISPRITE(pDev); 6974642e01fSmrg pCursorInfo->checkPixels = TRUE; 6984642e01fSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) 6994642e01fSmrg miSpriteRemoveCursor (pDev, pScreen); 7004642e01fSmrg } 7014642e01fSmrg } 7024642e01fSmrg } 70305b261ecSmrg } 70405b261ecSmrg} 70505b261ecSmrg 70605b261ecSmrgstatic void 7074642e01fSmrgmiSpriteFindColors (miCursorInfoPtr pDevCursor, ScreenPtr pScreen) 70805b261ecSmrg{ 7096747b715Smrg miSpriteScreenPtr pScreenPriv = 7104642e01fSmrg dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey); 71105b261ecSmrg CursorPtr pCursor; 71205b261ecSmrg xColorItem *sourceColor, *maskColor; 71305b261ecSmrg 7144642e01fSmrg pCursor = pDevCursor->pCursor; 71505b261ecSmrg sourceColor = &pScreenPriv->colors[SOURCE_COLOR]; 71605b261ecSmrg maskColor = &pScreenPriv->colors[MASK_COLOR]; 71705b261ecSmrg if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap || 71805b261ecSmrg !(pCursor->foreRed == sourceColor->red && 71905b261ecSmrg pCursor->foreGreen == sourceColor->green && 72005b261ecSmrg pCursor->foreBlue == sourceColor->blue && 72105b261ecSmrg pCursor->backRed == maskColor->red && 72205b261ecSmrg pCursor->backGreen == maskColor->green && 72305b261ecSmrg pCursor->backBlue == maskColor->blue)) 72405b261ecSmrg { 72505b261ecSmrg pScreenPriv->pColormap = pScreenPriv->pInstalledMap; 72605b261ecSmrg sourceColor->red = pCursor->foreRed; 72705b261ecSmrg sourceColor->green = pCursor->foreGreen; 72805b261ecSmrg sourceColor->blue = pCursor->foreBlue; 72905b261ecSmrg FakeAllocColor (pScreenPriv->pColormap, sourceColor); 73005b261ecSmrg maskColor->red = pCursor->backRed; 73105b261ecSmrg maskColor->green = pCursor->backGreen; 73205b261ecSmrg maskColor->blue = pCursor->backBlue; 73305b261ecSmrg FakeAllocColor (pScreenPriv->pColormap, maskColor); 73405b261ecSmrg /* "free" the pixels right away, don't let this confuse you */ 73505b261ecSmrg FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel); 73605b261ecSmrg FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel); 73705b261ecSmrg } 73805b261ecSmrg 7394642e01fSmrg pDevCursor->checkPixels = FALSE; 74005b261ecSmrg 74105b261ecSmrg} 74205b261ecSmrg 74305b261ecSmrg/* 74405b261ecSmrg * miPointer interface routines 74505b261ecSmrg */ 74605b261ecSmrg 74705b261ecSmrg#define SPRITE_PAD 8 74805b261ecSmrg 74905b261ecSmrgstatic Bool 7504642e01fSmrgmiSpriteRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 75105b261ecSmrg{ 7524642e01fSmrg miCursorInfoPtr pCursorInfo; 7534642e01fSmrg 7546747b715Smrg if (!IsMaster(pDev) && !pDev->u.master) 7554642e01fSmrg return FALSE; 7566747b715Smrg 7574642e01fSmrg pCursorInfo = MISPRITE(pDev); 7584642e01fSmrg 7594642e01fSmrg if (pCursor == pCursorInfo->pCursor) 7604642e01fSmrg pCursorInfo->checkPixels = TRUE; 76105b261ecSmrg 7626747b715Smrg return miDCRealizeCursor(pScreen, pCursor); 76305b261ecSmrg} 76405b261ecSmrg 76505b261ecSmrgstatic Bool 7664642e01fSmrgmiSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 76705b261ecSmrg{ 7686747b715Smrg return miDCUnrealizeCursor(pScreen, pCursor); 76905b261ecSmrg} 77005b261ecSmrg 77105b261ecSmrgstatic void 7724642e01fSmrgmiSpriteSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, 7734642e01fSmrg CursorPtr pCursor, int x, int y) 77405b261ecSmrg{ 7754642e01fSmrg miCursorInfoPtr pPointer; 7764642e01fSmrg 7776747b715Smrg if (!IsMaster(pDev) && !pDev->u.master) 7784642e01fSmrg return; 7796747b715Smrg 7804642e01fSmrg pPointer = MISPRITE(pDev); 7814642e01fSmrg 78205b261ecSmrg if (!pCursor) 78305b261ecSmrg { 7844642e01fSmrg pPointer->shouldBeUp = FALSE; 7854642e01fSmrg if (pPointer->isUp) 7864642e01fSmrg miSpriteRemoveCursor (pDev, pScreen); 7874642e01fSmrg pPointer->pCursor = 0; 78805b261ecSmrg return; 78905b261ecSmrg } 7904642e01fSmrg pPointer->shouldBeUp = TRUE; 7914642e01fSmrg if (pPointer->x == x && 7924642e01fSmrg pPointer->y == y && 7934642e01fSmrg pPointer->pCursor == pCursor && 7944642e01fSmrg !pPointer->checkPixels) 79505b261ecSmrg { 79605b261ecSmrg return; 79705b261ecSmrg } 7984642e01fSmrg pPointer->x = x; 7994642e01fSmrg pPointer->y = y; 8004642e01fSmrg pPointer->pCacheWin = NullWindow; 8014642e01fSmrg if (pPointer->checkPixels || pPointer->pCursor != pCursor) 80205b261ecSmrg { 8034642e01fSmrg pPointer->pCursor = pCursor; 8044642e01fSmrg miSpriteFindColors (pPointer, pScreen); 80505b261ecSmrg } 8064642e01fSmrg if (pPointer->isUp) { 8076747b715Smrg /* TODO: reimplement flicker-free MoveCursor */ 8086747b715Smrg SPRITE_DEBUG (("SetCursor remove %d\n", pDev->id)); 8096747b715Smrg miSpriteRemoveCursor (pDev, pScreen); 81005b261ecSmrg } 8114642e01fSmrg 8124642e01fSmrg if (!pPointer->isUp && pPointer->pCursor) 81305b261ecSmrg { 8144642e01fSmrg SPRITE_DEBUG (("SetCursor restore %d\n", pDev->id)); 8154642e01fSmrg miSpriteSaveUnderCursor(pDev, pScreen); 8164642e01fSmrg miSpriteRestoreCursor (pDev, pScreen); 81705b261ecSmrg } 8184642e01fSmrg 81905b261ecSmrg} 82005b261ecSmrg 82105b261ecSmrgstatic void 8224642e01fSmrgmiSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 82305b261ecSmrg{ 8244642e01fSmrg CursorPtr pCursor; 82505b261ecSmrg 8266747b715Smrg if (!IsMaster(pDev) && !pDev->u.master) 8274642e01fSmrg return; 8286747b715Smrg 8294642e01fSmrg pCursor = MISPRITE(pDev)->pCursor; 8304642e01fSmrg 8314642e01fSmrg miSpriteSetCursor (pDev, pScreen, pCursor, x, y); 8324642e01fSmrg} 8334642e01fSmrg 8344642e01fSmrg 8354642e01fSmrgstatic Bool 8364642e01fSmrgmiSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) 8374642e01fSmrg{ 8384642e01fSmrg miCursorInfoPtr pCursorInfo; 8394642e01fSmrg int ret = FALSE; 8404642e01fSmrg 8416747b715Smrg pCursorInfo = malloc(sizeof(miCursorInfoRec)); 8424642e01fSmrg if (!pCursorInfo) 8434642e01fSmrg return FALSE; 8444642e01fSmrg 8454642e01fSmrg pCursorInfo->pCursor = NULL; 8464642e01fSmrg pCursorInfo->x = 0; 8474642e01fSmrg pCursorInfo->y = 0; 8484642e01fSmrg pCursorInfo->isUp = FALSE; 8494642e01fSmrg pCursorInfo->shouldBeUp = FALSE; 8504642e01fSmrg pCursorInfo->pCacheWin = NullWindow; 8514642e01fSmrg pCursorInfo->isInCacheWin = FALSE; 8524642e01fSmrg pCursorInfo->checkPixels = TRUE; 8534642e01fSmrg pCursorInfo->pScreen = FALSE; 8544642e01fSmrg 8556747b715Smrg ret = miDCDeviceInitialize(pDev, pScreen); 8564642e01fSmrg if (!ret) 8574642e01fSmrg { 8586747b715Smrg free(pCursorInfo); 8594642e01fSmrg pCursorInfo = NULL; 8604642e01fSmrg } 8614642e01fSmrg dixSetPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey, pCursorInfo); 8624642e01fSmrg return ret; 8634642e01fSmrg} 8644642e01fSmrg 8654642e01fSmrgstatic void 8664642e01fSmrgmiSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) 8674642e01fSmrg{ 8684642e01fSmrg if (DevHasCursor(pDev)) 8696747b715Smrg miDCDeviceCleanup(pDev, pScreen); 87005b261ecSmrg} 87105b261ecSmrg 87205b261ecSmrg/* 87305b261ecSmrg * undraw/draw cursor 87405b261ecSmrg */ 87505b261ecSmrg 87605b261ecSmrgstatic void 8774642e01fSmrgmiSpriteRemoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen) 87805b261ecSmrg{ 87905b261ecSmrg miSpriteScreenPtr pScreenPriv; 8804642e01fSmrg miCursorInfoPtr pCursorInfo; 8814642e01fSmrg 88205b261ecSmrg 8836747b715Smrg if (!IsMaster(pDev) && !pDev->u.master) 8844642e01fSmrg return; 8856747b715Smrg 88605b261ecSmrg DamageDrawInternal (pScreen, TRUE); 8876747b715Smrg pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey); 8884642e01fSmrg pCursorInfo = MISPRITE(pDev); 8894642e01fSmrg 8904642e01fSmrg miSpriteIsDown(pCursorInfo); 8914642e01fSmrg pCursorInfo->pCacheWin = NullWindow; 8924642e01fSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 8936747b715Smrg if (!miDCRestoreUnderCursor(pDev, 8946747b715Smrg pScreen, 8956747b715Smrg pCursorInfo->saved.x1, 8966747b715Smrg pCursorInfo->saved.y1, 8976747b715Smrg pCursorInfo->saved.x2 - 8986747b715Smrg pCursorInfo->saved.x1, 8996747b715Smrg pCursorInfo->saved.y2 - 9006747b715Smrg pCursorInfo->saved.y1)) 90105b261ecSmrg { 9026747b715Smrg miSpriteIsUp(pCursorInfo); 90305b261ecSmrg } 9044642e01fSmrg miSpriteEnableDamage(pScreen, pScreenPriv); 90505b261ecSmrg DamageDrawInternal (pScreen, FALSE); 90605b261ecSmrg} 90705b261ecSmrg 9084642e01fSmrg/* 9094642e01fSmrg * Called from the block handler, saves area under cursor 9104642e01fSmrg * before waiting for something to do. 9114642e01fSmrg */ 9124642e01fSmrg 9134642e01fSmrgstatic void 9144642e01fSmrgmiSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen) 9154642e01fSmrg{ 9164642e01fSmrg miSpriteScreenPtr pScreenPriv; 9174642e01fSmrg int x, y; 9184642e01fSmrg CursorPtr pCursor; 9194642e01fSmrg miCursorInfoPtr pCursorInfo; 9204642e01fSmrg 9216747b715Smrg if (!IsMaster(pDev) && !pDev->u.master) 9224642e01fSmrg return; 9236747b715Smrg 9244642e01fSmrg DamageDrawInternal (pScreen, TRUE); 9256747b715Smrg pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey); 9264642e01fSmrg pCursorInfo = MISPRITE(pDev); 9274642e01fSmrg 9284642e01fSmrg miSpriteComputeSaved (pDev, pScreen); 9294642e01fSmrg pCursor = pCursorInfo->pCursor; 9304642e01fSmrg 9314642e01fSmrg x = pCursorInfo->x - (int)pCursor->bits->xhot; 9324642e01fSmrg y = pCursorInfo->y - (int)pCursor->bits->yhot; 9334642e01fSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 9344642e01fSmrg 9356747b715Smrg miDCSaveUnderCursor(pDev, 9366747b715Smrg pScreen, 9376747b715Smrg pCursorInfo->saved.x1, 9386747b715Smrg pCursorInfo->saved.y1, 9396747b715Smrg pCursorInfo->saved.x2 - 9406747b715Smrg pCursorInfo->saved.x1, 9416747b715Smrg pCursorInfo->saved.y2 - 9426747b715Smrg pCursorInfo->saved.y1); 9434642e01fSmrg SPRITE_DEBUG(("SaveUnderCursor %d\n", pDev->id)); 9444642e01fSmrg miSpriteEnableDamage(pScreen, pScreenPriv); 9454642e01fSmrg DamageDrawInternal (pScreen, FALSE); 9464642e01fSmrg} 9474642e01fSmrg 9484642e01fSmrg 94905b261ecSmrg/* 95005b261ecSmrg * Called from the block handler, restores the cursor 95105b261ecSmrg * before waiting for something to do. 95205b261ecSmrg */ 95305b261ecSmrg 95405b261ecSmrgstatic void 9554642e01fSmrgmiSpriteRestoreCursor (DeviceIntPtr pDev, ScreenPtr pScreen) 95605b261ecSmrg{ 95705b261ecSmrg miSpriteScreenPtr pScreenPriv; 95805b261ecSmrg int x, y; 95905b261ecSmrg CursorPtr pCursor; 9604642e01fSmrg miCursorInfoPtr pCursorInfo; 9614642e01fSmrg 9626747b715Smrg if (!IsMaster(pDev) && !pDev->u.master) 9634642e01fSmrg return; 96405b261ecSmrg 96505b261ecSmrg DamageDrawInternal (pScreen, TRUE); 9666747b715Smrg pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey); 9674642e01fSmrg pCursorInfo = MISPRITE(pDev); 9684642e01fSmrg 9694642e01fSmrg miSpriteComputeSaved (pDev, pScreen); 9704642e01fSmrg pCursor = pCursorInfo->pCursor; 9714642e01fSmrg 9724642e01fSmrg x = pCursorInfo->x - (int)pCursor->bits->xhot; 9734642e01fSmrg y = pCursorInfo->y - (int)pCursor->bits->yhot; 9744642e01fSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 9754642e01fSmrg SPRITE_DEBUG(("RestoreCursor %d\n", pDev->id)); 9764642e01fSmrg if (pCursorInfo->checkPixels) 9774642e01fSmrg miSpriteFindColors (pCursorInfo, pScreen); 9786747b715Smrg if (miDCPutUpCursor(pDev, pScreen, 9794642e01fSmrg pCursor, x, y, 9804642e01fSmrg pScreenPriv->colors[SOURCE_COLOR].pixel, 9814642e01fSmrg pScreenPriv->colors[MASK_COLOR].pixel)) 98205b261ecSmrg { 9834642e01fSmrg miSpriteIsUp(pCursorInfo); 9844642e01fSmrg pCursorInfo->pScreen = pScreen; 98505b261ecSmrg } 9864642e01fSmrg miSpriteEnableDamage(pScreen, pScreenPriv); 98705b261ecSmrg DamageDrawInternal (pScreen, FALSE); 98805b261ecSmrg} 98905b261ecSmrg 99005b261ecSmrg/* 99105b261ecSmrg * compute the desired area of the screen to save 99205b261ecSmrg */ 99305b261ecSmrg 99405b261ecSmrgstatic void 9954642e01fSmrgmiSpriteComputeSaved (DeviceIntPtr pDev, ScreenPtr pScreen) 99605b261ecSmrg{ 99705b261ecSmrg int x, y, w, h; 99805b261ecSmrg int wpad, hpad; 99905b261ecSmrg CursorPtr pCursor; 10004642e01fSmrg miCursorInfoPtr pCursorInfo; 100105b261ecSmrg 10026747b715Smrg if (!IsMaster(pDev) && !pDev->u.master) 10034642e01fSmrg return; 10046747b715Smrg 10054642e01fSmrg pCursorInfo = MISPRITE(pDev); 10064642e01fSmrg 10074642e01fSmrg pCursor = pCursorInfo->pCursor; 10084642e01fSmrg x = pCursorInfo->x - (int)pCursor->bits->xhot; 10094642e01fSmrg y = pCursorInfo->y - (int)pCursor->bits->yhot; 101005b261ecSmrg w = pCursor->bits->width; 101105b261ecSmrg h = pCursor->bits->height; 101205b261ecSmrg wpad = SPRITE_PAD; 101305b261ecSmrg hpad = SPRITE_PAD; 10144642e01fSmrg pCursorInfo->saved.x1 = x - wpad; 10154642e01fSmrg pCursorInfo->saved.y1 = y - hpad; 10164642e01fSmrg pCursorInfo->saved.x2 = pCursorInfo->saved.x1 + w + wpad * 2; 10174642e01fSmrg pCursorInfo->saved.y2 = pCursorInfo->saved.y1 + h + hpad * 2; 101805b261ecSmrg} 10194642e01fSmrg 1020