1706f2543Smrg/* 2706f2543Smrg * misprite.c 3706f2543Smrg * 4706f2543Smrg * machine independent software sprite routines 5706f2543Smrg */ 6706f2543Smrg 7706f2543Smrg/* 8706f2543Smrg 9706f2543SmrgCopyright 1989, 1998 The Open Group 10706f2543Smrg 11706f2543SmrgPermission to use, copy, modify, distribute, and sell this software and its 12706f2543Smrgdocumentation for any purpose is hereby granted without fee, provided that 13706f2543Smrgthe above copyright notice appear in all copies and that both that 14706f2543Smrgcopyright notice and this permission notice appear in supporting 15706f2543Smrgdocumentation. 16706f2543Smrg 17706f2543SmrgThe above copyright notice and this permission notice shall be included in 18706f2543Smrgall copies or substantial portions of the Software. 19706f2543Smrg 20706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23706f2543SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 24706f2543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 25706f2543SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26706f2543Smrg 27706f2543SmrgExcept as contained in this notice, the name of The Open Group shall not be 28706f2543Smrgused in advertising or otherwise to promote the sale, use or other dealings 29706f2543Smrgin this Software without prior written authorization from The Open Group. 30706f2543Smrg*/ 31706f2543Smrg 32706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 33706f2543Smrg#include <dix-config.h> 34706f2543Smrg#endif 35706f2543Smrg 36706f2543Smrg#include <X11/X.h> 37706f2543Smrg#include <X11/Xproto.h> 38706f2543Smrg#include "misc.h" 39706f2543Smrg#include "pixmapstr.h" 40706f2543Smrg#include "input.h" 41706f2543Smrg#include "mi.h" 42706f2543Smrg#include "cursorstr.h" 43706f2543Smrg#include <X11/fonts/font.h> 44706f2543Smrg#include "scrnintstr.h" 45706f2543Smrg#include "colormapst.h" 46706f2543Smrg#include "windowstr.h" 47706f2543Smrg#include "gcstruct.h" 48706f2543Smrg#include "mipointer.h" 49706f2543Smrg#include "misprite.h" 50706f2543Smrg#include "dixfontstr.h" 51706f2543Smrg#include <X11/fonts/fontstruct.h> 52706f2543Smrg#include "inputstr.h" 53706f2543Smrg#include "damage.h" 54706f2543Smrg 55706f2543Smrgtypedef struct { 56706f2543Smrg CursorPtr pCursor; 57706f2543Smrg int x; /* cursor hotspot */ 58706f2543Smrg int y; 59706f2543Smrg BoxRec saved; /* saved area from the screen */ 60706f2543Smrg Bool isUp; /* cursor in frame buffer */ 61706f2543Smrg Bool shouldBeUp; /* cursor should be displayed */ 62706f2543Smrg WindowPtr pCacheWin; /* window the cursor last seen in */ 63706f2543Smrg Bool isInCacheWin; 64706f2543Smrg Bool checkPixels; /* check colormap collision */ 65706f2543Smrg ScreenPtr pScreen; 66706f2543Smrg} miCursorInfoRec, *miCursorInfoPtr; 67706f2543Smrg 68706f2543Smrg/* 69706f2543Smrg * per screen information 70706f2543Smrg */ 71706f2543Smrg 72706f2543Smrgtypedef struct { 73706f2543Smrg /* screen procedures */ 74706f2543Smrg CloseScreenProcPtr CloseScreen; 75706f2543Smrg GetImageProcPtr GetImage; 76706f2543Smrg GetSpansProcPtr GetSpans; 77706f2543Smrg SourceValidateProcPtr SourceValidate; 78706f2543Smrg 79706f2543Smrg /* window procedures */ 80706f2543Smrg CopyWindowProcPtr CopyWindow; 81706f2543Smrg 82706f2543Smrg /* colormap procedures */ 83706f2543Smrg InstallColormapProcPtr InstallColormap; 84706f2543Smrg StoreColorsProcPtr StoreColors; 85706f2543Smrg 86706f2543Smrg /* os layer procedures */ 87706f2543Smrg ScreenBlockHandlerProcPtr BlockHandler; 88706f2543Smrg 89706f2543Smrg /* device cursor procedures */ 90706f2543Smrg DeviceCursorInitializeProcPtr DeviceCursorInitialize; 91706f2543Smrg DeviceCursorCleanupProcPtr DeviceCursorCleanup; 92706f2543Smrg 93706f2543Smrg xColorItem colors[2]; 94706f2543Smrg ColormapPtr pInstalledMap; 95706f2543Smrg ColormapPtr pColormap; 96706f2543Smrg VisualPtr pVisual; 97706f2543Smrg DamagePtr pDamage; /* damage tracking structure */ 98706f2543Smrg Bool damageRegistered; 99706f2543Smrg int numberOfCursors; 100706f2543Smrg} miSpriteScreenRec, *miSpriteScreenPtr; 101706f2543Smrg 102706f2543Smrg#define SOURCE_COLOR 0 103706f2543Smrg#define MASK_COLOR 1 104706f2543Smrg 105706f2543Smrg/* 106706f2543Smrg * Overlap BoxPtr and Box elements 107706f2543Smrg */ 108706f2543Smrg#define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \ 109706f2543Smrg (((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \ 110706f2543Smrg ((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2)) 111706f2543Smrg 112706f2543Smrg/* 113706f2543Smrg * Overlap BoxPtr, origins, and rectangle 114706f2543Smrg */ 115706f2543Smrg#define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \ 116706f2543Smrg BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h)) 117706f2543Smrg 118706f2543Smrg/* 119706f2543Smrg * Overlap BoxPtr, origins and RectPtr 120706f2543Smrg */ 121706f2543Smrg#define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \ 122706f2543Smrg ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y, \ 123706f2543Smrg (int)((pRect)->width), (int)((pRect)->height)) 124706f2543Smrg/* 125706f2543Smrg * Overlap BoxPtr and horizontal span 126706f2543Smrg */ 127706f2543Smrg#define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y)) 128706f2543Smrg 129706f2543Smrg#define LINE_SORT(x1,y1,x2,y2) \ 130706f2543Smrg{ int _t; \ 131706f2543Smrg if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \ 132706f2543Smrg if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } } 133706f2543Smrg 134706f2543Smrg#define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \ 135706f2543Smrg BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2)) 136706f2543Smrg 137706f2543Smrg 138706f2543Smrg#define SPRITE_DEBUG_ENABLE 0 139706f2543Smrg#if SPRITE_DEBUG_ENABLE 140706f2543Smrg#define SPRITE_DEBUG(x) ErrorF x 141706f2543Smrg#else 142706f2543Smrg#define SPRITE_DEBUG(x) 143706f2543Smrg#endif 144706f2543Smrg 145706f2543Smrg#define MISPRITE(dev) \ 146706f2543Smrg ((!IsMaster(dev) && !dev->u.master) ? \ 147706f2543Smrg (miCursorInfoPtr)dixLookupPrivate(&dev->devPrivates, miSpriteDevPrivatesKey) : \ 148706f2543Smrg (miCursorInfoPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miSpriteDevPrivatesKey)) 149706f2543Smrg 150706f2543Smrgstatic void 151706f2543SmrgmiSpriteDisableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 152706f2543Smrg{ 153706f2543Smrg if (pScreenPriv->damageRegistered) { 154706f2543Smrg DamageUnregister (&(pScreen->GetScreenPixmap(pScreen)->drawable), 155706f2543Smrg pScreenPriv->pDamage); 156706f2543Smrg pScreenPriv->damageRegistered = 0; 157706f2543Smrg } 158706f2543Smrg} 159706f2543Smrg 160706f2543Smrgstatic void 161706f2543SmrgmiSpriteEnableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 162706f2543Smrg{ 163706f2543Smrg if (!pScreenPriv->damageRegistered) { 164706f2543Smrg pScreenPriv->damageRegistered = 1; 165706f2543Smrg DamageRegister (&(pScreen->GetScreenPixmap(pScreen)->drawable), 166706f2543Smrg pScreenPriv->pDamage); 167706f2543Smrg } 168706f2543Smrg} 169706f2543Smrg 170706f2543Smrgstatic void 171706f2543SmrgmiSpriteIsUp(miCursorInfoPtr pDevCursor) 172706f2543Smrg{ 173706f2543Smrg pDevCursor->isUp = TRUE; 174706f2543Smrg} 175706f2543Smrg 176706f2543Smrgstatic void 177706f2543SmrgmiSpriteIsDown(miCursorInfoPtr pDevCursor) 178706f2543Smrg{ 179706f2543Smrg pDevCursor->isUp = FALSE; 180706f2543Smrg} 181706f2543Smrg 182706f2543Smrg/* 183706f2543Smrg * screen wrappers 184706f2543Smrg */ 185706f2543Smrg 186706f2543Smrgstatic DevPrivateKeyRec miSpriteScreenKeyRec; 187706f2543Smrg#define miSpriteScreenKey (&miSpriteScreenKeyRec) 188706f2543Smrg#define GetSpriteScreen(pScreen) \ 189706f2543Smrg (dixLookupPrivate(&(pScreen)->devPrivates, miSpriteScreenKey)) 190706f2543Smrgstatic DevPrivateKeyRec miSpriteDevPrivatesKeyRec; 191706f2543Smrg#define miSpriteDevPrivatesKey (&miSpriteDevPrivatesKeyRec) 192706f2543Smrg 193706f2543Smrgstatic Bool miSpriteCloseScreen(int i, ScreenPtr pScreen); 194706f2543Smrgstatic void miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy, 195706f2543Smrg int w, int h, unsigned int format, 196706f2543Smrg unsigned long planemask, char *pdstLine); 197706f2543Smrgstatic void miSpriteGetSpans(DrawablePtr pDrawable, int wMax, 198706f2543Smrg DDXPointPtr ppt, int *pwidth, int nspans, 199706f2543Smrg char *pdstStart); 200706f2543Smrgstatic void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, 201706f2543Smrg int width, int height, 202706f2543Smrg unsigned int subWindowMode); 203706f2543Smrgstatic void miSpriteCopyWindow (WindowPtr pWindow, 204706f2543Smrg DDXPointRec ptOldOrg, 205706f2543Smrg RegionPtr prgnSrc); 206706f2543Smrgstatic void miSpriteBlockHandler(int i, pointer blockData, 207706f2543Smrg pointer pTimeout, 208706f2543Smrg pointer pReadMask); 209706f2543Smrgstatic void miSpriteInstallColormap(ColormapPtr pMap); 210706f2543Smrgstatic void miSpriteStoreColors(ColormapPtr pMap, int ndef, 211706f2543Smrg xColorItem *pdef); 212706f2543Smrg 213706f2543Smrgstatic void miSpriteComputeSaved(DeviceIntPtr pDev, 214706f2543Smrg ScreenPtr pScreen); 215706f2543Smrg 216706f2543Smrgstatic Bool miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, 217706f2543Smrg ScreenPtr pScreen); 218706f2543Smrgstatic void miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, 219706f2543Smrg ScreenPtr pScreen); 220706f2543Smrg 221706f2543Smrg#define SCREEN_PROLOGUE(pPriv, pScreen, field) ((pScreen)->field = \ 222706f2543Smrg (pPriv)->field) 223706f2543Smrg#define SCREEN_EPILOGUE(pPriv, pScreen, field)\ 224706f2543Smrg ((pPriv)->field = (pScreen)->field, (pScreen)->field = miSprite##field) 225706f2543Smrg 226706f2543Smrg/* 227706f2543Smrg * pointer-sprite method table 228706f2543Smrg */ 229706f2543Smrg 230706f2543Smrgstatic Bool miSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 231706f2543Smrg CursorPtr pCursor); 232706f2543Smrgstatic Bool miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 233706f2543Smrg CursorPtr pCursor); 234706f2543Smrgstatic void miSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 235706f2543Smrg CursorPtr pCursor, int x, int y); 236706f2543Smrgstatic void miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 237706f2543Smrg int x, int y); 238706f2543Smrg 239706f2543SmrgmiPointerSpriteFuncRec miSpritePointerFuncs = { 240706f2543Smrg miSpriteRealizeCursor, 241706f2543Smrg miSpriteUnrealizeCursor, 242706f2543Smrg miSpriteSetCursor, 243706f2543Smrg miSpriteMoveCursor, 244706f2543Smrg miSpriteDeviceCursorInitialize, 245706f2543Smrg miSpriteDeviceCursorCleanup, 246706f2543Smrg}; 247706f2543Smrg 248706f2543Smrg/* 249706f2543Smrg * other misc functions 250706f2543Smrg */ 251706f2543Smrg 252706f2543Smrgstatic void miSpriteRemoveCursor(DeviceIntPtr pDev, 253706f2543Smrg ScreenPtr pScreen); 254706f2543Smrgstatic void miSpriteSaveUnderCursor(DeviceIntPtr pDev, 255706f2543Smrg ScreenPtr pScreen); 256706f2543Smrgstatic void miSpriteRestoreCursor(DeviceIntPtr pDev, 257706f2543Smrg ScreenPtr pScreen); 258706f2543Smrg 259706f2543Smrgstatic void 260706f2543SmrgmiSpriteRegisterBlockHandler(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv) 261706f2543Smrg{ 262706f2543Smrg if (!pScreenPriv->BlockHandler) { 263706f2543Smrg pScreenPriv->BlockHandler = pScreen->BlockHandler; 264706f2543Smrg pScreen->BlockHandler = miSpriteBlockHandler; 265706f2543Smrg } 266706f2543Smrg} 267706f2543Smrg 268706f2543Smrgstatic void 269706f2543SmrgmiSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure) 270706f2543Smrg{ 271706f2543Smrg ScreenPtr pScreen = closure; 272706f2543Smrg miCursorInfoPtr pCursorInfo; 273706f2543Smrg DeviceIntPtr pDev; 274706f2543Smrg 275706f2543Smrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) 276706f2543Smrg { 277706f2543Smrg if (DevHasCursor(pDev)) 278706f2543Smrg { 279706f2543Smrg pCursorInfo = MISPRITE(pDev); 280706f2543Smrg 281706f2543Smrg if (pCursorInfo->isUp && 282706f2543Smrg pCursorInfo->pScreen == pScreen && 283706f2543Smrg RegionContainsRect(pRegion, &pCursorInfo->saved) != rgnOUT) 284706f2543Smrg { 285706f2543Smrg SPRITE_DEBUG(("Damage remove\n")); 286706f2543Smrg miSpriteRemoveCursor (pDev, pScreen); 287706f2543Smrg } 288706f2543Smrg } 289706f2543Smrg } 290706f2543Smrg} 291706f2543Smrg 292706f2543Smrg/* 293706f2543Smrg * miSpriteInitialize -- called from device-dependent screen 294706f2543Smrg * initialization proc after all of the function pointers have 295706f2543Smrg * been stored in the screen structure. 296706f2543Smrg */ 297706f2543Smrg 298706f2543SmrgBool 299706f2543SmrgmiSpriteInitialize (ScreenPtr pScreen, 300706f2543Smrg miPointerScreenFuncPtr screenFuncs) 301706f2543Smrg{ 302706f2543Smrg miSpriteScreenPtr pScreenPriv; 303706f2543Smrg VisualPtr pVisual; 304706f2543Smrg 305706f2543Smrg if (!DamageSetup (pScreen)) 306706f2543Smrg return FALSE; 307706f2543Smrg 308706f2543Smrg if (!dixRegisterPrivateKey(&miSpriteScreenKeyRec, PRIVATE_SCREEN, 0)) 309706f2543Smrg return FALSE; 310706f2543Smrg 311706f2543Smrg if (!dixRegisterPrivateKey(&miSpriteDevPrivatesKeyRec, PRIVATE_DEVICE, 0)) 312706f2543Smrg return FALSE; 313706f2543Smrg 314706f2543Smrg pScreenPriv = malloc(sizeof (miSpriteScreenRec)); 315706f2543Smrg if (!pScreenPriv) 316706f2543Smrg return FALSE; 317706f2543Smrg 318706f2543Smrg pScreenPriv->pDamage = DamageCreate (miSpriteReportDamage, 319706f2543Smrg NULL, 320706f2543Smrg DamageReportRawRegion, 321706f2543Smrg TRUE, 322706f2543Smrg pScreen, 323706f2543Smrg pScreen); 324706f2543Smrg 325706f2543Smrg if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE)) 326706f2543Smrg { 327706f2543Smrg free(pScreenPriv); 328706f2543Smrg return FALSE; 329706f2543Smrg } 330706f2543Smrg for (pVisual = pScreen->visuals; 331706f2543Smrg pVisual->vid != pScreen->rootVisual; 332706f2543Smrg pVisual++) 333706f2543Smrg ; 334706f2543Smrg pScreenPriv->pVisual = pVisual; 335706f2543Smrg pScreenPriv->CloseScreen = pScreen->CloseScreen; 336706f2543Smrg pScreenPriv->GetImage = pScreen->GetImage; 337706f2543Smrg pScreenPriv->GetSpans = pScreen->GetSpans; 338706f2543Smrg pScreenPriv->SourceValidate = pScreen->SourceValidate; 339706f2543Smrg 340706f2543Smrg pScreenPriv->CopyWindow = pScreen->CopyWindow; 341706f2543Smrg 342706f2543Smrg pScreenPriv->InstallColormap = pScreen->InstallColormap; 343706f2543Smrg pScreenPriv->StoreColors = pScreen->StoreColors; 344706f2543Smrg 345706f2543Smrg pScreenPriv->BlockHandler = NULL; 346706f2543Smrg 347706f2543Smrg pScreenPriv->DeviceCursorInitialize = pScreen->DeviceCursorInitialize; 348706f2543Smrg pScreenPriv->DeviceCursorCleanup = pScreen->DeviceCursorCleanup; 349706f2543Smrg 350706f2543Smrg pScreenPriv->pInstalledMap = NULL; 351706f2543Smrg pScreenPriv->pColormap = NULL; 352706f2543Smrg pScreenPriv->colors[SOURCE_COLOR].red = 0; 353706f2543Smrg pScreenPriv->colors[SOURCE_COLOR].green = 0; 354706f2543Smrg pScreenPriv->colors[SOURCE_COLOR].blue = 0; 355706f2543Smrg pScreenPriv->colors[MASK_COLOR].red = 0; 356706f2543Smrg pScreenPriv->colors[MASK_COLOR].green = 0; 357706f2543Smrg pScreenPriv->colors[MASK_COLOR].blue = 0; 358706f2543Smrg pScreenPriv->damageRegistered = 0; 359706f2543Smrg pScreenPriv->numberOfCursors = 0; 360706f2543Smrg 361706f2543Smrg dixSetPrivate(&pScreen->devPrivates, miSpriteScreenKey, pScreenPriv); 362706f2543Smrg 363706f2543Smrg pScreen->CloseScreen = miSpriteCloseScreen; 364706f2543Smrg pScreen->GetImage = miSpriteGetImage; 365706f2543Smrg pScreen->GetSpans = miSpriteGetSpans; 366706f2543Smrg pScreen->SourceValidate = miSpriteSourceValidate; 367706f2543Smrg 368706f2543Smrg pScreen->CopyWindow = miSpriteCopyWindow; 369706f2543Smrg pScreen->InstallColormap = miSpriteInstallColormap; 370706f2543Smrg pScreen->StoreColors = miSpriteStoreColors; 371706f2543Smrg 372706f2543Smrg return TRUE; 373706f2543Smrg} 374706f2543Smrg 375706f2543Smrg/* 376706f2543Smrg * Screen wrappers 377706f2543Smrg */ 378706f2543Smrg 379706f2543Smrg/* 380706f2543Smrg * CloseScreen wrapper -- unwrap everything, free the private data 381706f2543Smrg * and call the wrapped function 382706f2543Smrg */ 383706f2543Smrg 384706f2543Smrgstatic Bool 385706f2543SmrgmiSpriteCloseScreen (int i, ScreenPtr pScreen) 386706f2543Smrg{ 387706f2543Smrg miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); 388706f2543Smrg 389706f2543Smrg pScreen->CloseScreen = pScreenPriv->CloseScreen; 390706f2543Smrg pScreen->GetImage = pScreenPriv->GetImage; 391706f2543Smrg pScreen->GetSpans = pScreenPriv->GetSpans; 392706f2543Smrg pScreen->SourceValidate = pScreenPriv->SourceValidate; 393706f2543Smrg pScreen->InstallColormap = pScreenPriv->InstallColormap; 394706f2543Smrg pScreen->StoreColors = pScreenPriv->StoreColors; 395706f2543Smrg 396706f2543Smrg DamageDestroy (pScreenPriv->pDamage); 397706f2543Smrg 398706f2543Smrg free(pScreenPriv); 399706f2543Smrg 400706f2543Smrg return (*pScreen->CloseScreen) (i, pScreen); 401706f2543Smrg} 402706f2543Smrg 403706f2543Smrgstatic void 404706f2543SmrgmiSpriteGetImage (DrawablePtr pDrawable, int sx, int sy, int w, int h, 405706f2543Smrg unsigned int format, unsigned long planemask, 406706f2543Smrg char *pdstLine) 407706f2543Smrg{ 408706f2543Smrg ScreenPtr pScreen = pDrawable->pScreen; 409706f2543Smrg DeviceIntPtr pDev; 410706f2543Smrg miCursorInfoPtr pCursorInfo; 411706f2543Smrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 412706f2543Smrg 413706f2543Smrg SCREEN_PROLOGUE (pPriv, pScreen, GetImage); 414706f2543Smrg 415706f2543Smrg if (pDrawable->type == DRAWABLE_WINDOW) 416706f2543Smrg { 417706f2543Smrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 418706f2543Smrg { 419706f2543Smrg if (DevHasCursor(pDev)) 420706f2543Smrg { 421706f2543Smrg pCursorInfo = MISPRITE(pDev); 422706f2543Smrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 423706f2543Smrg ORG_OVERLAP(&pCursorInfo->saved,pDrawable->x,pDrawable->y, 424706f2543Smrg sx, sy, w, h)) 425706f2543Smrg { 426706f2543Smrg SPRITE_DEBUG (("GetImage remove\n")); 427706f2543Smrg miSpriteRemoveCursor (pDev, pScreen); 428706f2543Smrg } 429706f2543Smrg } 430706f2543Smrg } 431706f2543Smrg } 432706f2543Smrg 433706f2543Smrg (*pScreen->GetImage) (pDrawable, sx, sy, w, h, 434706f2543Smrg format, planemask, pdstLine); 435706f2543Smrg 436706f2543Smrg SCREEN_EPILOGUE (pPriv, pScreen, GetImage); 437706f2543Smrg} 438706f2543Smrg 439706f2543Smrgstatic void 440706f2543SmrgmiSpriteGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, 441706f2543Smrg int *pwidth, int nspans, char *pdstStart) 442706f2543Smrg{ 443706f2543Smrg ScreenPtr pScreen = pDrawable->pScreen; 444706f2543Smrg DeviceIntPtr pDev; 445706f2543Smrg miCursorInfoPtr pCursorInfo; 446706f2543Smrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 447706f2543Smrg 448706f2543Smrg SCREEN_PROLOGUE (pPriv, pScreen, GetSpans); 449706f2543Smrg 450706f2543Smrg if (pDrawable->type == DRAWABLE_WINDOW) 451706f2543Smrg { 452706f2543Smrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 453706f2543Smrg { 454706f2543Smrg if (DevHasCursor(pDev)) 455706f2543Smrg { 456706f2543Smrg pCursorInfo = MISPRITE(pDev); 457706f2543Smrg 458706f2543Smrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) 459706f2543Smrg { 460706f2543Smrg DDXPointPtr pts; 461706f2543Smrg int *widths; 462706f2543Smrg int nPts; 463706f2543Smrg int xorg, 464706f2543Smrg yorg; 465706f2543Smrg 466706f2543Smrg xorg = pDrawable->x; 467706f2543Smrg yorg = pDrawable->y; 468706f2543Smrg 469706f2543Smrg for (pts = ppt, widths = pwidth, nPts = nspans; 470706f2543Smrg nPts--; 471706f2543Smrg pts++, widths++) 472706f2543Smrg { 473706f2543Smrg if (SPN_OVERLAP(&pCursorInfo->saved,pts->y+yorg, 474706f2543Smrg pts->x+xorg,*widths)) 475706f2543Smrg { 476706f2543Smrg SPRITE_DEBUG (("GetSpans remove\n")); 477706f2543Smrg miSpriteRemoveCursor (pDev, pScreen); 478706f2543Smrg break; 479706f2543Smrg } 480706f2543Smrg } 481706f2543Smrg } 482706f2543Smrg } 483706f2543Smrg } 484706f2543Smrg } 485706f2543Smrg 486706f2543Smrg (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); 487706f2543Smrg 488706f2543Smrg SCREEN_EPILOGUE (pPriv, pScreen, GetSpans); 489706f2543Smrg} 490706f2543Smrg 491706f2543Smrgstatic void 492706f2543SmrgmiSpriteSourceValidate (DrawablePtr pDrawable, int x, int y, int width, 493706f2543Smrg int height, unsigned int subWindowMode) 494706f2543Smrg{ 495706f2543Smrg ScreenPtr pScreen = pDrawable->pScreen; 496706f2543Smrg DeviceIntPtr pDev; 497706f2543Smrg miCursorInfoPtr pCursorInfo; 498706f2543Smrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 499706f2543Smrg 500706f2543Smrg SCREEN_PROLOGUE (pPriv, pScreen, SourceValidate); 501706f2543Smrg 502706f2543Smrg if (pDrawable->type == DRAWABLE_WINDOW) 503706f2543Smrg { 504706f2543Smrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 505706f2543Smrg { 506706f2543Smrg if (DevHasCursor(pDev)) 507706f2543Smrg { 508706f2543Smrg pCursorInfo = MISPRITE(pDev); 509706f2543Smrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 510706f2543Smrg ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y, 511706f2543Smrg x, y, width, height)) 512706f2543Smrg { 513706f2543Smrg SPRITE_DEBUG (("SourceValidate remove\n")); 514706f2543Smrg miSpriteRemoveCursor (pDev, pScreen); 515706f2543Smrg } 516706f2543Smrg } 517706f2543Smrg } 518706f2543Smrg } 519706f2543Smrg 520706f2543Smrg if (pScreen->SourceValidate) 521706f2543Smrg (*pScreen->SourceValidate) (pDrawable, x, y, width, height, subWindowMode); 522706f2543Smrg 523706f2543Smrg SCREEN_EPILOGUE (pPriv, pScreen, SourceValidate); 524706f2543Smrg} 525706f2543Smrg 526706f2543Smrgstatic void 527706f2543SmrgmiSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) 528706f2543Smrg{ 529706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 530706f2543Smrg DeviceIntPtr pDev; 531706f2543Smrg miCursorInfoPtr pCursorInfo; 532706f2543Smrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 533706f2543Smrg 534706f2543Smrg SCREEN_PROLOGUE (pPriv, pScreen, CopyWindow); 535706f2543Smrg 536706f2543Smrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 537706f2543Smrg { 538706f2543Smrg if (DevHasCursor(pDev)) 539706f2543Smrg { 540706f2543Smrg pCursorInfo = MISPRITE(pDev); 541706f2543Smrg /* 542706f2543Smrg * Damage will take care of destination check 543706f2543Smrg */ 544706f2543Smrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && 545706f2543Smrg RegionContainsRect(prgnSrc, &pCursorInfo->saved) != rgnOUT) 546706f2543Smrg { 547706f2543Smrg SPRITE_DEBUG (("CopyWindow remove\n")); 548706f2543Smrg miSpriteRemoveCursor (pDev, pScreen); 549706f2543Smrg } 550706f2543Smrg } 551706f2543Smrg } 552706f2543Smrg 553706f2543Smrg (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc); 554706f2543Smrg SCREEN_EPILOGUE (pPriv, pScreen, CopyWindow); 555706f2543Smrg} 556706f2543Smrg 557706f2543Smrgstatic void 558706f2543SmrgmiSpriteBlockHandler (int i, pointer blockData, pointer pTimeout, 559706f2543Smrg pointer pReadmask) 560706f2543Smrg{ 561706f2543Smrg ScreenPtr pScreen = screenInfo.screens[i]; 562706f2543Smrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 563706f2543Smrg DeviceIntPtr pDev; 564706f2543Smrg miCursorInfoPtr pCursorInfo; 565706f2543Smrg Bool WorkToDo = FALSE; 566706f2543Smrg 567706f2543Smrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 568706f2543Smrg { 569706f2543Smrg if (DevHasCursor(pDev)) 570706f2543Smrg { 571706f2543Smrg pCursorInfo = MISPRITE(pDev); 572706f2543Smrg if (pCursorInfo && !pCursorInfo->isUp 573706f2543Smrg && pCursorInfo->pScreen == pScreen 574706f2543Smrg && pCursorInfo->shouldBeUp) 575706f2543Smrg { 576706f2543Smrg SPRITE_DEBUG (("BlockHandler save")); 577706f2543Smrg miSpriteSaveUnderCursor (pDev, pScreen); 578706f2543Smrg } 579706f2543Smrg } 580706f2543Smrg } 581706f2543Smrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 582706f2543Smrg { 583706f2543Smrg if (DevHasCursor(pDev)) 584706f2543Smrg { 585706f2543Smrg pCursorInfo = MISPRITE(pDev); 586706f2543Smrg if (pCursorInfo && !pCursorInfo->isUp && 587706f2543Smrg pCursorInfo->pScreen == pScreen && 588706f2543Smrg pCursorInfo->shouldBeUp) 589706f2543Smrg { 590706f2543Smrg SPRITE_DEBUG (("BlockHandler restore\n")); 591706f2543Smrg miSpriteRestoreCursor (pDev, pScreen); 592706f2543Smrg if (!pCursorInfo->isUp) 593706f2543Smrg WorkToDo = TRUE; 594706f2543Smrg } 595706f2543Smrg } 596706f2543Smrg } 597706f2543Smrg 598706f2543Smrg SCREEN_PROLOGUE(pPriv, pScreen, BlockHandler); 599706f2543Smrg 600706f2543Smrg (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 601706f2543Smrg 602706f2543Smrg if (WorkToDo) 603706f2543Smrg SCREEN_EPILOGUE(pPriv, pScreen, BlockHandler); 604706f2543Smrg else 605706f2543Smrg pPriv->BlockHandler = NULL; 606706f2543Smrg} 607706f2543Smrg 608706f2543Smrgstatic void 609706f2543SmrgmiSpriteInstallColormap (ColormapPtr pMap) 610706f2543Smrg{ 611706f2543Smrg ScreenPtr pScreen = pMap->pScreen; 612706f2543Smrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 613706f2543Smrg 614706f2543Smrg SCREEN_PROLOGUE(pPriv, pScreen, InstallColormap); 615706f2543Smrg 616706f2543Smrg (*pScreen->InstallColormap) (pMap); 617706f2543Smrg 618706f2543Smrg SCREEN_EPILOGUE(pPriv, pScreen, InstallColormap); 619706f2543Smrg 620706f2543Smrg /* InstallColormap can be called before devices are initialized. */ 621706f2543Smrg pPriv->pInstalledMap = pMap; 622706f2543Smrg if (pPriv->pColormap != pMap) 623706f2543Smrg { 624706f2543Smrg DeviceIntPtr pDev; 625706f2543Smrg miCursorInfoPtr pCursorInfo; 626706f2543Smrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) 627706f2543Smrg { 628706f2543Smrg if (DevHasCursor(pDev)) 629706f2543Smrg { 630706f2543Smrg pCursorInfo = MISPRITE(pDev); 631706f2543Smrg pCursorInfo->checkPixels = TRUE; 632706f2543Smrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) 633706f2543Smrg miSpriteRemoveCursor(pDev, pScreen); 634706f2543Smrg } 635706f2543Smrg } 636706f2543Smrg 637706f2543Smrg } 638706f2543Smrg} 639706f2543Smrg 640706f2543Smrgstatic void 641706f2543SmrgmiSpriteStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef) 642706f2543Smrg{ 643706f2543Smrg ScreenPtr pScreen = pMap->pScreen; 644706f2543Smrg miSpriteScreenPtr pPriv = GetSpriteScreen(pScreen); 645706f2543Smrg int i; 646706f2543Smrg int updated; 647706f2543Smrg VisualPtr pVisual; 648706f2543Smrg DeviceIntPtr pDev; 649706f2543Smrg miCursorInfoPtr pCursorInfo; 650706f2543Smrg 651706f2543Smrg SCREEN_PROLOGUE(pPriv, pScreen, StoreColors); 652706f2543Smrg 653706f2543Smrg (*pScreen->StoreColors) (pMap, ndef, pdef); 654706f2543Smrg 655706f2543Smrg SCREEN_EPILOGUE(pPriv, pScreen, StoreColors); 656706f2543Smrg 657706f2543Smrg if (pPriv->pColormap == pMap) 658706f2543Smrg { 659706f2543Smrg updated = 0; 660706f2543Smrg pVisual = pMap->pVisual; 661706f2543Smrg if (pVisual->class == DirectColor) 662706f2543Smrg { 663706f2543Smrg /* Direct color - match on any of the subfields */ 664706f2543Smrg 665706f2543Smrg#define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask))) 666706f2543Smrg 667706f2543Smrg#define UpdateDAC(dev, plane,dac,mask) {\ 668706f2543Smrg if (MaskMatch (dev->colors[plane].pixel,pdef[i].pixel,mask)) {\ 669706f2543Smrg dev->colors[plane].dac = pdef[i].dac; \ 670706f2543Smrg updated = 1; \ 671706f2543Smrg } \ 672706f2543Smrg} 673706f2543Smrg 674706f2543Smrg#define CheckDirect(dev, plane) \ 675706f2543Smrg UpdateDAC(dev, plane,red,redMask) \ 676706f2543Smrg UpdateDAC(dev, plane,green,greenMask) \ 677706f2543Smrg UpdateDAC(dev, plane,blue,blueMask) 678706f2543Smrg 679706f2543Smrg for (i = 0; i < ndef; i++) 680706f2543Smrg { 681706f2543Smrg CheckDirect (pPriv, SOURCE_COLOR) 682706f2543Smrg CheckDirect (pPriv, MASK_COLOR) 683706f2543Smrg } 684706f2543Smrg } 685706f2543Smrg else 686706f2543Smrg { 687706f2543Smrg /* PseudoColor/GrayScale - match on exact pixel */ 688706f2543Smrg for (i = 0; i < ndef; i++) 689706f2543Smrg { 690706f2543Smrg if (pdef[i].pixel == 691706f2543Smrg pPriv->colors[SOURCE_COLOR].pixel) 692706f2543Smrg { 693706f2543Smrg pPriv->colors[SOURCE_COLOR] = pdef[i]; 694706f2543Smrg if (++updated == 2) 695706f2543Smrg break; 696706f2543Smrg } 697706f2543Smrg if (pdef[i].pixel == 698706f2543Smrg pPriv->colors[MASK_COLOR].pixel) 699706f2543Smrg { 700706f2543Smrg pPriv->colors[MASK_COLOR] = pdef[i]; 701706f2543Smrg if (++updated == 2) 702706f2543Smrg break; 703706f2543Smrg } 704706f2543Smrg } 705706f2543Smrg } 706706f2543Smrg if (updated) 707706f2543Smrg { 708706f2543Smrg for(pDev = inputInfo.devices; pDev; pDev = pDev->next) 709706f2543Smrg { 710706f2543Smrg if (DevHasCursor(pDev)) 711706f2543Smrg { 712706f2543Smrg pCursorInfo = MISPRITE(pDev); 713706f2543Smrg pCursorInfo->checkPixels = TRUE; 714706f2543Smrg if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) 715706f2543Smrg miSpriteRemoveCursor (pDev, pScreen); 716706f2543Smrg } 717706f2543Smrg } 718706f2543Smrg } 719706f2543Smrg } 720706f2543Smrg} 721706f2543Smrg 722706f2543Smrgstatic void 723706f2543SmrgmiSpriteFindColors (miCursorInfoPtr pDevCursor, ScreenPtr pScreen) 724706f2543Smrg{ 725706f2543Smrg miSpriteScreenPtr pScreenPriv = GetSpriteScreen(pScreen); 726706f2543Smrg CursorPtr pCursor; 727706f2543Smrg xColorItem *sourceColor, *maskColor; 728706f2543Smrg 729706f2543Smrg pCursor = pDevCursor->pCursor; 730706f2543Smrg sourceColor = &pScreenPriv->colors[SOURCE_COLOR]; 731706f2543Smrg maskColor = &pScreenPriv->colors[MASK_COLOR]; 732706f2543Smrg if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap || 733706f2543Smrg !(pCursor->foreRed == sourceColor->red && 734706f2543Smrg pCursor->foreGreen == sourceColor->green && 735706f2543Smrg pCursor->foreBlue == sourceColor->blue && 736706f2543Smrg pCursor->backRed == maskColor->red && 737706f2543Smrg pCursor->backGreen == maskColor->green && 738706f2543Smrg pCursor->backBlue == maskColor->blue)) 739706f2543Smrg { 740706f2543Smrg pScreenPriv->pColormap = pScreenPriv->pInstalledMap; 741706f2543Smrg sourceColor->red = pCursor->foreRed; 742706f2543Smrg sourceColor->green = pCursor->foreGreen; 743706f2543Smrg sourceColor->blue = pCursor->foreBlue; 744706f2543Smrg FakeAllocColor (pScreenPriv->pColormap, sourceColor); 745706f2543Smrg maskColor->red = pCursor->backRed; 746706f2543Smrg maskColor->green = pCursor->backGreen; 747706f2543Smrg maskColor->blue = pCursor->backBlue; 748706f2543Smrg FakeAllocColor (pScreenPriv->pColormap, maskColor); 749706f2543Smrg /* "free" the pixels right away, don't let this confuse you */ 750706f2543Smrg FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel); 751706f2543Smrg FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel); 752706f2543Smrg } 753706f2543Smrg 754706f2543Smrg pDevCursor->checkPixels = FALSE; 755706f2543Smrg 756706f2543Smrg} 757706f2543Smrg 758706f2543Smrg/* 759706f2543Smrg * miPointer interface routines 760706f2543Smrg */ 761706f2543Smrg 762706f2543Smrg#define SPRITE_PAD 8 763706f2543Smrg 764706f2543Smrgstatic Bool 765706f2543SmrgmiSpriteRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 766706f2543Smrg{ 767706f2543Smrg miCursorInfoPtr pCursorInfo; 768706f2543Smrg 769706f2543Smrg if (!IsMaster(pDev) && !pDev->u.master) 770706f2543Smrg return FALSE; 771706f2543Smrg 772706f2543Smrg pCursorInfo = MISPRITE(pDev); 773706f2543Smrg 774706f2543Smrg if (pCursor == pCursorInfo->pCursor) 775706f2543Smrg pCursorInfo->checkPixels = TRUE; 776706f2543Smrg 777706f2543Smrg return miDCRealizeCursor(pScreen, pCursor); 778706f2543Smrg} 779706f2543Smrg 780706f2543Smrgstatic Bool 781706f2543SmrgmiSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) 782706f2543Smrg{ 783706f2543Smrg return miDCUnrealizeCursor(pScreen, pCursor); 784706f2543Smrg} 785706f2543Smrg 786706f2543Smrgstatic void 787706f2543SmrgmiSpriteSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, 788706f2543Smrg CursorPtr pCursor, int x, int y) 789706f2543Smrg{ 790706f2543Smrg miCursorInfoPtr pPointer; 791706f2543Smrg miSpriteScreenPtr pScreenPriv; 792706f2543Smrg 793706f2543Smrg if (!IsMaster(pDev) && !pDev->u.master) 794706f2543Smrg return; 795706f2543Smrg 796706f2543Smrg pPointer = MISPRITE(pDev); 797706f2543Smrg pScreenPriv = GetSpriteScreen(pScreen); 798706f2543Smrg 799706f2543Smrg if (!pCursor) 800706f2543Smrg { 801706f2543Smrg if (pPointer->shouldBeUp) 802706f2543Smrg --pScreenPriv->numberOfCursors; 803706f2543Smrg pPointer->shouldBeUp = FALSE; 804706f2543Smrg if (pPointer->isUp) 805706f2543Smrg miSpriteRemoveCursor (pDev, pScreen); 806706f2543Smrg if (pScreenPriv->numberOfCursors == 0) 807706f2543Smrg miSpriteDisableDamage(pScreen, pScreenPriv); 808706f2543Smrg pPointer->pCursor = 0; 809706f2543Smrg return; 810706f2543Smrg } 811706f2543Smrg if (!pPointer->shouldBeUp) 812706f2543Smrg pScreenPriv->numberOfCursors++; 813706f2543Smrg pPointer->shouldBeUp = TRUE; 814706f2543Smrg if (!pPointer->isUp) 815706f2543Smrg miSpriteRegisterBlockHandler(pScreen, pScreenPriv); 816706f2543Smrg if (pPointer->x == x && 817706f2543Smrg pPointer->y == y && 818706f2543Smrg pPointer->pCursor == pCursor && 819706f2543Smrg !pPointer->checkPixels) 820706f2543Smrg { 821706f2543Smrg return; 822706f2543Smrg } 823706f2543Smrg pPointer->x = x; 824706f2543Smrg pPointer->y = y; 825706f2543Smrg pPointer->pCacheWin = NullWindow; 826706f2543Smrg if (pPointer->checkPixels || pPointer->pCursor != pCursor) 827706f2543Smrg { 828706f2543Smrg pPointer->pCursor = pCursor; 829706f2543Smrg miSpriteFindColors (pPointer, pScreen); 830706f2543Smrg } 831706f2543Smrg if (pPointer->isUp) { 832706f2543Smrg /* TODO: reimplement flicker-free MoveCursor */ 833706f2543Smrg SPRITE_DEBUG (("SetCursor remove %d\n", pDev->id)); 834706f2543Smrg miSpriteRemoveCursor (pDev, pScreen); 835706f2543Smrg } 836706f2543Smrg 837706f2543Smrg if (!pPointer->isUp && pPointer->pCursor) 838706f2543Smrg { 839706f2543Smrg SPRITE_DEBUG (("SetCursor restore %d\n", pDev->id)); 840706f2543Smrg miSpriteSaveUnderCursor(pDev, pScreen); 841706f2543Smrg miSpriteRestoreCursor (pDev, pScreen); 842706f2543Smrg } 843706f2543Smrg 844706f2543Smrg} 845706f2543Smrg 846706f2543Smrgstatic void 847706f2543SmrgmiSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 848706f2543Smrg{ 849706f2543Smrg CursorPtr pCursor; 850706f2543Smrg 851706f2543Smrg if (!IsMaster(pDev) && !pDev->u.master) 852706f2543Smrg return; 853706f2543Smrg 854706f2543Smrg pCursor = MISPRITE(pDev)->pCursor; 855706f2543Smrg 856706f2543Smrg miSpriteSetCursor (pDev, pScreen, pCursor, x, y); 857706f2543Smrg} 858706f2543Smrg 859706f2543Smrg 860706f2543Smrgstatic Bool 861706f2543SmrgmiSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) 862706f2543Smrg{ 863706f2543Smrg miCursorInfoPtr pCursorInfo; 864706f2543Smrg int ret = FALSE; 865706f2543Smrg 866706f2543Smrg pCursorInfo = malloc(sizeof(miCursorInfoRec)); 867706f2543Smrg if (!pCursorInfo) 868706f2543Smrg return FALSE; 869706f2543Smrg 870706f2543Smrg pCursorInfo->pCursor = NULL; 871706f2543Smrg pCursorInfo->x = 0; 872706f2543Smrg pCursorInfo->y = 0; 873706f2543Smrg pCursorInfo->isUp = FALSE; 874706f2543Smrg pCursorInfo->shouldBeUp = FALSE; 875706f2543Smrg pCursorInfo->pCacheWin = NullWindow; 876706f2543Smrg pCursorInfo->isInCacheWin = FALSE; 877706f2543Smrg pCursorInfo->checkPixels = TRUE; 878706f2543Smrg pCursorInfo->pScreen = FALSE; 879706f2543Smrg 880706f2543Smrg ret = miDCDeviceInitialize(pDev, pScreen); 881706f2543Smrg if (!ret) 882706f2543Smrg { 883706f2543Smrg free(pCursorInfo); 884706f2543Smrg pCursorInfo = NULL; 885706f2543Smrg } 886706f2543Smrg dixSetPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey, pCursorInfo); 887706f2543Smrg return ret; 888706f2543Smrg} 889706f2543Smrg 890706f2543Smrgstatic void 891706f2543SmrgmiSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) 892706f2543Smrg{ 893706f2543Smrg if (DevHasCursor(pDev)) 894706f2543Smrg miDCDeviceCleanup(pDev, pScreen); 895706f2543Smrg} 896706f2543Smrg 897706f2543Smrg/* 898706f2543Smrg * undraw/draw cursor 899706f2543Smrg */ 900706f2543Smrg 901706f2543Smrgstatic void 902706f2543SmrgmiSpriteRemoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen) 903706f2543Smrg{ 904706f2543Smrg miSpriteScreenPtr pScreenPriv; 905706f2543Smrg miCursorInfoPtr pCursorInfo; 906706f2543Smrg 907706f2543Smrg 908706f2543Smrg if (!IsMaster(pDev) && !pDev->u.master) 909706f2543Smrg return; 910706f2543Smrg 911706f2543Smrg DamageDrawInternal (pScreen, TRUE); 912706f2543Smrg pScreenPriv = GetSpriteScreen(pScreen); 913706f2543Smrg pCursorInfo = MISPRITE(pDev); 914706f2543Smrg 915706f2543Smrg miSpriteIsDown(pCursorInfo); 916706f2543Smrg miSpriteRegisterBlockHandler(pScreen, pScreenPriv); 917706f2543Smrg pCursorInfo->pCacheWin = NullWindow; 918706f2543Smrg miSpriteDisableDamage(pScreen, pScreenPriv); 919706f2543Smrg if (!miDCRestoreUnderCursor(pDev, 920706f2543Smrg pScreen, 921706f2543Smrg pCursorInfo->saved.x1, 922706f2543Smrg pCursorInfo->saved.y1, 923706f2543Smrg pCursorInfo->saved.x2 - 924706f2543Smrg pCursorInfo->saved.x1, 925706f2543Smrg pCursorInfo->saved.y2 - 926706f2543Smrg pCursorInfo->saved.y1)) 927706f2543Smrg { 928706f2543Smrg miSpriteIsUp(pCursorInfo); 929706f2543Smrg } 930706f2543Smrg miSpriteEnableDamage(pScreen, pScreenPriv); 931706f2543Smrg DamageDrawInternal (pScreen, FALSE); 932706f2543Smrg} 933706f2543Smrg 934706f2543Smrg/* 935706f2543Smrg * Called from the block handler, saves area under cursor 936706f2543Smrg * before waiting for something to do. 937706f2543Smrg */ 938706f2543Smrg 939706f2543Smrgstatic void 940706f2543SmrgmiSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen) 941706f2543Smrg{ 942706f2543Smrg miSpriteScreenPtr pScreenPriv; 943706f2543Smrg int x, y; 944706f2543Smrg CursorPtr pCursor; 945706f2543Smrg miCursorInfoPtr pCursorInfo; 946706f2543Smrg 947706f2543Smrg if (!IsMaster(pDev) && !pDev->u.master) 948706f2543Smrg return; 949706f2543Smrg 950706f2543Smrg DamageDrawInternal (pScreen, TRUE); 951706f2543Smrg pScreenPriv = GetSpriteScreen(pScreen); 952706f2543Smrg pCursorInfo = MISPRITE(pDev); 953706f2543Smrg 954706f2543Smrg miSpriteComputeSaved (pDev, pScreen); 955706f2543Smrg pCursor = pCursorInfo->pCursor; 956706f2543Smrg 957706f2543Smrg x = pCursorInfo->x - (int)pCursor->bits->xhot; 958706f2543Smrg y = pCursorInfo->y - (int)pCursor->bits->yhot; 959706f2543Smrg miSpriteDisableDamage(pScreen, pScreenPriv); 960706f2543Smrg 961706f2543Smrg miDCSaveUnderCursor(pDev, 962706f2543Smrg pScreen, 963706f2543Smrg pCursorInfo->saved.x1, 964706f2543Smrg pCursorInfo->saved.y1, 965706f2543Smrg pCursorInfo->saved.x2 - 966706f2543Smrg pCursorInfo->saved.x1, 967706f2543Smrg pCursorInfo->saved.y2 - 968706f2543Smrg pCursorInfo->saved.y1); 969706f2543Smrg SPRITE_DEBUG(("SaveUnderCursor %d\n", pDev->id)); 970706f2543Smrg miSpriteEnableDamage(pScreen, pScreenPriv); 971706f2543Smrg DamageDrawInternal (pScreen, FALSE); 972706f2543Smrg} 973706f2543Smrg 974706f2543Smrg 975706f2543Smrg/* 976706f2543Smrg * Called from the block handler, restores the cursor 977706f2543Smrg * before waiting for something to do. 978706f2543Smrg */ 979706f2543Smrg 980706f2543Smrgstatic void 981706f2543SmrgmiSpriteRestoreCursor (DeviceIntPtr pDev, ScreenPtr pScreen) 982706f2543Smrg{ 983706f2543Smrg miSpriteScreenPtr pScreenPriv; 984706f2543Smrg int x, y; 985706f2543Smrg CursorPtr pCursor; 986706f2543Smrg miCursorInfoPtr pCursorInfo; 987706f2543Smrg 988706f2543Smrg if (!IsMaster(pDev) && !pDev->u.master) 989706f2543Smrg return; 990706f2543Smrg 991706f2543Smrg DamageDrawInternal (pScreen, TRUE); 992706f2543Smrg pScreenPriv = GetSpriteScreen(pScreen); 993706f2543Smrg pCursorInfo = MISPRITE(pDev); 994706f2543Smrg 995706f2543Smrg miSpriteComputeSaved (pDev, pScreen); 996706f2543Smrg pCursor = pCursorInfo->pCursor; 997706f2543Smrg 998706f2543Smrg x = pCursorInfo->x - (int)pCursor->bits->xhot; 999706f2543Smrg y = pCursorInfo->y - (int)pCursor->bits->yhot; 1000706f2543Smrg miSpriteDisableDamage(pScreen, pScreenPriv); 1001706f2543Smrg SPRITE_DEBUG(("RestoreCursor %d\n", pDev->id)); 1002706f2543Smrg if (pCursorInfo->checkPixels) 1003706f2543Smrg miSpriteFindColors (pCursorInfo, pScreen); 1004706f2543Smrg if (miDCPutUpCursor(pDev, pScreen, 1005706f2543Smrg pCursor, x, y, 1006706f2543Smrg pScreenPriv->colors[SOURCE_COLOR].pixel, 1007706f2543Smrg pScreenPriv->colors[MASK_COLOR].pixel)) 1008706f2543Smrg { 1009706f2543Smrg miSpriteIsUp(pCursorInfo); 1010706f2543Smrg pCursorInfo->pScreen = pScreen; 1011706f2543Smrg } 1012706f2543Smrg miSpriteEnableDamage(pScreen, pScreenPriv); 1013706f2543Smrg DamageDrawInternal (pScreen, FALSE); 1014706f2543Smrg} 1015706f2543Smrg 1016706f2543Smrg/* 1017706f2543Smrg * compute the desired area of the screen to save 1018706f2543Smrg */ 1019706f2543Smrg 1020706f2543Smrgstatic void 1021706f2543SmrgmiSpriteComputeSaved (DeviceIntPtr pDev, ScreenPtr pScreen) 1022706f2543Smrg{ 1023706f2543Smrg int x, y, w, h; 1024706f2543Smrg int wpad, hpad; 1025706f2543Smrg CursorPtr pCursor; 1026706f2543Smrg miCursorInfoPtr pCursorInfo; 1027706f2543Smrg 1028706f2543Smrg if (!IsMaster(pDev) && !pDev->u.master) 1029706f2543Smrg return; 1030706f2543Smrg 1031706f2543Smrg pCursorInfo = MISPRITE(pDev); 1032706f2543Smrg 1033706f2543Smrg pCursor = pCursorInfo->pCursor; 1034706f2543Smrg x = pCursorInfo->x - (int)pCursor->bits->xhot; 1035706f2543Smrg y = pCursorInfo->y - (int)pCursor->bits->yhot; 1036706f2543Smrg w = pCursor->bits->width; 1037706f2543Smrg h = pCursor->bits->height; 1038706f2543Smrg wpad = SPRITE_PAD; 1039706f2543Smrg hpad = SPRITE_PAD; 1040706f2543Smrg pCursorInfo->saved.x1 = x - wpad; 1041706f2543Smrg pCursorInfo->saved.y1 = y - hpad; 1042706f2543Smrg pCursorInfo->saved.x2 = pCursorInfo->saved.x1 + w + wpad * 2; 1043706f2543Smrg pCursorInfo->saved.y2 = pCursorInfo->saved.y1 + h + hpad * 2; 1044706f2543Smrg} 1045706f2543Smrg 1046