misprite.c revision 1b5d61b8
105b261ecSmrg/* 205b261ecSmrg * misprite.c 305b261ecSmrg * 405b261ecSmrg * machine independent software sprite routines 505b261ecSmrg */ 605b261ecSmrg 705b261ecSmrg/* 805b261ecSmrg 905b261ecSmrgCopyright 1989, 1998 The Open Group 1005b261ecSmrg 1105b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its 1205b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that 1305b261ecSmrgthe above copyright notice appear in all copies and that both that 1405b261ecSmrgcopyright notice and this permission notice appear in supporting 1505b261ecSmrgdocumentation. 1605b261ecSmrg 1705b261ecSmrgThe above copyright notice and this permission notice shall be included in 1805b261ecSmrgall copies or substantial portions of the Software. 1905b261ecSmrg 2005b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2105b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2205b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 2305b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2405b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2505b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2605b261ecSmrg 2705b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be 2805b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings 2905b261ecSmrgin this Software without prior written authorization from The Open Group. 3005b261ecSmrg*/ 3105b261ecSmrg 3205b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 3305b261ecSmrg#include <dix-config.h> 3405b261ecSmrg#endif 3505b261ecSmrg 366747b715Smrg#include <X11/X.h> 376747b715Smrg#include <X11/Xproto.h> 386747b715Smrg#include "misc.h" 396747b715Smrg#include "pixmapstr.h" 406747b715Smrg#include "input.h" 416747b715Smrg#include "mi.h" 426747b715Smrg#include "cursorstr.h" 436747b715Smrg#include <X11/fonts/font.h> 446747b715Smrg#include "scrnintstr.h" 456747b715Smrg#include "colormapst.h" 466747b715Smrg#include "windowstr.h" 476747b715Smrg#include "gcstruct.h" 486747b715Smrg#include "mipointer.h" 496747b715Smrg#include "misprite.h" 506747b715Smrg#include "dixfontstr.h" 516747b715Smrg#include <X11/fonts/fontstruct.h> 526747b715Smrg#include "inputstr.h" 536747b715Smrg#include "damage.h" 546747b715Smrg 556747b715Smrgtypedef struct { 5635c4bbdfSmrg CursorPtr pCursor; 5735c4bbdfSmrg int x; /* cursor hotspot */ 5835c4bbdfSmrg int y; 5935c4bbdfSmrg BoxRec saved; /* saved area from the screen */ 6035c4bbdfSmrg Bool isUp; /* cursor in frame buffer */ 6135c4bbdfSmrg Bool shouldBeUp; /* cursor should be displayed */ 6235c4bbdfSmrg Bool checkPixels; /* check colormap collision */ 6335c4bbdfSmrg ScreenPtr pScreen; 646747b715Smrg} miCursorInfoRec, *miCursorInfoPtr; 656747b715Smrg 666747b715Smrg/* 676747b715Smrg * per screen information 686747b715Smrg */ 696747b715Smrg 706747b715Smrgtypedef struct { 716747b715Smrg /* screen procedures */ 7235c4bbdfSmrg CloseScreenProcPtr CloseScreen; 7335c4bbdfSmrg GetImageProcPtr GetImage; 7435c4bbdfSmrg GetSpansProcPtr GetSpans; 7535c4bbdfSmrg SourceValidateProcPtr SourceValidate; 7635c4bbdfSmrg 776747b715Smrg /* window procedures */ 7835c4bbdfSmrg CopyWindowProcPtr CopyWindow; 7935c4bbdfSmrg 806747b715Smrg /* colormap procedures */ 8135c4bbdfSmrg InstallColormapProcPtr InstallColormap; 8235c4bbdfSmrg StoreColorsProcPtr StoreColors; 8335c4bbdfSmrg 846747b715Smrg /* os layer procedures */ 8535c4bbdfSmrg ScreenBlockHandlerProcPtr BlockHandler; 8635c4bbdfSmrg 8735c4bbdfSmrg xColorItem colors[2]; 8835c4bbdfSmrg ColormapPtr pInstalledMap; 8935c4bbdfSmrg ColormapPtr pColormap; 9035c4bbdfSmrg VisualPtr pVisual; 9135c4bbdfSmrg DamagePtr pDamage; /* damage tracking structure */ 9235c4bbdfSmrg Bool damageRegistered; 9335c4bbdfSmrg int numberOfCursors; 946747b715Smrg} miSpriteScreenRec, *miSpriteScreenPtr; 956747b715Smrg 966747b715Smrg#define SOURCE_COLOR 0 976747b715Smrg#define MASK_COLOR 1 986747b715Smrg 996747b715Smrg/* 1006747b715Smrg * Overlap BoxPtr and Box elements 1016747b715Smrg */ 1026747b715Smrg#define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \ 1036747b715Smrg (((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \ 1046747b715Smrg ((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2)) 1056747b715Smrg 1066747b715Smrg/* 1076747b715Smrg * Overlap BoxPtr, origins, and rectangle 1086747b715Smrg */ 1096747b715Smrg#define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \ 1106747b715Smrg BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h)) 1116747b715Smrg 1126747b715Smrg/* 1136747b715Smrg * Overlap BoxPtr, origins and RectPtr 1146747b715Smrg */ 1156747b715Smrg#define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \ 1166747b715Smrg ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y, \ 1176747b715Smrg (int)((pRect)->width), (int)((pRect)->height)) 1186747b715Smrg/* 1196747b715Smrg * Overlap BoxPtr and horizontal span 1206747b715Smrg */ 1216747b715Smrg#define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y)) 12205b261ecSmrg 1236747b715Smrg#define LINE_SORT(x1,y1,x2,y2) \ 1246747b715Smrg{ int _t; \ 1256747b715Smrg if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \ 1266747b715Smrg if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } } 1276747b715Smrg 1286747b715Smrg#define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \ 1296747b715Smrg BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2)) 1304642e01fSmrg 13105b261ecSmrg#define SPRITE_DEBUG_ENABLE 0 13205b261ecSmrg#if SPRITE_DEBUG_ENABLE 13305b261ecSmrg#define SPRITE_DEBUG(x) ErrorF x 13405b261ecSmrg#else 13505b261ecSmrg#define SPRITE_DEBUG(x) 13605b261ecSmrg#endif 13705b261ecSmrg 1381b5d61b8Smrgstatic DevPrivateKeyRec miSpriteScreenKeyRec; 1391b5d61b8Smrgstatic DevPrivateKeyRec miSpriteDevPrivatesKeyRec; 1401b5d61b8Smrg 1411b5d61b8Smrgstatic miSpriteScreenPtr 1421b5d61b8SmrgGetSpriteScreen(ScreenPtr pScreen) 1431b5d61b8Smrg{ 1441b5d61b8Smrg return dixLookupPrivate(&pScreen->devPrivates, &miSpriteScreenKeyRec); 1451b5d61b8Smrg} 1461b5d61b8Smrg 1471b5d61b8Smrgstatic miCursorInfoPtr 1481b5d61b8SmrgGetSprite(DeviceIntPtr dev) 1491b5d61b8Smrg{ 1501b5d61b8Smrg if (IsFloating(dev)) 1511b5d61b8Smrg return dixLookupPrivate(&dev->devPrivates, &miSpriteDevPrivatesKeyRec); 1521b5d61b8Smrg 1531b5d61b8Smrg return dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, 1541b5d61b8Smrg &miSpriteDevPrivatesKeyRec); 1551b5d61b8Smrg} 1564642e01fSmrg 1574642e01fSmrgstatic void 1584642e01fSmrgmiSpriteDisableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 1594642e01fSmrg{ 1606747b715Smrg if (pScreenPriv->damageRegistered) { 16135c4bbdfSmrg DamageUnregister(pScreenPriv->pDamage); 16235c4bbdfSmrg pScreenPriv->damageRegistered = 0; 1634642e01fSmrg } 1644642e01fSmrg} 1654642e01fSmrg 1664642e01fSmrgstatic void 1674642e01fSmrgmiSpriteEnableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 1684642e01fSmrg{ 1696747b715Smrg if (!pScreenPriv->damageRegistered) { 17035c4bbdfSmrg pScreenPriv->damageRegistered = 1; 17135c4bbdfSmrg DamageRegister(&(pScreen->GetScreenPixmap(pScreen)->drawable), 17235c4bbdfSmrg pScreenPriv->pDamage); 1734642e01fSmrg } 1744642e01fSmrg} 1754642e01fSmrg 1764642e01fSmrgstatic void 1774642e01fSmrgmiSpriteIsUp(miCursorInfoPtr pDevCursor) 1784642e01fSmrg{ 1794642e01fSmrg pDevCursor->isUp = TRUE; 1804642e01fSmrg} 1814642e01fSmrg 1824642e01fSmrgstatic void 1834642e01fSmrgmiSpriteIsDown(miCursorInfoPtr pDevCursor) 1844642e01fSmrg{ 1854642e01fSmrg pDevCursor->isUp = FALSE; 1864642e01fSmrg} 1874642e01fSmrg 18805b261ecSmrg/* 18905b261ecSmrg * screen wrappers 19005b261ecSmrg */ 19105b261ecSmrg 19235c4bbdfSmrgstatic Bool miSpriteCloseScreen(ScreenPtr pScreen); 19335c4bbdfSmrgstatic void miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy, 19435c4bbdfSmrg int w, int h, unsigned int format, 19535c4bbdfSmrg unsigned long planemask, char *pdstLine); 19635c4bbdfSmrgstatic void miSpriteGetSpans(DrawablePtr pDrawable, int wMax, 19735c4bbdfSmrg DDXPointPtr ppt, int *pwidth, int nspans, 19835c4bbdfSmrg char *pdstStart); 19935c4bbdfSmrgstatic void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, 20035c4bbdfSmrg int width, int height, 20135c4bbdfSmrg unsigned int subWindowMode); 20235c4bbdfSmrgstatic void miSpriteCopyWindow(WindowPtr pWindow, 20335c4bbdfSmrg DDXPointRec ptOldOrg, RegionPtr prgnSrc); 2041b5d61b8Smrgstatic void miSpriteBlockHandler(ScreenPtr pScreen, void *timeout); 20535c4bbdfSmrgstatic void miSpriteInstallColormap(ColormapPtr pMap); 20635c4bbdfSmrgstatic void miSpriteStoreColors(ColormapPtr pMap, int ndef, xColorItem * pdef); 20735c4bbdfSmrg 20835c4bbdfSmrgstatic void miSpriteComputeSaved(DeviceIntPtr pDev, ScreenPtr pScreen); 20935c4bbdfSmrg 21035c4bbdfSmrgstatic Bool miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, 21135c4bbdfSmrg ScreenPtr pScreen); 21235c4bbdfSmrgstatic void miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen); 21305b261ecSmrg 2149ace9065Smrg#define SCREEN_PROLOGUE(pPriv, pScreen, field) ((pScreen)->field = \ 2159ace9065Smrg (pPriv)->field) 2169ace9065Smrg#define SCREEN_EPILOGUE(pPriv, pScreen, field)\ 2179ace9065Smrg ((pPriv)->field = (pScreen)->field, (pScreen)->field = miSprite##field) 21805b261ecSmrg 21905b261ecSmrg/* 22005b261ecSmrg * pointer-sprite method table 22105b261ecSmrg */ 22205b261ecSmrg 2234642e01fSmrgstatic Bool miSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2244642e01fSmrg CursorPtr pCursor); 2254642e01fSmrgstatic Bool miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2264642e01fSmrg CursorPtr pCursor); 2274642e01fSmrgstatic void miSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2284642e01fSmrg CursorPtr pCursor, int x, int y); 2294642e01fSmrgstatic void miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 2304642e01fSmrg int x, int y); 23105b261ecSmrg 2326747b715SmrgmiPointerSpriteFuncRec miSpritePointerFuncs = { 23305b261ecSmrg miSpriteRealizeCursor, 23405b261ecSmrg miSpriteUnrealizeCursor, 23505b261ecSmrg miSpriteSetCursor, 23605b261ecSmrg miSpriteMoveCursor, 2374642e01fSmrg miSpriteDeviceCursorInitialize, 2384642e01fSmrg miSpriteDeviceCursorCleanup, 23905b261ecSmrg}; 24005b261ecSmrg 24105b261ecSmrg/* 24205b261ecSmrg * other misc functions 24305b261ecSmrg */ 24405b261ecSmrg 24535c4bbdfSmrgstatic void miSpriteRemoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen); 24635c4bbdfSmrgstatic void miSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen); 24735c4bbdfSmrgstatic void miSpriteRestoreCursor(DeviceIntPtr pDev, ScreenPtr pScreen); 24805b261ecSmrg 2499ace9065Smrgstatic void 2509ace9065SmrgmiSpriteRegisterBlockHandler(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 2519ace9065Smrg{ 2529ace9065Smrg if (!pScreenPriv->BlockHandler) { 2539ace9065Smrg pScreenPriv->BlockHandler = pScreen->BlockHandler; 2549ace9065Smrg pScreen->BlockHandler = miSpriteBlockHandler; 2559ace9065Smrg } 2569ace9065Smrg} 2579ace9065Smrg 25805b261ecSmrgstatic void 25935c4bbdfSmrgmiSpriteReportDamage(DamagePtr pDamage, RegionPtr pRegion, void *closure) 26005b261ecSmrg{ 26135c4bbdfSmrg ScreenPtr pScreen = closure; 26235c4bbdfSmrg miCursorInfoPtr pCursorInfo; 26335c4bbdfSmrg DeviceIntPtr pDev; 26435c4bbdfSmrg 26535c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 26635c4bbdfSmrg if (DevHasCursor(pDev)) { 2671b5d61b8Smrg pCursorInfo = GetSprite(pDev); 2684642e01fSmrg 2694642e01fSmrg if (pCursorInfo->isUp && 2704642e01fSmrg pCursorInfo->pScreen == pScreen && 27135c4bbdfSmrg RegionContainsRect(pRegion, &pCursorInfo->saved) != rgnOUT) { 2724642e01fSmrg SPRITE_DEBUG(("Damage remove\n")); 27335c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 2744642e01fSmrg } 2754642e01fSmrg } 27605b261ecSmrg } 27705b261ecSmrg} 27805b261ecSmrg 27905b261ecSmrg/* 28005b261ecSmrg * miSpriteInitialize -- called from device-dependent screen 28105b261ecSmrg * initialization proc after all of the function pointers have 28205b261ecSmrg * been stored in the screen structure. 28305b261ecSmrg */ 28405b261ecSmrg 28505b261ecSmrgBool 28635c4bbdfSmrgmiSpriteInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs) 28705b261ecSmrg{ 28835c4bbdfSmrg miSpriteScreenPtr pScreenPriv; 28935c4bbdfSmrg VisualPtr pVisual; 2904642e01fSmrg 29135c4bbdfSmrg if (!DamageSetup(pScreen)) 29235c4bbdfSmrg return FALSE; 29305b261ecSmrg 2946747b715Smrg if (!dixRegisterPrivateKey(&miSpriteScreenKeyRec, PRIVATE_SCREEN, 0)) 29535c4bbdfSmrg return FALSE; 2966747b715Smrg 29735c4bbdfSmrg if (!dixRegisterPrivateKey 29835c4bbdfSmrg (&miSpriteDevPrivatesKeyRec, PRIVATE_DEVICE, sizeof(miCursorInfoRec))) 29935c4bbdfSmrg return FALSE; 3006747b715Smrg 30135c4bbdfSmrg pScreenPriv = malloc(sizeof(miSpriteScreenRec)); 30205b261ecSmrg if (!pScreenPriv) 30335c4bbdfSmrg return FALSE; 30435c4bbdfSmrg 30535c4bbdfSmrg pScreenPriv->pDamage = DamageCreate(miSpriteReportDamage, 30635c4bbdfSmrg NULL, 30735c4bbdfSmrg DamageReportRawRegion, 30835c4bbdfSmrg TRUE, pScreen, pScreen); 30935c4bbdfSmrg 31035c4bbdfSmrg if (!miPointerInitialize(pScreen, &miSpritePointerFuncs, screenFuncs, TRUE)) { 31135c4bbdfSmrg free(pScreenPriv); 31235c4bbdfSmrg return FALSE; 31305b261ecSmrg } 31405b261ecSmrg for (pVisual = pScreen->visuals; 31535c4bbdfSmrg pVisual->vid != pScreen->rootVisual; pVisual++); 31605b261ecSmrg pScreenPriv->pVisual = pVisual; 31705b261ecSmrg pScreenPriv->CloseScreen = pScreen->CloseScreen; 31805b261ecSmrg pScreenPriv->GetImage = pScreen->GetImage; 31905b261ecSmrg pScreenPriv->GetSpans = pScreen->GetSpans; 32005b261ecSmrg pScreenPriv->SourceValidate = pScreen->SourceValidate; 32105b261ecSmrg 32205b261ecSmrg pScreenPriv->CopyWindow = pScreen->CopyWindow; 3234642e01fSmrg 32405b261ecSmrg pScreenPriv->InstallColormap = pScreen->InstallColormap; 32505b261ecSmrg pScreenPriv->StoreColors = pScreen->StoreColors; 3264642e01fSmrg 3279ace9065Smrg pScreenPriv->BlockHandler = NULL; 3284642e01fSmrg 32905b261ecSmrg pScreenPriv->pInstalledMap = NULL; 33005b261ecSmrg pScreenPriv->pColormap = NULL; 33105b261ecSmrg pScreenPriv->colors[SOURCE_COLOR].red = 0; 33205b261ecSmrg pScreenPriv->colors[SOURCE_COLOR].green = 0; 33305b261ecSmrg pScreenPriv->colors[SOURCE_COLOR].blue = 0; 33405b261ecSmrg pScreenPriv->colors[MASK_COLOR].red = 0; 33505b261ecSmrg pScreenPriv->colors[MASK_COLOR].green = 0; 33605b261ecSmrg pScreenPriv->colors[MASK_COLOR].blue = 0; 3376747b715Smrg pScreenPriv->damageRegistered = 0; 3389ace9065Smrg pScreenPriv->numberOfCursors = 0; 3396747b715Smrg 3401b5d61b8Smrg dixSetPrivate(&pScreen->devPrivates, &miSpriteScreenKeyRec, pScreenPriv); 3414642e01fSmrg 34205b261ecSmrg pScreen->CloseScreen = miSpriteCloseScreen; 34305b261ecSmrg pScreen->GetImage = miSpriteGetImage; 34405b261ecSmrg pScreen->GetSpans = miSpriteGetSpans; 34505b261ecSmrg pScreen->SourceValidate = miSpriteSourceValidate; 3464642e01fSmrg 34705b261ecSmrg pScreen->CopyWindow = miSpriteCopyWindow; 34805b261ecSmrg pScreen->InstallColormap = miSpriteInstallColormap; 34905b261ecSmrg pScreen->StoreColors = miSpriteStoreColors; 35005b261ecSmrg 35105b261ecSmrg return TRUE; 35205b261ecSmrg} 35305b261ecSmrg 35405b261ecSmrg/* 35505b261ecSmrg * Screen wrappers 35605b261ecSmrg */ 35705b261ecSmrg 35805b261ecSmrg/* 35905b261ecSmrg * CloseScreen wrapper -- unwrap everything, free the private data 36005b261ecSmrg * and call the wrapped function 36105b261ecSmrg */ 36205b261ecSmrg 36305b261ecSmrgstatic Bool 36435c4bbdfSmrgmiSpriteCloseScreen(ScreenPtr pScreen) 36505b261ecSmrg{ 36635c4bbdfSmrg miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); 36705b261ecSmrg 36805b261ecSmrg pScreen->CloseScreen = pScreenPriv->CloseScreen; 36905b261ecSmrg pScreen->GetImage = pScreenPriv->GetImage; 37005b261ecSmrg pScreen->GetSpans = pScreenPriv->GetSpans; 37105b261ecSmrg pScreen->SourceValidate = pScreenPriv->SourceValidate; 37205b261ecSmrg pScreen->InstallColormap = pScreenPriv->InstallColormap; 37305b261ecSmrg pScreen->StoreColors = pScreenPriv->StoreColors; 37405b261ecSmrg 37535c4bbdfSmrg DamageDestroy(pScreenPriv->pDamage); 3764642e01fSmrg 3776747b715Smrg free(pScreenPriv); 37805b261ecSmrg 37935c4bbdfSmrg return (*pScreen->CloseScreen) (pScreen); 38005b261ecSmrg} 38105b261ecSmrg 38205b261ecSmrgstatic void 38335c4bbdfSmrgmiSpriteGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, 38435c4bbdfSmrg unsigned int format, unsigned long planemask, char *pdstLine) 38505b261ecSmrg{ 38635c4bbdfSmrg ScreenPtr pScreen = pDrawable->pScreen; 38735c4bbdfSmrg DeviceIntPtr pDev; 38835c4bbdfSmrg miCursorInfoPtr pCursorInfo; 38935c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 39035c4bbdfSmrg 39135c4bbdfSmrg SCREEN_PROLOGUE(pPriv, pScreen, GetImage); 39235c4bbdfSmrg 39335c4bbdfSmrg if (pDrawable->type == DRAWABLE_WINDOW) { 39435c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 39535c4bbdfSmrg if (DevHasCursor(pDev)) { 3961b5d61b8Smrg pCursorInfo = GetSprite(pDev); 39735c4bbdfSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 39835c4bbdfSmrg ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y, 39935c4bbdfSmrg sx, sy, w, h)) { 40035c4bbdfSmrg SPRITE_DEBUG(("GetImage remove\n")); 40135c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 40235c4bbdfSmrg } 4036747b715Smrg } 4044642e01fSmrg } 40505b261ecSmrg } 40605b261ecSmrg 40735c4bbdfSmrg (*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine); 40805b261ecSmrg 40935c4bbdfSmrg SCREEN_EPILOGUE(pPriv, pScreen, GetImage); 41005b261ecSmrg} 41105b261ecSmrg 41205b261ecSmrgstatic void 41335c4bbdfSmrgmiSpriteGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, 41435c4bbdfSmrg int *pwidth, int nspans, char *pdstStart) 41505b261ecSmrg{ 41635c4bbdfSmrg ScreenPtr pScreen = pDrawable->pScreen; 41735c4bbdfSmrg DeviceIntPtr pDev; 41835c4bbdfSmrg miCursorInfoPtr pCursorInfo; 41935c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 42035c4bbdfSmrg 42135c4bbdfSmrg SCREEN_PROLOGUE(pPriv, pScreen, GetSpans); 42235c4bbdfSmrg 42335c4bbdfSmrg if (pDrawable->type == DRAWABLE_WINDOW) { 42435c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 42535c4bbdfSmrg if (DevHasCursor(pDev)) { 4261b5d61b8Smrg pCursorInfo = GetSprite(pDev); 4276747b715Smrg 42835c4bbdfSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) { 42935c4bbdfSmrg DDXPointPtr pts; 43035c4bbdfSmrg int *widths; 43135c4bbdfSmrg int nPts; 43235c4bbdfSmrg int xorg, yorg; 4336747b715Smrg 4346747b715Smrg xorg = pDrawable->x; 4356747b715Smrg yorg = pDrawable->y; 4366747b715Smrg 4376747b715Smrg for (pts = ppt, widths = pwidth, nPts = nspans; 43835c4bbdfSmrg nPts--; pts++, widths++) { 43935c4bbdfSmrg if (SPN_OVERLAP(&pCursorInfo->saved, pts->y + yorg, 44035c4bbdfSmrg pts->x + xorg, *widths)) { 44135c4bbdfSmrg SPRITE_DEBUG(("GetSpans remove\n")); 44235c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 4436747b715Smrg break; 4446747b715Smrg } 4454642e01fSmrg } 4464642e01fSmrg } 4474642e01fSmrg } 4484642e01fSmrg } 44905b261ecSmrg } 45005b261ecSmrg 45105b261ecSmrg (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); 45205b261ecSmrg 45335c4bbdfSmrg SCREEN_EPILOGUE(pPriv, pScreen, GetSpans); 45405b261ecSmrg} 45505b261ecSmrg 45605b261ecSmrgstatic void 45735c4bbdfSmrgmiSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, int width, 45835c4bbdfSmrg int height, unsigned int subWindowMode) 45905b261ecSmrg{ 46035c4bbdfSmrg ScreenPtr pScreen = pDrawable->pScreen; 46135c4bbdfSmrg DeviceIntPtr pDev; 46235c4bbdfSmrg miCursorInfoPtr pCursorInfo; 46335c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 46435c4bbdfSmrg 46535c4bbdfSmrg SCREEN_PROLOGUE(pPriv, pScreen, SourceValidate); 46635c4bbdfSmrg 46735c4bbdfSmrg if (pDrawable->type == DRAWABLE_WINDOW) { 46835c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 46935c4bbdfSmrg if (DevHasCursor(pDev)) { 4701b5d61b8Smrg pCursorInfo = GetSprite(pDev); 47135c4bbdfSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 47235c4bbdfSmrg ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y, 47335c4bbdfSmrg x, y, width, height)) { 47435c4bbdfSmrg SPRITE_DEBUG(("SourceValidate remove\n")); 47535c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 47635c4bbdfSmrg } 47735c4bbdfSmrg } 47835c4bbdfSmrg } 47905b261ecSmrg } 48005b261ecSmrg 48105b261ecSmrg if (pScreen->SourceValidate) 48235c4bbdfSmrg (*pScreen->SourceValidate) (pDrawable, x, y, width, height, 48335c4bbdfSmrg subWindowMode); 48405b261ecSmrg 48535c4bbdfSmrg SCREEN_EPILOGUE(pPriv, pScreen, SourceValidate); 48605b261ecSmrg} 48705b261ecSmrg 48805b261ecSmrgstatic void 48935c4bbdfSmrgmiSpriteCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) 49005b261ecSmrg{ 49135c4bbdfSmrg ScreenPtr pScreen = pWindow->drawable.pScreen; 49235c4bbdfSmrg DeviceIntPtr pDev; 49335c4bbdfSmrg miCursorInfoPtr pCursorInfo; 49435c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 4954642e01fSmrg 49635c4bbdfSmrg SCREEN_PROLOGUE(pPriv, pScreen, CopyWindow); 49705b261ecSmrg 49835c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 49935c4bbdfSmrg if (DevHasCursor(pDev)) { 5001b5d61b8Smrg pCursorInfo = GetSprite(pDev); 5014642e01fSmrg /* 5024642e01fSmrg * Damage will take care of destination check 5034642e01fSmrg */ 5044642e01fSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 50535c4bbdfSmrg RegionContainsRect(prgnSrc, &pCursorInfo->saved) != rgnOUT) { 50635c4bbdfSmrg SPRITE_DEBUG(("CopyWindow remove\n")); 50735c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 5084642e01fSmrg } 5094642e01fSmrg } 51005b261ecSmrg } 51105b261ecSmrg 51205b261ecSmrg (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc); 51335c4bbdfSmrg SCREEN_EPILOGUE(pPriv, pScreen, CopyWindow); 51405b261ecSmrg} 51505b261ecSmrg 51605b261ecSmrgstatic void 5171b5d61b8SmrgmiSpriteBlockHandler(ScreenPtr pScreen, void *timeout) 51805b261ecSmrg{ 51935c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 52035c4bbdfSmrg DeviceIntPtr pDev; 52135c4bbdfSmrg miCursorInfoPtr pCursorInfo; 52235c4bbdfSmrg Bool WorkToDo = FALSE; 52335c4bbdfSmrg 52435c4bbdfSmrg SCREEN_PROLOGUE(pPriv, pScreen, BlockHandler); 52535c4bbdfSmrg 52635c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 52735c4bbdfSmrg if (DevHasCursor(pDev)) { 5281b5d61b8Smrg pCursorInfo = GetSprite(pDev); 5294642e01fSmrg if (pCursorInfo && !pCursorInfo->isUp 53035c4bbdfSmrg && pCursorInfo->pScreen == pScreen && pCursorInfo->shouldBeUp) { 53135c4bbdfSmrg SPRITE_DEBUG(("BlockHandler save")); 53235c4bbdfSmrg miSpriteSaveUnderCursor(pDev, pScreen); 5334642e01fSmrg } 5344642e01fSmrg } 5354642e01fSmrg } 53635c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 53735c4bbdfSmrg if (DevHasCursor(pDev)) { 5381b5d61b8Smrg pCursorInfo = GetSprite(pDev); 5394642e01fSmrg if (pCursorInfo && !pCursorInfo->isUp && 54035c4bbdfSmrg pCursorInfo->pScreen == pScreen && pCursorInfo->shouldBeUp) { 54135c4bbdfSmrg SPRITE_DEBUG(("BlockHandler restore\n")); 54235c4bbdfSmrg miSpriteRestoreCursor(pDev, pScreen); 5439ace9065Smrg if (!pCursorInfo->isUp) 5449ace9065Smrg WorkToDo = TRUE; 5454642e01fSmrg } 5464642e01fSmrg } 54705b261ecSmrg } 5489ace9065Smrg 5491b5d61b8Smrg (*pScreen->BlockHandler) (pScreen, timeout); 5509ace9065Smrg 5519ace9065Smrg if (WorkToDo) 5529ace9065Smrg SCREEN_EPILOGUE(pPriv, pScreen, BlockHandler); 5539ace9065Smrg else 5549ace9065Smrg pPriv->BlockHandler = NULL; 55505b261ecSmrg} 55605b261ecSmrg 55705b261ecSmrgstatic void 55835c4bbdfSmrgmiSpriteInstallColormap(ColormapPtr pMap) 55905b261ecSmrg{ 56035c4bbdfSmrg ScreenPtr pScreen = pMap->pScreen; 56135c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 56205b261ecSmrg 5639ace9065Smrg SCREEN_PROLOGUE(pPriv, pScreen, InstallColormap); 5644642e01fSmrg 56505b261ecSmrg (*pScreen->InstallColormap) (pMap); 56605b261ecSmrg 5679ace9065Smrg SCREEN_EPILOGUE(pPriv, pScreen, InstallColormap); 56805b261ecSmrg 5694642e01fSmrg /* InstallColormap can be called before devices are initialized. */ 57005b261ecSmrg pPriv->pInstalledMap = pMap; 57135c4bbdfSmrg if (pPriv->pColormap != pMap) { 5724642e01fSmrg DeviceIntPtr pDev; 57335c4bbdfSmrg miCursorInfoPtr pCursorInfo; 57435c4bbdfSmrg 57535c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 57635c4bbdfSmrg if (DevHasCursor(pDev)) { 5771b5d61b8Smrg pCursorInfo = GetSprite(pDev); 5784642e01fSmrg pCursorInfo->checkPixels = TRUE; 5794642e01fSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) 5804642e01fSmrg miSpriteRemoveCursor(pDev, pScreen); 5814642e01fSmrg } 5824642e01fSmrg } 5834642e01fSmrg 58405b261ecSmrg } 58505b261ecSmrg} 58605b261ecSmrg 58705b261ecSmrgstatic void 58835c4bbdfSmrgmiSpriteStoreColors(ColormapPtr pMap, int ndef, xColorItem * pdef) 58905b261ecSmrg{ 59035c4bbdfSmrg ScreenPtr pScreen = pMap->pScreen; 59135c4bbdfSmrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 59235c4bbdfSmrg int i; 59335c4bbdfSmrg int updated; 59435c4bbdfSmrg VisualPtr pVisual; 59535c4bbdfSmrg DeviceIntPtr pDev; 59635c4bbdfSmrg miCursorInfoPtr pCursorInfo; 59705b261ecSmrg 5989ace9065Smrg SCREEN_PROLOGUE(pPriv, pScreen, StoreColors); 5994642e01fSmrg 60005b261ecSmrg (*pScreen->StoreColors) (pMap, ndef, pdef); 60105b261ecSmrg 6029ace9065Smrg SCREEN_EPILOGUE(pPriv, pScreen, StoreColors); 60305b261ecSmrg 60435c4bbdfSmrg if (pPriv->pColormap == pMap) { 6054642e01fSmrg updated = 0; 6064642e01fSmrg pVisual = pMap->pVisual; 60735c4bbdfSmrg if (pVisual->class == DirectColor) { 6084642e01fSmrg /* Direct color - match on any of the subfields */ 60905b261ecSmrg 61005b261ecSmrg#define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask))) 61105b261ecSmrg 6124642e01fSmrg#define UpdateDAC(dev, plane,dac,mask) {\ 6134642e01fSmrg if (MaskMatch (dev->colors[plane].pixel,pdef[i].pixel,mask)) {\ 6144642e01fSmrg dev->colors[plane].dac = pdef[i].dac; \ 61505b261ecSmrg updated = 1; \ 61605b261ecSmrg } \ 61705b261ecSmrg} 61805b261ecSmrg 6194642e01fSmrg#define CheckDirect(dev, plane) \ 6204642e01fSmrg UpdateDAC(dev, plane,red,redMask) \ 6214642e01fSmrg UpdateDAC(dev, plane,green,greenMask) \ 6224642e01fSmrg UpdateDAC(dev, plane,blue,blueMask) 6234642e01fSmrg 62435c4bbdfSmrg for (i = 0; i < ndef; i++) { 62535c4bbdfSmrg CheckDirect(pPriv, SOURCE_COLOR) 62635c4bbdfSmrg CheckDirect(pPriv, MASK_COLOR) 6274642e01fSmrg } 6284642e01fSmrg } 62935c4bbdfSmrg else { 6304642e01fSmrg /* PseudoColor/GrayScale - match on exact pixel */ 63135c4bbdfSmrg for (i = 0; i < ndef; i++) { 63235c4bbdfSmrg if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel) { 6334642e01fSmrg pPriv->colors[SOURCE_COLOR] = pdef[i]; 6344642e01fSmrg if (++updated == 2) 6354642e01fSmrg break; 6364642e01fSmrg } 63735c4bbdfSmrg if (pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel) { 6384642e01fSmrg pPriv->colors[MASK_COLOR] = pdef[i]; 6394642e01fSmrg if (++updated == 2) 6404642e01fSmrg break; 6414642e01fSmrg } 6424642e01fSmrg } 6434642e01fSmrg } 64435c4bbdfSmrg if (updated) { 64535c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 64635c4bbdfSmrg if (DevHasCursor(pDev)) { 6471b5d61b8Smrg pCursorInfo = GetSprite(pDev); 6484642e01fSmrg pCursorInfo->checkPixels = TRUE; 6494642e01fSmrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) 65035c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 6514642e01fSmrg } 6524642e01fSmrg } 6534642e01fSmrg } 65405b261ecSmrg } 65505b261ecSmrg} 65605b261ecSmrg 65705b261ecSmrgstatic void 65835c4bbdfSmrgmiSpriteFindColors(miCursorInfoPtr pDevCursor, ScreenPtr pScreen) 65905b261ecSmrg{ 66035c4bbdfSmrg miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); 66135c4bbdfSmrg CursorPtr pCursor; 66235c4bbdfSmrg xColorItem *sourceColor, *maskColor; 66305b261ecSmrg 6644642e01fSmrg pCursor = pDevCursor->pCursor; 66505b261ecSmrg sourceColor = &pScreenPriv->colors[SOURCE_COLOR]; 66605b261ecSmrg maskColor = &pScreenPriv->colors[MASK_COLOR]; 66705b261ecSmrg if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap || 66835c4bbdfSmrg !(pCursor->foreRed == sourceColor->red && 66935c4bbdfSmrg pCursor->foreGreen == sourceColor->green && 67005b261ecSmrg pCursor->foreBlue == sourceColor->blue && 67135c4bbdfSmrg pCursor->backRed == maskColor->red && 67235c4bbdfSmrg pCursor->backGreen == maskColor->green && 67335c4bbdfSmrg pCursor->backBlue == maskColor->blue)) { 67435c4bbdfSmrg pScreenPriv->pColormap = pScreenPriv->pInstalledMap; 67535c4bbdfSmrg sourceColor->red = pCursor->foreRed; 67635c4bbdfSmrg sourceColor->green = pCursor->foreGreen; 67735c4bbdfSmrg sourceColor->blue = pCursor->foreBlue; 67835c4bbdfSmrg FakeAllocColor(pScreenPriv->pColormap, sourceColor); 67935c4bbdfSmrg maskColor->red = pCursor->backRed; 68035c4bbdfSmrg maskColor->green = pCursor->backGreen; 68135c4bbdfSmrg maskColor->blue = pCursor->backBlue; 68235c4bbdfSmrg FakeAllocColor(pScreenPriv->pColormap, maskColor); 68335c4bbdfSmrg /* "free" the pixels right away, don't let this confuse you */ 68435c4bbdfSmrg FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel); 68535c4bbdfSmrg FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel); 68605b261ecSmrg } 68705b261ecSmrg 6884642e01fSmrg pDevCursor->checkPixels = FALSE; 68905b261ecSmrg 69005b261ecSmrg} 69105b261ecSmrg 69205b261ecSmrg/* 69305b261ecSmrg * miPointer interface routines 69405b261ecSmrg */ 69505b261ecSmrg 69605b261ecSmrg#define SPRITE_PAD 8 69705b261ecSmrg 69805b261ecSmrgstatic Bool 69935c4bbdfSmrgmiSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 70005b261ecSmrg{ 7014642e01fSmrg miCursorInfoPtr pCursorInfo; 7024642e01fSmrg 70335c4bbdfSmrg if (IsFloating(pDev)) 7044642e01fSmrg return FALSE; 7056747b715Smrg 7061b5d61b8Smrg pCursorInfo = GetSprite(pDev); 7074642e01fSmrg 7084642e01fSmrg if (pCursor == pCursorInfo->pCursor) 70935c4bbdfSmrg pCursorInfo->checkPixels = TRUE; 71005b261ecSmrg 7116747b715Smrg return miDCRealizeCursor(pScreen, pCursor); 71205b261ecSmrg} 71305b261ecSmrg 71405b261ecSmrgstatic Bool 7154642e01fSmrgmiSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 71605b261ecSmrg{ 7176747b715Smrg return miDCUnrealizeCursor(pScreen, pCursor); 71805b261ecSmrg} 71905b261ecSmrg 72005b261ecSmrgstatic void 72135c4bbdfSmrgmiSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 72235c4bbdfSmrg CursorPtr pCursor, int x, int y) 72305b261ecSmrg{ 72435c4bbdfSmrg miCursorInfoPtr pPointer; 72535c4bbdfSmrg miSpriteScreenPtr pScreenPriv; 7264642e01fSmrg 72735c4bbdfSmrg if (IsFloating(pDev)) 7284642e01fSmrg return; 7296747b715Smrg 7301b5d61b8Smrg pPointer = GetSprite(pDev); 7319ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 7324642e01fSmrg 73335c4bbdfSmrg if (!pCursor) { 73435c4bbdfSmrg if (pPointer->shouldBeUp) 73535c4bbdfSmrg --pScreenPriv->numberOfCursors; 73635c4bbdfSmrg pPointer->shouldBeUp = FALSE; 73735c4bbdfSmrg if (pPointer->isUp) 73835c4bbdfSmrg miSpriteRemoveCursor(pDev, pScreen); 73935c4bbdfSmrg if (pScreenPriv->numberOfCursors == 0) 74035c4bbdfSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 74135c4bbdfSmrg pPointer->pCursor = 0; 74235c4bbdfSmrg return; 74305b261ecSmrg } 7449ace9065Smrg if (!pPointer->shouldBeUp) 74535c4bbdfSmrg pScreenPriv->numberOfCursors++; 7464642e01fSmrg pPointer->shouldBeUp = TRUE; 7479ace9065Smrg if (!pPointer->isUp) 74835c4bbdfSmrg miSpriteRegisterBlockHandler(pScreen, pScreenPriv); 7494642e01fSmrg if (pPointer->x == x && 75035c4bbdfSmrg pPointer->y == y && 75135c4bbdfSmrg pPointer->pCursor == pCursor && !pPointer->checkPixels) { 75235c4bbdfSmrg return; 75305b261ecSmrg } 7544642e01fSmrg pPointer->x = x; 7554642e01fSmrg pPointer->y = y; 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 7821b5d61b8Smrg pCursor = GetSprite(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 = 7961b5d61b8Smrg dixLookupPrivate(&pDev->devPrivates, &miSpriteDevPrivatesKeyRec); 79735c4bbdfSmrg pCursorInfo->pCursor = NULL; 79835c4bbdfSmrg pCursorInfo->x = 0; 79935c4bbdfSmrg pCursorInfo->y = 0; 80035c4bbdfSmrg pCursorInfo->isUp = FALSE; 80135c4bbdfSmrg pCursorInfo->shouldBeUp = FALSE; 80235c4bbdfSmrg pCursorInfo->checkPixels = TRUE; 80335c4bbdfSmrg pCursorInfo->pScreen = FALSE; 8044642e01fSmrg } 80535c4bbdfSmrg 8064642e01fSmrg return ret; 8074642e01fSmrg} 8084642e01fSmrg 8094642e01fSmrgstatic void 8104642e01fSmrgmiSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) 8114642e01fSmrg{ 81235c4bbdfSmrg miCursorInfoPtr pCursorInfo = 8131b5d61b8Smrg dixLookupPrivate(&pDev->devPrivates, &miSpriteDevPrivatesKeyRec); 81435c4bbdfSmrg 8154642e01fSmrg if (DevHasCursor(pDev)) 8166747b715Smrg miDCDeviceCleanup(pDev, pScreen); 81735c4bbdfSmrg 81835c4bbdfSmrg memset(pCursorInfo, 0, sizeof(miCursorInfoRec)); 81905b261ecSmrg} 82005b261ecSmrg 82105b261ecSmrg/* 82205b261ecSmrg * undraw/draw cursor 82305b261ecSmrg */ 82405b261ecSmrg 82505b261ecSmrgstatic void 82635c4bbdfSmrgmiSpriteRemoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen) 82705b261ecSmrg{ 82835c4bbdfSmrg miSpriteScreenPtr pScreenPriv; 82935c4bbdfSmrg miCursorInfoPtr pCursorInfo; 83005b261ecSmrg 83135c4bbdfSmrg if (IsFloating(pDev)) 8324642e01fSmrg return; 8336747b715Smrg 83435c4bbdfSmrg DamageDrawInternal(pScreen, TRUE); 8359ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 8361b5d61b8Smrg pCursorInfo = GetSprite(pDev); 8374642e01fSmrg 8384642e01fSmrg miSpriteIsDown(pCursorInfo); 8399ace9065Smrg miSpriteRegisterBlockHandler(pScreen, pScreenPriv); 8404642e01fSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 8416747b715Smrg if (!miDCRestoreUnderCursor(pDev, 8426747b715Smrg pScreen, 8436747b715Smrg pCursorInfo->saved.x1, 8446747b715Smrg pCursorInfo->saved.y1, 8456747b715Smrg pCursorInfo->saved.x2 - 8466747b715Smrg pCursorInfo->saved.x1, 8476747b715Smrg pCursorInfo->saved.y2 - 84835c4bbdfSmrg pCursorInfo->saved.y1)) { 8496747b715Smrg miSpriteIsUp(pCursorInfo); 85005b261ecSmrg } 8514642e01fSmrg miSpriteEnableDamage(pScreen, pScreenPriv); 85235c4bbdfSmrg DamageDrawInternal(pScreen, FALSE); 85305b261ecSmrg} 85405b261ecSmrg 8554642e01fSmrg/* 8564642e01fSmrg * Called from the block handler, saves area under cursor 8574642e01fSmrg * before waiting for something to do. 8584642e01fSmrg */ 8594642e01fSmrg 8604642e01fSmrgstatic void 8614642e01fSmrgmiSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen) 8624642e01fSmrg{ 86335c4bbdfSmrg miSpriteScreenPtr pScreenPriv; 86435c4bbdfSmrg miCursorInfoPtr pCursorInfo; 8654642e01fSmrg 86635c4bbdfSmrg if (IsFloating(pDev)) 8674642e01fSmrg return; 8686747b715Smrg 86935c4bbdfSmrg DamageDrawInternal(pScreen, TRUE); 8709ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 8711b5d61b8Smrg pCursorInfo = GetSprite(pDev); 8724642e01fSmrg 87335c4bbdfSmrg miSpriteComputeSaved(pDev, pScreen); 8744642e01fSmrg 8754642e01fSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 8764642e01fSmrg 8776747b715Smrg miDCSaveUnderCursor(pDev, 8786747b715Smrg pScreen, 8796747b715Smrg pCursorInfo->saved.x1, 8806747b715Smrg pCursorInfo->saved.y1, 8816747b715Smrg pCursorInfo->saved.x2 - 8826747b715Smrg pCursorInfo->saved.x1, 88335c4bbdfSmrg pCursorInfo->saved.y2 - pCursorInfo->saved.y1); 8844642e01fSmrg SPRITE_DEBUG(("SaveUnderCursor %d\n", pDev->id)); 8854642e01fSmrg miSpriteEnableDamage(pScreen, pScreenPriv); 88635c4bbdfSmrg DamageDrawInternal(pScreen, FALSE); 8874642e01fSmrg} 8884642e01fSmrg 88905b261ecSmrg/* 89005b261ecSmrg * Called from the block handler, restores the cursor 89105b261ecSmrg * before waiting for something to do. 89205b261ecSmrg */ 89305b261ecSmrg 89405b261ecSmrgstatic void 89535c4bbdfSmrgmiSpriteRestoreCursor(DeviceIntPtr pDev, ScreenPtr pScreen) 89605b261ecSmrg{ 89735c4bbdfSmrg miSpriteScreenPtr pScreenPriv; 89835c4bbdfSmrg int x, y; 89935c4bbdfSmrg CursorPtr pCursor; 90035c4bbdfSmrg miCursorInfoPtr pCursorInfo; 9014642e01fSmrg 90235c4bbdfSmrg if (IsFloating(pDev)) 9034642e01fSmrg return; 90405b261ecSmrg 90535c4bbdfSmrg DamageDrawInternal(pScreen, TRUE); 9069ace9065Smrg pScreenPriv = GetSpriteScreen(pScreen); 9071b5d61b8Smrg pCursorInfo = GetSprite(pDev); 9084642e01fSmrg 90935c4bbdfSmrg miSpriteComputeSaved(pDev, pScreen); 9104642e01fSmrg pCursor = pCursorInfo->pCursor; 9114642e01fSmrg 91235c4bbdfSmrg x = pCursorInfo->x - (int) pCursor->bits->xhot; 91335c4bbdfSmrg y = pCursorInfo->y - (int) pCursor->bits->yhot; 9144642e01fSmrg miSpriteDisableDamage(pScreen, pScreenPriv); 9154642e01fSmrg SPRITE_DEBUG(("RestoreCursor %d\n", pDev->id)); 9164642e01fSmrg if (pCursorInfo->checkPixels) 91735c4bbdfSmrg miSpriteFindColors(pCursorInfo, pScreen); 9186747b715Smrg if (miDCPutUpCursor(pDev, pScreen, 91935c4bbdfSmrg pCursor, x, y, 92035c4bbdfSmrg pScreenPriv->colors[SOURCE_COLOR].pixel, 92135c4bbdfSmrg pScreenPriv->colors[MASK_COLOR].pixel)) { 9224642e01fSmrg miSpriteIsUp(pCursorInfo); 9234642e01fSmrg pCursorInfo->pScreen = pScreen; 92405b261ecSmrg } 9254642e01fSmrg miSpriteEnableDamage(pScreen, pScreenPriv); 92635c4bbdfSmrg DamageDrawInternal(pScreen, FALSE); 92705b261ecSmrg} 92805b261ecSmrg 92905b261ecSmrg/* 93005b261ecSmrg * compute the desired area of the screen to save 93105b261ecSmrg */ 93205b261ecSmrg 93305b261ecSmrgstatic void 93435c4bbdfSmrgmiSpriteComputeSaved(DeviceIntPtr pDev, ScreenPtr pScreen) 93505b261ecSmrg{ 93635c4bbdfSmrg int x, y, w, h; 93735c4bbdfSmrg int wpad, hpad; 93835c4bbdfSmrg CursorPtr pCursor; 9394642e01fSmrg miCursorInfoPtr pCursorInfo; 94005b261ecSmrg 94135c4bbdfSmrg if (IsFloating(pDev)) 9424642e01fSmrg return; 9436747b715Smrg 9441b5d61b8Smrg pCursorInfo = GetSprite(pDev); 9454642e01fSmrg 9464642e01fSmrg pCursor = pCursorInfo->pCursor; 94735c4bbdfSmrg x = pCursorInfo->x - (int) pCursor->bits->xhot; 94835c4bbdfSmrg y = pCursorInfo->y - (int) pCursor->bits->yhot; 94905b261ecSmrg w = pCursor->bits->width; 95005b261ecSmrg h = pCursor->bits->height; 95105b261ecSmrg wpad = SPRITE_PAD; 95205b261ecSmrg hpad = SPRITE_PAD; 9534642e01fSmrg pCursorInfo->saved.x1 = x - wpad; 9544642e01fSmrg pCursorInfo->saved.y1 = y - hpad; 9554642e01fSmrg pCursorInfo->saved.x2 = pCursorInfo->saved.x1 + w + wpad * 2; 9564642e01fSmrg pCursorInfo->saved.y2 = pCursorInfo->saved.y1 + h + hpad * 2; 95705b261ecSmrg} 958