misprite.c revision 9ace9065
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; 999ace9065Smrg int numberOfCursors; 1006747b715Smrg} miSpriteScreenRec, *miSpriteScreenPtr; 1016747b715Smrg 1026747b715Smrg#define SOURCE_COLOR 0 1036747b715Smrg#define MASK_COLOR 1 1046747b715Smrg 1056747b715Smrg/* 1066747b715Smrg * Overlap BoxPtr and Box elements 1076747b715Smrg */ 1086747b715Smrg#define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \ 1096747b715Smrg (((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \ 1106747b715Smrg ((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2)) 1116747b715Smrg 1126747b715Smrg/* 1136747b715Smrg * Overlap BoxPtr, origins, and rectangle 1146747b715Smrg */ 1156747b715Smrg#define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \ 1166747b715Smrg BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h)) 1176747b715Smrg 1186747b715Smrg/* 1196747b715Smrg * Overlap BoxPtr, origins and RectPtr 1206747b715Smrg */ 1216747b715Smrg#define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \ 1226747b715Smrg ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y, \ 1236747b715Smrg (int)((pRect)->width), (int)((pRect)->height)) 1246747b715Smrg/* 1256747b715Smrg * Overlap BoxPtr and horizontal span 1266747b715Smrg */ 1276747b715Smrg#define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y)) 12805b261ecSmrg 1296747b715Smrg#define LINE_SORT(x1,y1,x2,y2) \ 1306747b715Smrg{ int _t; \ 1316747b715Smrg if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \ 1326747b715Smrg if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } } 1336747b715Smrg 1346747b715Smrg#define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \ 1356747b715Smrg BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2)) 1364642e01fSmrg 1374642e01fSmrg 13805b261ecSmrg#define SPRITE_DEBUG_ENABLE 0 13905b261ecSmrg#if SPRITE_DEBUG_ENABLE 14005b261ecSmrg#define SPRITE_DEBUG(x) ErrorF x 14105b261ecSmrg#else 14205b261ecSmrg#define SPRITE_DEBUG(x) 14305b261ecSmrg#endif 14405b261ecSmrg 1454642e01fSmrg#define MISPRITE(dev) \ 1466747b715Smrg ((!IsMaster(dev) && !dev->u.master) ? \ 1474642e01fSmrg (miCursorInfoPtr)dixLookupPrivate(&dev->devPrivates, miSpriteDevPrivatesKey) : \ 1486747b715Smrg (miCursorInfoPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miSpriteDevPrivatesKey)) 1494642e01fSmrg 1504642e01fSmrgstatic void 1514642e01fSmrgmiSpriteDisableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 1524642e01fSmrg{ 1536747b715Smrg if (pScreenPriv->damageRegistered) { 1544642e01fSmrg DamageUnregister (&(pScreen->GetScreenPixmap(pScreen)->drawable), 1554642e01fSmrg pScreenPriv->pDamage); 1566747b715Smrg pScreenPriv->damageRegistered = 0; 1574642e01fSmrg } 1584642e01fSmrg} 1594642e01fSmrg 1604642e01fSmrgstatic void 1614642e01fSmrgmiSpriteEnableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 1624642e01fSmrg{ 1636747b715Smrg if (!pScreenPriv->damageRegistered) { 1646747b715Smrg pScreenPriv->damageRegistered = 1; 1654642e01fSmrg DamageRegister (&(pScreen->GetScreenPixmap(pScreen)->drawable), 1664642e01fSmrg pScreenPriv->pDamage); 1674642e01fSmrg } 1684642e01fSmrg} 1694642e01fSmrg 1704642e01fSmrgstatic void 1714642e01fSmrgmiSpriteIsUp(miCursorInfoPtr pDevCursor) 1724642e01fSmrg{ 1734642e01fSmrg pDevCursor->isUp = TRUE; 1744642e01fSmrg} 1754642e01fSmrg 1764642e01fSmrgstatic void 1774642e01fSmrgmiSpriteIsDown(miCursorInfoPtr pDevCursor) 1784642e01fSmrg{ 1794642e01fSmrg pDevCursor->isUp = FALSE; 1804642e01fSmrg} 1814642e01fSmrg 18205b261ecSmrg/* 18305b261ecSmrg * screen wrappers 18405b261ecSmrg */ 18505b261ecSmrg 1866747b715Smrgstatic DevPrivateKeyRec miSpriteScreenKeyRec; 1876747b715Smrg#define miSpriteScreenKey (&miSpriteScreenKeyRec) 1889ace9065Smrg#define GetSpriteScreen(pScreen) \ 1899ace9065Smrg (dixLookupPrivate(&(pScreen)->devPrivates, miSpriteScreenKey)) 1906747b715Smrgstatic DevPrivateKeyRec miSpriteDevPrivatesKeyRec; 1916747b715Smrg#define miSpriteDevPrivatesKey (&miSpriteDevPrivatesKeyRec) 19205b261ecSmrg 19305b261ecSmrgstatic Bool miSpriteCloseScreen(int i, ScreenPtr pScreen); 19405b261ecSmrgstatic void miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy, 19505b261ecSmrg int w, int h, unsigned int format, 19605b261ecSmrg unsigned long planemask, char *pdstLine); 19705b261ecSmrgstatic void miSpriteGetSpans(DrawablePtr pDrawable, int wMax, 19805b261ecSmrg DDXPointPtr ppt, int *pwidth, int nspans, 19905b261ecSmrg char *pdstStart); 20005b261ecSmrgstatic void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, 2019ace9065Smrg int width, int height, 2029ace9065Smrg unsigned int subWindowMode); 20305b261ecSmrgstatic void miSpriteCopyWindow (WindowPtr pWindow, 20405b261ecSmrg DDXPointRec ptOldOrg, 20505b261ecSmrg RegionPtr prgnSrc); 20605b261ecSmrgstatic void miSpriteBlockHandler(int i, pointer blockData, 20705b261ecSmrg pointer pTimeout, 20805b261ecSmrg pointer pReadMask); 20905b261ecSmrgstatic void miSpriteInstallColormap(ColormapPtr pMap); 21005b261ecSmrgstatic void miSpriteStoreColors(ColormapPtr pMap, int ndef, 21105b261ecSmrg xColorItem *pdef); 21205b261ecSmrg 2134642e01fSmrgstatic void miSpriteComputeSaved(DeviceIntPtr pDev, 2144642e01fSmrg ScreenPtr pScreen); 21505b261ecSmrg 2164642e01fSmrgstatic Bool miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, 2174642e01fSmrg ScreenPtr pScreen); 2184642e01fSmrgstatic void miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, 2194642e01fSmrg ScreenPtr pScreen); 22005b261ecSmrg 2219ace9065Smrg#define SCREEN_PROLOGUE(pPriv, pScreen, field) ((pScreen)->field = \ 2229ace9065Smrg (pPriv)->field) 2239ace9065Smrg#define SCREEN_EPILOGUE(pPriv, pScreen, field)\ 2249ace9065Smrg ((pPriv)->field = (pScreen)->field, (pScreen)->field = miSprite##field) 22505b261ecSmrg 22605b261ecSmrg/* 22705b261ecSmrg * pointer-sprite method table 22805b261ecSmrg */ 22905b261ecSmrg 2304642e01fSmrgstatic Bool miSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2314642e01fSmrg CursorPtr pCursor); 2324642e01fSmrgstatic Bool miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2334642e01fSmrg CursorPtr pCursor); 2344642e01fSmrgstatic void miSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2354642e01fSmrg CursorPtr pCursor, int x, int y); 2364642e01fSmrgstatic void miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2374642e01fSmrg int x, int y); 23805b261ecSmrg 2396747b715SmrgmiPointerSpriteFuncRec miSpritePointerFuncs = { 24005b261ecSmrg miSpriteRealizeCursor, 24105b261ecSmrg miSpriteUnrealizeCursor, 24205b261ecSmrg miSpriteSetCursor, 24305b261ecSmrg miSpriteMoveCursor, 2444642e01fSmrg miSpriteDeviceCursorInitialize, 2454642e01fSmrg miSpriteDeviceCursorCleanup, 24605b261ecSmrg}; 24705b261ecSmrg 24805b261ecSmrg/* 24905b261ecSmrg * other misc functions 25005b261ecSmrg */ 25105b261ecSmrg 2524642e01fSmrgstatic void miSpriteRemoveCursor(DeviceIntPtr pDev, 2534642e01fSmrg ScreenPtr pScreen); 2544642e01fSmrgstatic void miSpriteSaveUnderCursor(DeviceIntPtr pDev, 2554642e01fSmrg ScreenPtr pScreen); 2564642e01fSmrgstatic void miSpriteRestoreCursor(DeviceIntPtr pDev, 2574642e01fSmrg ScreenPtr pScreen); 25805b261ecSmrg 2599ace9065Smrgstatic void 2609ace9065SmrgmiSpriteRegisterBlockHandler(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 2619ace9065Smrg{ 2629ace9065Smrg if (!pScreenPriv->BlockHandler) { 2639ace9065Smrg pScreenPriv->BlockHandler = pScreen->BlockHandler; 2649ace9065Smrg pScreen->BlockHandler = miSpriteBlockHandler; 2659ace9065Smrg } 2669ace9065Smrg} 2679ace9065Smrg 26805b261ecSmrgstatic void 26905b261ecSmrgmiSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure) 27005b261ecSmrg{ 27105b261ecSmrg ScreenPtr pScreen = closure; 2724642e01fSmrg miCursorInfoPtr pCursorInfo; 2734642e01fSmrg DeviceIntPtr pDev; 2744642e01fSmrg 2754642e01fSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) 27605b261ecSmrg { 2774642e01fSmrg if (DevHasCursor(pDev)) 2784642e01fSmrg { 2794642e01fSmrg pCursorInfo = MISPRITE(pDev); 2804642e01fSmrg 2814642e01fSmrg if (pCursorInfo->isUp && 2824642e01fSmrg pCursorInfo->pScreen == pScreen && 2836747b715Smrg RegionContainsRect(pRegion, &pCursorInfo->saved) != rgnOUT) 2844642e01fSmrg { 2854642e01fSmrg SPRITE_DEBUG(("Damage remove\n")); 2864642e01fSmrg miSpriteRemoveCursor (pDev, pScreen); 2874642e01fSmrg } 2884642e01fSmrg } 28905b261ecSmrg } 29005b261ecSmrg} 29105b261ecSmrg 29205b261ecSmrg/* 29305b261ecSmrg * miSpriteInitialize -- called from device-dependent screen 29405b261ecSmrg * initialization proc after all of the function pointers have 29505b261ecSmrg * been stored in the screen structure. 29605b261ecSmrg */ 29705b261ecSmrg 29805b261ecSmrgBool 2994642e01fSmrgmiSpriteInitialize (ScreenPtr pScreen, 3004642e01fSmrg miPointerScreenFuncPtr screenFuncs) 30105b261ecSmrg{ 30205b261ecSmrg miSpriteScreenPtr pScreenPriv; 30305b261ecSmrg VisualPtr pVisual; 3044642e01fSmrg 30505b261ecSmrg if (!DamageSetup (pScreen)) 30605b261ecSmrg return FALSE; 30705b261ecSmrg 3086747b715Smrg if (!dixRegisterPrivateKey(&miSpriteScreenKeyRec, PRIVATE_SCREEN, 0)) 3096747b715Smrg return FALSE; 3106747b715Smrg 3116747b715Smrg if (!dixRegisterPrivateKey(&miSpriteDevPrivatesKeyRec, PRIVATE_DEVICE, 0)) 3126747b715Smrg return FALSE; 3136747b715Smrg 3146747b715Smrg pScreenPriv = malloc(sizeof (miSpriteScreenRec)); 31505b261ecSmrg if (!pScreenPriv) 31605b261ecSmrg return FALSE; 3174642e01fSmrg 31805b261ecSmrg pScreenPriv->pDamage = DamageCreate (miSpriteReportDamage, 3196747b715Smrg NULL, 32005b261ecSmrg DamageReportRawRegion, 32105b261ecSmrg TRUE, 32205b261ecSmrg pScreen, 3236747b715Smrg pScreen); 32405b261ecSmrg 32505b261ecSmrg if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE)) 32605b261ecSmrg { 3276747b715Smrg free(pScreenPriv); 32805b261ecSmrg return FALSE; 32905b261ecSmrg } 33005b261ecSmrg for (pVisual = pScreen->visuals; 33105b261ecSmrg pVisual->vid != pScreen->rootVisual; 33205b261ecSmrg pVisual++) 33305b261ecSmrg ; 33405b261ecSmrg pScreenPriv->pVisual = pVisual; 33505b261ecSmrg pScreenPriv->CloseScreen = pScreen->CloseScreen; 33605b261ecSmrg pScreenPriv->GetImage = pScreen->GetImage; 33705b261ecSmrg pScreenPriv->GetSpans = pScreen->GetSpans; 33805b261ecSmrg pScreenPriv->SourceValidate = pScreen->SourceValidate; 33905b261ecSmrg 34005b261ecSmrg pScreenPriv->CopyWindow = pScreen->CopyWindow; 3414642e01fSmrg 34205b261ecSmrg pScreenPriv->InstallColormap = pScreen->InstallColormap; 34305b261ecSmrg pScreenPriv->StoreColors = pScreen->StoreColors; 3444642e01fSmrg 3459ace9065Smrg pScreenPriv->BlockHandler = NULL; 3464642e01fSmrg 3474642e01fSmrg pScreenPriv->DeviceCursorInitialize = pScreen->DeviceCursorInitialize; 3484642e01fSmrg pScreenPriv->DeviceCursorCleanup = pScreen->DeviceCursorCleanup; 3494642e01fSmrg 35005b261ecSmrg pScreenPriv->pInstalledMap = NULL; 35105b261ecSmrg pScreenPriv->pColormap = NULL; 35205b261ecSmrg pScreenPriv->colors[SOURCE_COLOR].red = 0; 35305b261ecSmrg pScreenPriv->colors[SOURCE_COLOR].green = 0; 35405b261ecSmrg pScreenPriv->colors[SOURCE_COLOR].blue = 0; 35505b261ecSmrg pScreenPriv->colors[MASK_COLOR].red = 0; 35605b261ecSmrg pScreenPriv->colors[MASK_COLOR].green = 0; 35705b261ecSmrg pScreenPriv->colors[MASK_COLOR].blue = 0; 3586747b715Smrg pScreenPriv->damageRegistered = 0; 3599ace9065Smrg pScreenPriv->numberOfCursors = 0; 3606747b715Smrg 3614642e01fSmrg dixSetPrivate(&pScreen->devPrivates, miSpriteScreenKey, pScreenPriv); 3624642e01fSmrg 36305b261ecSmrg pScreen->CloseScreen = miSpriteCloseScreen; 36405b261ecSmrg pScreen->GetImage = miSpriteGetImage; 36505b261ecSmrg pScreen->GetSpans = miSpriteGetSpans; 36605b261ecSmrg pScreen->SourceValidate = miSpriteSourceValidate; 3674642e01fSmrg 36805b261ecSmrg pScreen->CopyWindow = miSpriteCopyWindow; 36905b261ecSmrg pScreen->InstallColormap = miSpriteInstallColormap; 37005b261ecSmrg pScreen->StoreColors = miSpriteStoreColors; 37105b261ecSmrg 37205b261ecSmrg return TRUE; 37305b261ecSmrg} 37405b261ecSmrg 37505b261ecSmrg/* 37605b261ecSmrg * Screen wrappers 37705b261ecSmrg */ 37805b261ecSmrg 37905b261ecSmrg/* 38005b261ecSmrg * CloseScreen wrapper -- unwrap everything, free the private data 38105b261ecSmrg * and call the wrapped function 38205b261ecSmrg */ 38305b261ecSmrg 38405b261ecSmrgstatic Bool 3854642e01fSmrgmiSpriteCloseScreen (int i, ScreenPtr pScreen) 38605b261ecSmrg{ 3879ace9065Smrg miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); 38805b261ecSmrg 38905b261ecSmrg pScreen->CloseScreen = pScreenPriv->CloseScreen; 39005b261ecSmrg pScreen->GetImage = pScreenPriv->GetImage; 39105b261ecSmrg pScreen->GetSpans = pScreenPriv->GetSpans; 39205b261ecSmrg pScreen->SourceValidate = pScreenPriv->SourceValidate; 39305b261ecSmrg pScreen->InstallColormap = pScreenPriv->InstallColormap; 39405b261ecSmrg pScreen->StoreColors = pScreenPriv->StoreColors; 39505b261ecSmrg 39605b261ecSmrg DamageDestroy (pScreenPriv->pDamage); 3974642e01fSmrg 3986747b715Smrg free(pScreenPriv); 39905b261ecSmrg 40005b261ecSmrg return (*pScreen->CloseScreen) (i, pScreen); 40105b261ecSmrg} 40205b261ecSmrg 40305b261ecSmrgstatic void 4044642e01fSmrgmiSpriteGetImage (DrawablePtr pDrawable, int sx, int sy, int w, int h, 4054642e01fSmrg unsigned int format, unsigned long planemask, 4064642e01fSmrg char *pdstLine) 40705b261ecSmrg{ 4089ace9065Smrg ScreenPtr pScreen = pDrawable->pScreen; 4099ace9065Smrg DeviceIntPtr pDev; 4109ace9065Smrg miCursorInfoPtr pCursorInfo; 4119ace9065Smrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 41205b261ecSmrg 4139ace9065Smrg SCREEN_PROLOGUE (pPriv, pScreen, GetImage); 41405b261ecSmrg 4156747b715Smrg if (pDrawable->type == DRAWABLE_WINDOW) 41605b261ecSmrg { 4176747b715Smrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 4184642e01fSmrg { 4196747b715Smrg if (DevHasCursor(pDev)) 4206747b715Smrg { 4216747b715Smrg pCursorInfo = MISPRITE(pDev); 4226747b715Smrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 4236747b715Smrg ORG_OVERLAP(&pCursorInfo->saved,pDrawable->x,pDrawable->y, 4246747b715Smrg sx, sy, w, h)) 4256747b715Smrg { 4266747b715Smrg SPRITE_DEBUG (("GetImage remove\n")); 4276747b715Smrg miSpriteRemoveCursor (pDev, pScreen); 4286747b715Smrg } 4296747b715Smrg } 4304642e01fSmrg } 43105b261ecSmrg } 43205b261ecSmrg 43305b261ecSmrg (*pScreen->GetImage) (pDrawable, sx, sy, w, h, 43405b261ecSmrg format, planemask, pdstLine); 43505b261ecSmrg 4369ace9065Smrg SCREEN_EPILOGUE (pPriv, pScreen, GetImage); 43705b261ecSmrg} 43805b261ecSmrg 43905b261ecSmrgstatic void 4404642e01fSmrgmiSpriteGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, 4414642e01fSmrg int *pwidth, int nspans, char *pdstStart) 44205b261ecSmrg{ 44305b261ecSmrg ScreenPtr pScreen = pDrawable->pScreen; 4446747b715Smrg DeviceIntPtr pDev; 4454642e01fSmrg miCursorInfoPtr pCursorInfo; 4469ace9065Smrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 4474642e01fSmrg 4489ace9065Smrg SCREEN_PROLOGUE (pPriv, pScreen, GetSpans); 44905b261ecSmrg 4506747b715Smrg if (pDrawable->type == DRAWABLE_WINDOW) 45105b261ecSmrg { 4526747b715Smrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 4534642e01fSmrg { 4546747b715Smrg if (DevHasCursor(pDev)) 4554642e01fSmrg { 4566747b715Smrg pCursorInfo = MISPRITE(pDev); 4576747b715Smrg 4586747b715Smrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) 4594642e01fSmrg { 4606747b715Smrg DDXPointPtr pts; 4616747b715Smrg int *widths; 4626747b715Smrg int nPts; 4636747b715Smrg int xorg, 4646747b715Smrg yorg; 4656747b715Smrg 4666747b715Smrg xorg = pDrawable->x; 4676747b715Smrg yorg = pDrawable->y; 4686747b715Smrg 4696747b715Smrg for (pts = ppt, widths = pwidth, nPts = nspans; 4706747b715Smrg nPts--; 4716747b715Smrg pts++, widths++) 4724642e01fSmrg { 4736747b715Smrg if (SPN_OVERLAP(&pCursorInfo->saved,pts->y+yorg, 4746747b715Smrg pts->x+xorg,*widths)) 4756747b715Smrg { 4766747b715Smrg SPRITE_DEBUG (("GetSpans remove\n")); 4776747b715Smrg miSpriteRemoveCursor (pDev, pScreen); 4786747b715Smrg break; 4796747b715Smrg } 4804642e01fSmrg } 4814642e01fSmrg } 4824642e01fSmrg } 4834642e01fSmrg } 48405b261ecSmrg } 48505b261ecSmrg 48605b261ecSmrg (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); 48705b261ecSmrg 4889ace9065Smrg SCREEN_EPILOGUE (pPriv, pScreen, GetSpans); 48905b261ecSmrg} 49005b261ecSmrg 49105b261ecSmrgstatic void 4924642e01fSmrgmiSpriteSourceValidate (DrawablePtr pDrawable, int x, int y, int width, 4939ace9065Smrg int height, unsigned int subWindowMode) 49405b261ecSmrg{ 49505b261ecSmrg ScreenPtr pScreen = pDrawable->pScreen; 4966747b715Smrg DeviceIntPtr pDev; 4974642e01fSmrg miCursorInfoPtr pCursorInfo; 4989ace9065Smrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 4994642e01fSmrg 5009ace9065Smrg SCREEN_PROLOGUE (pPriv, pScreen, SourceValidate); 50105b261ecSmrg 5026747b715Smrg if (pDrawable->type == DRAWABLE_WINDOW) 50305b261ecSmrg { 5046747b715Smrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 5056747b715Smrg { 5066747b715Smrg if (DevHasCursor(pDev)) 5076747b715Smrg { 5086747b715Smrg pCursorInfo = MISPRITE(pDev); 5096747b715Smrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 5106747b715Smrg ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y, 5116747b715Smrg x, y, width, height)) 5126747b715Smrg { 5136747b715Smrg SPRITE_DEBUG (("SourceValidate remove\n")); 5146747b715Smrg miSpriteRemoveCursor (pDev, pScreen); 5156747b715Smrg } 5166747b715Smrg } 5176747b715Smrg } 51805b261ecSmrg } 51905b261ecSmrg 52005b261ecSmrg if (pScreen->SourceValidate) 5219ace9065Smrg (*pScreen->SourceValidate) (pDrawable, x, y, width, height, subWindowMode); 52205b261ecSmrg 5239ace9065Smrg SCREEN_EPILOGUE (pPriv, pScreen, SourceValidate); 52405b261ecSmrg} 52505b261ecSmrg 52605b261ecSmrgstatic void 52705b261ecSmrgmiSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) 52805b261ecSmrg{ 52905b261ecSmrg ScreenPtr pScreen = pWindow->drawable.pScreen; 5306747b715Smrg DeviceIntPtr pDev; 5314642e01fSmrg miCursorInfoPtr pCursorInfo; 5329ace9065Smrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 5334642e01fSmrg 5349ace9065Smrg SCREEN_PROLOGUE (pPriv, pScreen, CopyWindow); 53505b261ecSmrg 5364642e01fSmrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 53705b261ecSmrg { 5384642e01fSmrg if (DevHasCursor(pDev)) 5394642e01fSmrg { 5404642e01fSmrg pCursorInfo = MISPRITE(pDev); 5414642e01fSmrg /* 5424642e01fSmrg * Damage will take care of destination check 5434642e01fSmrg */ 5444642e01fSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 5456747b715Smrg RegionContainsRect(prgnSrc, &pCursorInfo->saved) != rgnOUT) 5464642e01fSmrg { 5474642e01fSmrg SPRITE_DEBUG (("CopyWindow remove\n")); 5484642e01fSmrg miSpriteRemoveCursor (pDev, pScreen); 5494642e01fSmrg } 5504642e01fSmrg } 55105b261ecSmrg } 55205b261ecSmrg 55305b261ecSmrg (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc); 5549ace9065Smrg SCREEN_EPILOGUE (pPriv, pScreen, CopyWindow); 55505b261ecSmrg} 55605b261ecSmrg 55705b261ecSmrgstatic void 5584642e01fSmrgmiSpriteBlockHandler (int i, pointer blockData, pointer pTimeout, 5594642e01fSmrg pointer pReadmask) 56005b261ecSmrg{ 56105b261ecSmrg ScreenPtr pScreen = screenInfo.screens[i]; 5629ace9065Smrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 5636747b715Smrg DeviceIntPtr pDev; 5644642e01fSmrg miCursorInfoPtr pCursorInfo; 5659ace9065Smrg Bool WorkToDo = FALSE; 56605b261ecSmrg 5674642e01fSmrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 5684642e01fSmrg { 5694642e01fSmrg if (DevHasCursor(pDev)) 5704642e01fSmrg { 5714642e01fSmrg pCursorInfo = MISPRITE(pDev); 5724642e01fSmrg if (pCursorInfo && !pCursorInfo->isUp 5734642e01fSmrg && pCursorInfo->pScreen == pScreen 5744642e01fSmrg && pCursorInfo->shouldBeUp) 5754642e01fSmrg { 5768223e2f2Smrg SPRITE_DEBUG (("BlockHandler save")); 5774642e01fSmrg miSpriteSaveUnderCursor (pDev, pScreen); 5784642e01fSmrg } 5794642e01fSmrg } 5804642e01fSmrg } 5814642e01fSmrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 58205b261ecSmrg { 5834642e01fSmrg if (DevHasCursor(pDev)) 5844642e01fSmrg { 5854642e01fSmrg pCursorInfo = MISPRITE(pDev); 5864642e01fSmrg if (pCursorInfo && !pCursorInfo->isUp && 5874642e01fSmrg pCursorInfo->pScreen == pScreen && 5884642e01fSmrg pCursorInfo->shouldBeUp) 5894642e01fSmrg { 5904642e01fSmrg SPRITE_DEBUG (("BlockHandler restore\n")); 5914642e01fSmrg miSpriteRestoreCursor (pDev, pScreen); 5929ace9065Smrg if (!pCursorInfo->isUp) 5939ace9065Smrg WorkToDo = TRUE; 5944642e01fSmrg } 5954642e01fSmrg } 59605b261ecSmrg } 5979ace9065Smrg 5989ace9065Smrg SCREEN_PROLOGUE(pPriv, pScreen, BlockHandler); 5999ace9065Smrg 6009ace9065Smrg (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 6019ace9065Smrg 6029ace9065Smrg if (WorkToDo) 6039ace9065Smrg SCREEN_EPILOGUE(pPriv, pScreen, BlockHandler); 6049ace9065Smrg else 6059ace9065Smrg pPriv->BlockHandler = NULL; 60605b261ecSmrg} 60705b261ecSmrg 60805b261ecSmrgstatic void 6094642e01fSmrgmiSpriteInstallColormap (ColormapPtr pMap) 61005b261ecSmrg{ 61105b261ecSmrg ScreenPtr pScreen = pMap->pScreen; 6129ace9065Smrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 61305b261ecSmrg 6149ace9065Smrg SCREEN_PROLOGUE(pPriv, pScreen, InstallColormap); 6154642e01fSmrg 61605b261ecSmrg (*pScreen->InstallColormap) (pMap); 61705b261ecSmrg 6189ace9065Smrg SCREEN_EPILOGUE(pPriv, pScreen, InstallColormap); 61905b261ecSmrg 6204642e01fSmrg /* InstallColormap can be called before devices are initialized. */ 62105b261ecSmrg pPriv->pInstalledMap = pMap; 62205b261ecSmrg if (pPriv->pColormap != pMap) 62305b261ecSmrg { 6244642e01fSmrg DeviceIntPtr pDev; 6254642e01fSmrg miCursorInfoPtr pCursorInfo; 6264642e01fSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) 6274642e01fSmrg { 6284642e01fSmrg if (DevHasCursor(pDev)) 6294642e01fSmrg { 6304642e01fSmrg pCursorInfo = MISPRITE(pDev); 6314642e01fSmrg pCursorInfo->checkPixels = TRUE; 6324642e01fSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) 6334642e01fSmrg miSpriteRemoveCursor(pDev, pScreen); 6344642e01fSmrg } 6354642e01fSmrg } 6364642e01fSmrg 63705b261ecSmrg } 63805b261ecSmrg} 63905b261ecSmrg 64005b261ecSmrgstatic void 6414642e01fSmrgmiSpriteStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef) 64205b261ecSmrg{ 64305b261ecSmrg ScreenPtr pScreen = pMap->pScreen; 6449ace9065Smrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 64505b261ecSmrg int i; 64605b261ecSmrg int updated; 64705b261ecSmrg VisualPtr pVisual; 6486747b715Smrg DeviceIntPtr pDev; 6494642e01fSmrg miCursorInfoPtr pCursorInfo; 65005b261ecSmrg 6519ace9065Smrg SCREEN_PROLOGUE(pPriv, pScreen, StoreColors); 6524642e01fSmrg 65305b261ecSmrg (*pScreen->StoreColors) (pMap, ndef, pdef); 65405b261ecSmrg 6559ace9065Smrg SCREEN_EPILOGUE(pPriv, pScreen, StoreColors); 65605b261ecSmrg 65705b261ecSmrg if (pPriv->pColormap == pMap) 65805b261ecSmrg { 6594642e01fSmrg updated = 0; 6604642e01fSmrg pVisual = pMap->pVisual; 6614642e01fSmrg if (pVisual->class == DirectColor) 6624642e01fSmrg { 6634642e01fSmrg /* Direct color - match on any of the subfields */ 66405b261ecSmrg 66505b261ecSmrg#define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask))) 66605b261ecSmrg 6674642e01fSmrg#define UpdateDAC(dev, plane,dac,mask) {\ 6684642e01fSmrg if (MaskMatch (dev->colors[plane].pixel,pdef[i].pixel,mask)) {\ 6694642e01fSmrg dev->colors[plane].dac = pdef[i].dac; \ 67005b261ecSmrg updated = 1; \ 67105b261ecSmrg } \ 67205b261ecSmrg} 67305b261ecSmrg 6744642e01fSmrg#define CheckDirect(dev, plane) \ 6754642e01fSmrg UpdateDAC(dev, plane,red,redMask) \ 6764642e01fSmrg UpdateDAC(dev, plane,green,greenMask) \ 6774642e01fSmrg UpdateDAC(dev, plane,blue,blueMask) 6784642e01fSmrg 6794642e01fSmrg for (i = 0; i < ndef; i++) 6804642e01fSmrg { 6814642e01fSmrg CheckDirect (pPriv, SOURCE_COLOR) 6824642e01fSmrg CheckDirect (pPriv, MASK_COLOR) 6834642e01fSmrg } 6844642e01fSmrg } 6854642e01fSmrg else 6864642e01fSmrg { 6874642e01fSmrg /* PseudoColor/GrayScale - match on exact pixel */ 6884642e01fSmrg for (i = 0; i < ndef; i++) 6894642e01fSmrg { 6904642e01fSmrg if (pdef[i].pixel == 6914642e01fSmrg pPriv->colors[SOURCE_COLOR].pixel) 6924642e01fSmrg { 6934642e01fSmrg pPriv->colors[SOURCE_COLOR] = pdef[i]; 6944642e01fSmrg if (++updated == 2) 6954642e01fSmrg break; 6964642e01fSmrg } 6974642e01fSmrg if (pdef[i].pixel == 6984642e01fSmrg pPriv->colors[MASK_COLOR].pixel) 6994642e01fSmrg { 7004642e01fSmrg pPriv->colors[MASK_COLOR] = pdef[i]; 7014642e01fSmrg if (++updated == 2) 7024642e01fSmrg break; 7034642e01fSmrg } 7044642e01fSmrg } 7054642e01fSmrg } 7064642e01fSmrg if (updated) 7074642e01fSmrg { 7084642e01fSmrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 7094642e01fSmrg { 7104642e01fSmrg if (DevHasCursor(pDev)) 7114642e01fSmrg { 7124642e01fSmrg pCursorInfo = MISPRITE(pDev); 7134642e01fSmrg pCursorInfo->checkPixels = TRUE; 7144642e01fSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) 7154642e01fSmrg miSpriteRemoveCursor (pDev, pScreen); 7164642e01fSmrg } 7174642e01fSmrg } 7184642e01fSmrg } 71905b261ecSmrg } 72005b261ecSmrg} 72105b261ecSmrg 72205b261ecSmrgstatic void 7234642e01fSmrgmiSpriteFindColors (miCursorInfoPtr pDevCursor, ScreenPtr pScreen) 72405b261ecSmrg{ 7259ace9065Smrg miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); 72605b261ecSmrg CursorPtr pCursor; 72705b261ecSmrg xColorItem *sourceColor, *maskColor; 72805b261ecSmrg 7294642e01fSmrg pCursor = pDevCursor->pCursor; 73005b261ecSmrg sourceColor = &pScreenPriv->colors[SOURCE_COLOR]; 73105b261ecSmrg maskColor = &pScreenPriv->colors[MASK_COLOR]; 73205b261ecSmrg if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap || 73305b261ecSmrg !(pCursor->foreRed == sourceColor->red && 73405b261ecSmrg pCursor->foreGreen == sourceColor->green && 73505b261ecSmrg pCursor->foreBlue == sourceColor->blue && 73605b261ecSmrg pCursor->backRed == maskColor->red && 73705b261ecSmrg pCursor->backGreen == maskColor->green && 73805b261ecSmrg pCursor->backBlue == maskColor->blue)) 73905b261ecSmrg { 74005b261ecSmrg pScreenPriv->pColormap = pScreenPriv->pInstalledMap; 74105b261ecSmrg sourceColor->red = pCursor->foreRed; 74205b261ecSmrg sourceColor->green = pCursor->foreGreen; 74305b261ecSmrg sourceColor->blue = pCursor->foreBlue; 74405b261ecSmrg FakeAllocColor (pScreenPriv->pColormap, sourceColor); 74505b261ecSmrg maskColor->red = pCursor->backRed; 74605b261ecSmrg maskColor->green = pCursor->backGreen; 74705b261ecSmrg maskColor->blue = pCursor->backBlue; 74805b261ecSmrg FakeAllocColor (pScreenPriv->pColormap, maskColor); 74905b261ecSmrg /* "free" the pixels right away, don't let this confuse you */ 75005b261ecSmrg FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel); 75105b261ecSmrg FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel); 75205b261ecSmrg } 75305b261ecSmrg 7544642e01fSmrg pDevCursor->checkPixels = FALSE; 75505b261ecSmrg 75605b261ecSmrg} 75705b261ecSmrg 75805b261ecSmrg/* 75905b261ecSmrg * miPointer interface routines 76005b261ecSmrg */ 76105b261ecSmrg 76205b261ecSmrg#define SPRITE_PAD 8 76305b261ecSmrg 76405b261ecSmrgstatic Bool 7654642e01fSmrgmiSpriteRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 76605b261ecSmrg{ 7674642e01fSmrg miCursorInfoPtr pCursorInfo; 7684642e01fSmrg 7696747b715Smrg if (!IsMaster(pDev) && !pDev->u.master) 7704642e01fSmrg return FALSE; 7716747b715Smrg 7724642e01fSmrg pCursorInfo = MISPRITE(pDev); 7734642e01fSmrg 7744642e01fSmrg if (pCursor == pCursorInfo->pCursor) 7754642e01fSmrg pCursorInfo->checkPixels = TRUE; 77605b261ecSmrg 7776747b715Smrg return miDCRealizeCursor(pScreen, pCursor); 77805b261ecSmrg} 77905b261ecSmrg 78005b261ecSmrgstatic Bool 7814642e01fSmrgmiSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 78205b261ecSmrg{ 7836747b715Smrg return miDCUnrealizeCursor(pScreen, pCursor); 78405b261ecSmrg} 78505b261ecSmrg 78605b261ecSmrgstatic void 7874642e01fSmrgmiSpriteSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, 7884642e01fSmrg CursorPtr pCursor, int x, int y) 78905b261ecSmrg{ 7909ace9065Smrg miCursorInfoPtr pPointer; 7919ace9065Smrg miSpriteScreenPtr pScreenPriv; 7924642e01fSmrg 7936747b715Smrg if (!IsMaster(pDev) && !pDev->u.master) 7944642e01fSmrg return; 7956747b715Smrg 7964642e01fSmrg pPointer = MISPRITE(pDev); 7979ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 7984642e01fSmrg 79905b261ecSmrg if (!pCursor) 80005b261ecSmrg { 8019ace9065Smrg if (pPointer->shouldBeUp) 8029ace9065Smrg --pScreenPriv->numberOfCursors; 8034642e01fSmrg pPointer->shouldBeUp = FALSE; 8044642e01fSmrg if (pPointer->isUp) 8054642e01fSmrg miSpriteRemoveCursor (pDev, pScreen); 8069ace9065Smrg if (pScreenPriv->numberOfCursors == 0) 8079ace9065Smrg miSpriteDisableDamage(pScreen, pScreenPriv); 8084642e01fSmrg pPointer->pCursor = 0; 80905b261ecSmrg return; 81005b261ecSmrg } 8119ace9065Smrg if (!pPointer->shouldBeUp) 8129ace9065Smrg pScreenPriv->numberOfCursors++; 8134642e01fSmrg pPointer->shouldBeUp = TRUE; 8149ace9065Smrg if (!pPointer->isUp) 8159ace9065Smrg miSpriteRegisterBlockHandler(pScreen, pScreenPriv); 8164642e01fSmrg if (pPointer->x == x && 8174642e01fSmrg pPointer->y == y && 8184642e01fSmrg pPointer->pCursor == pCursor && 8194642e01fSmrg !pPointer->checkPixels) 82005b261ecSmrg { 82105b261ecSmrg return; 82205b261ecSmrg } 8234642e01fSmrg pPointer->x = x; 8244642e01fSmrg pPointer->y = y; 8254642e01fSmrg pPointer->pCacheWin = NullWindow; 8264642e01fSmrg if (pPointer->checkPixels || pPointer->pCursor != pCursor) 82705b261ecSmrg { 8284642e01fSmrg pPointer->pCursor = pCursor; 8294642e01fSmrg miSpriteFindColors (pPointer, pScreen); 83005b261ecSmrg } 8314642e01fSmrg if (pPointer->isUp) { 8326747b715Smrg /* TODO: reimplement flicker-free MoveCursor */ 8336747b715Smrg SPRITE_DEBUG (("SetCursor remove %d\n", pDev->id)); 8346747b715Smrg miSpriteRemoveCursor (pDev, pScreen); 83505b261ecSmrg } 8364642e01fSmrg 8374642e01fSmrg if (!pPointer->isUp && pPointer->pCursor) 83805b261ecSmrg { 8394642e01fSmrg SPRITE_DEBUG (("SetCursor restore %d\n", pDev->id)); 8404642e01fSmrg miSpriteSaveUnderCursor(pDev, pScreen); 8414642e01fSmrg miSpriteRestoreCursor (pDev, pScreen); 84205b261ecSmrg } 8434642e01fSmrg 84405b261ecSmrg} 84505b261ecSmrg 84605b261ecSmrgstatic void 8474642e01fSmrgmiSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 84805b261ecSmrg{ 8494642e01fSmrg CursorPtr pCursor; 85005b261ecSmrg 8516747b715Smrg if (!IsMaster(pDev) && !pDev->u.master) 8524642e01fSmrg return; 8536747b715Smrg 8544642e01fSmrg pCursor = MISPRITE(pDev)->pCursor; 8554642e01fSmrg 8564642e01fSmrg miSpriteSetCursor (pDev, pScreen, pCursor, x, y); 8574642e01fSmrg} 8584642e01fSmrg 8594642e01fSmrg 8604642e01fSmrgstatic Bool 8614642e01fSmrgmiSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) 8624642e01fSmrg{ 8634642e01fSmrg miCursorInfoPtr pCursorInfo; 8644642e01fSmrg int ret = FALSE; 8654642e01fSmrg 8666747b715Smrg pCursorInfo = malloc(sizeof(miCursorInfoRec)); 8674642e01fSmrg if (!pCursorInfo) 8684642e01fSmrg return FALSE; 8694642e01fSmrg 8704642e01fSmrg pCursorInfo->pCursor = NULL; 8714642e01fSmrg pCursorInfo->x = 0; 8724642e01fSmrg pCursorInfo->y = 0; 8734642e01fSmrg pCursorInfo->isUp = FALSE; 8744642e01fSmrg pCursorInfo->shouldBeUp = FALSE; 8754642e01fSmrg pCursorInfo->pCacheWin = NullWindow; 8764642e01fSmrg pCursorInfo->isInCacheWin = FALSE; 8774642e01fSmrg pCursorInfo->checkPixels = TRUE; 8784642e01fSmrg pCursorInfo->pScreen = FALSE; 8794642e01fSmrg 8806747b715Smrg ret = miDCDeviceInitialize(pDev, pScreen); 8814642e01fSmrg if (!ret) 8824642e01fSmrg { 8836747b715Smrg free(pCursorInfo); 8844642e01fSmrg pCursorInfo = NULL; 8854642e01fSmrg } 8864642e01fSmrg dixSetPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey, pCursorInfo); 8874642e01fSmrg return ret; 8884642e01fSmrg} 8894642e01fSmrg 8904642e01fSmrgstatic void 8914642e01fSmrgmiSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) 8924642e01fSmrg{ 8934642e01fSmrg if (DevHasCursor(pDev)) 8946747b715Smrg miDCDeviceCleanup(pDev, pScreen); 89505b261ecSmrg} 89605b261ecSmrg 89705b261ecSmrg/* 89805b261ecSmrg * undraw/draw cursor 89905b261ecSmrg */ 90005b261ecSmrg 90105b261ecSmrgstatic void 9024642e01fSmrgmiSpriteRemoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen) 90305b261ecSmrg{ 90405b261ecSmrg miSpriteScreenPtr pScreenPriv; 9054642e01fSmrg miCursorInfoPtr pCursorInfo; 9064642e01fSmrg 90705b261ecSmrg 9086747b715Smrg if (!IsMaster(pDev) && !pDev->u.master) 9094642e01fSmrg return; 9106747b715Smrg 91105b261ecSmrg DamageDrawInternal (pScreen, TRUE); 9129ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 9134642e01fSmrg pCursorInfo = MISPRITE(pDev); 9144642e01fSmrg 9154642e01fSmrg miSpriteIsDown(pCursorInfo); 9169ace9065Smrg miSpriteRegisterBlockHandler(pScreen, pScreenPriv); 9174642e01fSmrg pCursorInfo->pCacheWin = NullWindow; 9184642e01fSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 9196747b715Smrg if (!miDCRestoreUnderCursor(pDev, 9206747b715Smrg pScreen, 9216747b715Smrg pCursorInfo->saved.x1, 9226747b715Smrg pCursorInfo->saved.y1, 9236747b715Smrg pCursorInfo->saved.x2 - 9246747b715Smrg pCursorInfo->saved.x1, 9256747b715Smrg pCursorInfo->saved.y2 - 9266747b715Smrg pCursorInfo->saved.y1)) 92705b261ecSmrg { 9286747b715Smrg miSpriteIsUp(pCursorInfo); 92905b261ecSmrg } 9304642e01fSmrg miSpriteEnableDamage(pScreen, pScreenPriv); 93105b261ecSmrg DamageDrawInternal (pScreen, FALSE); 93205b261ecSmrg} 93305b261ecSmrg 9344642e01fSmrg/* 9354642e01fSmrg * Called from the block handler, saves area under cursor 9364642e01fSmrg * before waiting for something to do. 9374642e01fSmrg */ 9384642e01fSmrg 9394642e01fSmrgstatic void 9404642e01fSmrgmiSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen) 9414642e01fSmrg{ 9424642e01fSmrg miSpriteScreenPtr pScreenPriv; 9434642e01fSmrg int x, y; 9444642e01fSmrg CursorPtr pCursor; 9454642e01fSmrg miCursorInfoPtr pCursorInfo; 9464642e01fSmrg 9476747b715Smrg if (!IsMaster(pDev) && !pDev->u.master) 9484642e01fSmrg return; 9496747b715Smrg 9504642e01fSmrg DamageDrawInternal (pScreen, TRUE); 9519ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 9524642e01fSmrg pCursorInfo = MISPRITE(pDev); 9534642e01fSmrg 9544642e01fSmrg miSpriteComputeSaved (pDev, pScreen); 9554642e01fSmrg pCursor = pCursorInfo->pCursor; 9564642e01fSmrg 9574642e01fSmrg x = pCursorInfo->x - (int)pCursor->bits->xhot; 9584642e01fSmrg y = pCursorInfo->y - (int)pCursor->bits->yhot; 9594642e01fSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 9604642e01fSmrg 9616747b715Smrg miDCSaveUnderCursor(pDev, 9626747b715Smrg pScreen, 9636747b715Smrg pCursorInfo->saved.x1, 9646747b715Smrg pCursorInfo->saved.y1, 9656747b715Smrg pCursorInfo->saved.x2 - 9666747b715Smrg pCursorInfo->saved.x1, 9676747b715Smrg pCursorInfo->saved.y2 - 9686747b715Smrg pCursorInfo->saved.y1); 9694642e01fSmrg SPRITE_DEBUG(("SaveUnderCursor %d\n", pDev->id)); 9704642e01fSmrg miSpriteEnableDamage(pScreen, pScreenPriv); 9714642e01fSmrg DamageDrawInternal (pScreen, FALSE); 9724642e01fSmrg} 9734642e01fSmrg 9744642e01fSmrg 97505b261ecSmrg/* 97605b261ecSmrg * Called from the block handler, restores the cursor 97705b261ecSmrg * before waiting for something to do. 97805b261ecSmrg */ 97905b261ecSmrg 98005b261ecSmrgstatic void 9814642e01fSmrgmiSpriteRestoreCursor (DeviceIntPtr pDev, ScreenPtr pScreen) 98205b261ecSmrg{ 98305b261ecSmrg miSpriteScreenPtr pScreenPriv; 98405b261ecSmrg int x, y; 98505b261ecSmrg CursorPtr pCursor; 9864642e01fSmrg miCursorInfoPtr pCursorInfo; 9874642e01fSmrg 9886747b715Smrg if (!IsMaster(pDev) && !pDev->u.master) 9894642e01fSmrg return; 99005b261ecSmrg 99105b261ecSmrg DamageDrawInternal (pScreen, TRUE); 9929ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 9934642e01fSmrg pCursorInfo = MISPRITE(pDev); 9944642e01fSmrg 9954642e01fSmrg miSpriteComputeSaved (pDev, pScreen); 9964642e01fSmrg pCursor = pCursorInfo->pCursor; 9974642e01fSmrg 9984642e01fSmrg x = pCursorInfo->x - (int)pCursor->bits->xhot; 9994642e01fSmrg y = pCursorInfo->y - (int)pCursor->bits->yhot; 10004642e01fSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 10014642e01fSmrg SPRITE_DEBUG(("RestoreCursor %d\n", pDev->id)); 10024642e01fSmrg if (pCursorInfo->checkPixels) 10034642e01fSmrg miSpriteFindColors (pCursorInfo, pScreen); 10046747b715Smrg if (miDCPutUpCursor(pDev, pScreen, 10054642e01fSmrg pCursor, x, y, 10064642e01fSmrg pScreenPriv->colors[SOURCE_COLOR].pixel, 10074642e01fSmrg pScreenPriv->colors[MASK_COLOR].pixel)) 100805b261ecSmrg { 10094642e01fSmrg miSpriteIsUp(pCursorInfo); 10104642e01fSmrg pCursorInfo->pScreen = pScreen; 101105b261ecSmrg } 10124642e01fSmrg miSpriteEnableDamage(pScreen, pScreenPriv); 101305b261ecSmrg DamageDrawInternal (pScreen, FALSE); 101405b261ecSmrg} 101505b261ecSmrg 101605b261ecSmrg/* 101705b261ecSmrg * compute the desired area of the screen to save 101805b261ecSmrg */ 101905b261ecSmrg 102005b261ecSmrgstatic void 10214642e01fSmrgmiSpriteComputeSaved (DeviceIntPtr pDev, ScreenPtr pScreen) 102205b261ecSmrg{ 102305b261ecSmrg int x, y, w, h; 102405b261ecSmrg int wpad, hpad; 102505b261ecSmrg CursorPtr pCursor; 10264642e01fSmrg miCursorInfoPtr pCursorInfo; 102705b261ecSmrg 10286747b715Smrg if (!IsMaster(pDev) && !pDev->u.master) 10294642e01fSmrg return; 10306747b715Smrg 10314642e01fSmrg pCursorInfo = MISPRITE(pDev); 10324642e01fSmrg 10334642e01fSmrg pCursor = pCursorInfo->pCursor; 10344642e01fSmrg x = pCursorInfo->x - (int)pCursor->bits->xhot; 10354642e01fSmrg y = pCursorInfo->y - (int)pCursor->bits->yhot; 103605b261ecSmrg w = pCursor->bits->width; 103705b261ecSmrg h = pCursor->bits->height; 103805b261ecSmrg wpad = SPRITE_PAD; 103905b261ecSmrg hpad = SPRITE_PAD; 10404642e01fSmrg pCursorInfo->saved.x1 = x - wpad; 10414642e01fSmrg pCursorInfo->saved.y1 = y - hpad; 10424642e01fSmrg pCursorInfo->saved.x2 = pCursorInfo->saved.x1 + w + wpad * 2; 10434642e01fSmrg pCursorInfo->saved.y2 = pCursorInfo->saved.y1 + h + hpad * 2; 104405b261ecSmrg} 10454642e01fSmrg 1046