diff options
Diffstat (limited to 'mi/midispcur.c')
-rw-r--r-- | mi/midispcur.c | 262 |
1 files changed, 217 insertions, 45 deletions
diff --git a/mi/midispcur.c b/mi/midispcur.c index 4c33d8e1d..3917a7928 100644 --- a/mi/midispcur.c +++ b/mi/midispcur.c @@ -30,6 +30,7 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ +/* $XFree86: xc/programs/Xserver/mi/midispcur.c,v 1.9 2002/12/09 04:10:57 tsi Exp $ */ #define NEED_EVENTS # include "X.h" @@ -44,15 +45,16 @@ in this Software without prior written authorization from The Open Group. # include "mipointer.h" # include "misprite.h" # include "gcstruct.h" - -extern WindowPtr *WindowTable; +#ifdef ARGB_CURSOR +# include "picturestr.h" +#endif /* per-screen private data */ static int miDCScreenIndex; static unsigned long miDCGeneration = 0; -static Bool miDCCloseScreen(); +static Bool miDCCloseScreen(int index, ScreenPtr pScreen); typedef struct { GCPtr pSourceGC, pMaskGC; @@ -61,22 +63,39 @@ typedef struct { GCPtr pPixSourceGC, pPixMaskGC; CloseScreenProcPtr CloseScreen; PixmapPtr pSave, pTemp; +#ifdef ARGB_CURSOR + PicturePtr pRootPicture; + PicturePtr pTempPicture; +#endif } miDCScreenRec, *miDCScreenPtr; /* per-cursor per-screen private data */ typedef struct { PixmapPtr sourceBits; /* source bits */ PixmapPtr maskBits; /* mask bits */ +#ifdef ARGB_CURSOR + PicturePtr pPicture; +#endif } miDCCursorRec, *miDCCursorPtr; /* * sprite/cursor method table */ -static Bool miDCRealizeCursor(), miDCUnrealizeCursor(); -static Bool miDCPutUpCursor(), miDCSaveUnderCursor(); -static Bool miDCRestoreUnderCursor(), miDCMoveCursor(); -static Bool miDCChangeSave(); +static Bool miDCRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor); +static Bool miDCUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor); +static Bool miDCPutUpCursor(ScreenPtr pScreen, CursorPtr pCursor, + int x, int y, unsigned long source, + unsigned long mask); +static Bool miDCSaveUnderCursor(ScreenPtr pScreen, int x, int y, + int w, int h); +static Bool miDCRestoreUnderCursor(ScreenPtr pScreen, int x, int y, + int w, int h); +static Bool miDCMoveCursor(ScreenPtr pScreen, CursorPtr pCursor, + int x, int y, int w, int h, int dx, int dy, + unsigned long source, unsigned long mask); +static Bool miDCChangeSave(ScreenPtr pScreen, int x, int y, int w, int h, + int dx, int dy); static miSpriteCursorFuncRec miDCFuncs = { miDCRealizeCursor, @@ -117,6 +136,10 @@ miDCInitialize (pScreen, screenFuncs) pScreenPriv->pMoveGC = pScreenPriv->pPixSourceGC = pScreenPriv->pPixMaskGC = NULL; +#ifdef ARGB_CURSOR + pScreenPriv->pRootPicture = NULL; + pScreenPriv->pTempPicture = NULL; +#endif pScreenPriv->pSave = pScreenPriv->pTemp = NULL; @@ -135,9 +158,11 @@ miDCInitialize (pScreen, screenFuncs) #define tossGC(gc) (gc ? FreeGC (gc, (GContext) 0) : 0) #define tossPix(pix) (pix ? (*pScreen->DestroyPixmap) (pix) : TRUE) +#define tossPict(pict) (pict ? FreePicture (pict, 0) : 0) static Bool miDCCloseScreen (index, pScreen) + int index; ScreenPtr pScreen; { miDCScreenPtr pScreenPriv; @@ -153,6 +178,10 @@ miDCCloseScreen (index, pScreen) tossGC (pScreenPriv->pPixMaskGC); tossPix (pScreenPriv->pSave); tossPix (pScreenPriv->pTemp); +#ifdef ARGB_CURSOR + tossPict (pScreenPriv->pRootPicture); + tossPict (pScreenPriv->pTempPicture); +#endif xfree ((pointer) pScreenPriv); return (*pScreen->CloseScreen) (index, pScreen); } @@ -167,10 +196,50 @@ miDCRealizeCursor (pScreen, pCursor) return TRUE; } +#ifdef ARGB_CURSOR +#define EnsurePicture(picture,draw,win) (picture || miDCMakePicture(&picture,draw,win)) + +static VisualPtr +miDCGetWindowVisual (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + VisualID vid = wVisual (pWin); + int i; + + for (i = 0; i < pScreen->numVisuals; i++) + if (pScreen->visuals[i].vid == vid) + return &pScreen->visuals[i]; + return 0; +} + +static PicturePtr +miDCMakePicture (PicturePtr *ppPicture, DrawablePtr pDraw, WindowPtr pWin) +{ + ScreenPtr pScreen = pDraw->pScreen; + VisualPtr pVisual; + PictFormatPtr pFormat; + XID subwindow_mode = IncludeInferiors; + PicturePtr pPicture; + int error; + + pVisual = miDCGetWindowVisual (pWin); + if (!pVisual) + return 0; + pFormat = PictureMatchVisual (pScreen, pDraw->depth, pVisual); + if (!pFormat) + return 0; + pPicture = CreatePicture (0, pDraw, pFormat, + CPSubwindowMode, &subwindow_mode, + serverClient, &error); + *ppPicture = pPicture; + return pPicture; +} +#endif + static miDCCursorPtr -miDCRealize (pScreen, pCursor) - ScreenPtr pScreen; - CursorPtr pCursor; +miDCRealize ( + ScreenPtr pScreen, + CursorPtr pCursor) { miDCCursorPtr pPriv; GCPtr pGC; @@ -179,6 +248,55 @@ miDCRealize (pScreen, pCursor) pPriv = (miDCCursorPtr) xalloc (sizeof (miDCCursorRec)); if (!pPriv) return (miDCCursorPtr)NULL; +#ifdef ARGB_CURSOR + if (pCursor->bits->argb) + { + PixmapPtr pPixmap; + PictFormatPtr pFormat; + int error; + + pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8); + if (!pFormat) + { + xfree ((pointer) pPriv); + return (miDCCursorPtr)NULL; + } + + pPriv->sourceBits = 0; + pPriv->maskBits = 0; + pPixmap = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, + pCursor->bits->height, 32); + if (!pPixmap) + { + xfree ((pointer) pPriv); + return (miDCCursorPtr)NULL; + } + pGC = GetScratchGC (32, pScreen); + if (!pGC) + { + (*pScreen->DestroyPixmap) (pPixmap); + xfree ((pointer) pPriv); + return (miDCCursorPtr)NULL; + } + ValidateGC (&pPixmap->drawable, pGC); + (*pGC->ops->PutImage) (&pPixmap->drawable, pGC, 32, + 0, 0, pCursor->bits->width, + pCursor->bits->height, + 0, ZPixmap, (char *) pCursor->bits->argb); + FreeScratchGC (pGC); + pPriv->pPicture = CreatePicture (0, &pPixmap->drawable, + pFormat, 0, 0, serverClient, &error); + (*pScreen->DestroyPixmap) (pPixmap); + if (!pPriv->pPicture) + { + xfree ((pointer) pPriv); + return (miDCCursorPtr)NULL; + } + pCursor->bits->devPriv[pScreen->myNum] = (pointer) pPriv; + return pPriv; + } + pPriv->pPicture = 0; +#endif pPriv->sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1); if (!pPriv->sourceBits) { @@ -241,8 +359,14 @@ miDCUnrealizeCursor (pScreen, pCursor) pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum]; if (pPriv && (pCursor->bits->refcnt <= 1)) { - (*pScreen->DestroyPixmap) (pPriv->sourceBits); - (*pScreen->DestroyPixmap) (pPriv->maskBits); + if (pPriv->sourceBits) + (*pScreen->DestroyPixmap) (pPriv->sourceBits); + if (pPriv->maskBits) + (*pScreen->DestroyPixmap) (pPriv->maskBits); +#ifdef ARGB_CURSOR + if (pPriv->pPicture) + FreePicture (pPriv->pPicture, 0); +#endif xfree ((pointer) pPriv); pCursor->bits->devPriv[pScreen->myNum] = (pointer)NULL; } @@ -250,13 +374,17 @@ miDCUnrealizeCursor (pScreen, pCursor) } static void -miDCPutBits (pDrawable, pPriv, sourceGC, maskGC, x, y, w, h, source, mask) - DrawablePtr pDrawable; - GCPtr sourceGC, maskGC; - int x, y; - unsigned w, h; - miDCCursorPtr pPriv; - unsigned long source, mask; +miDCPutBits ( + DrawablePtr pDrawable, + miDCCursorPtr pPriv, + GCPtr sourceGC, + GCPtr maskGC, + int x, + int y, + unsigned w, + unsigned h, + unsigned long source, + unsigned long mask) { XID gcvals[1]; @@ -281,9 +409,9 @@ miDCPutBits (pDrawable, pPriv, sourceGC, maskGC, x, y, w, h, source, mask) #define EnsureGC(gc,win) (gc || miDCMakeGC(&gc, win)) static GCPtr -miDCMakeGC(ppGC, pWin) - GCPtr *ppGC; - WindowPtr pWin; +miDCMakeGC( + GCPtr *ppGC, + WindowPtr pWin) { GCPtr pGC; int status; @@ -293,12 +421,13 @@ miDCMakeGC(ppGC, pWin) gcvals[1] = FALSE; pGC = CreateGC((DrawablePtr)pWin, GCSubwindowMode|GCGraphicsExposures, gcvals, &status); - if (pGC) + if (pGC && pWin->drawable.pScreen->DrawGuarantee) (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack); *ppGC = pGC; return pGC; } + static Bool miDCPutUpCursor (pScreen, pCursor, x, y, source, mask) ScreenPtr pScreen; @@ -319,18 +448,36 @@ miDCPutUpCursor (pScreen, pCursor, x, y, source, mask) } pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; pWin = WindowTable[pScreen->myNum]; - if (!EnsureGC(pScreenPriv->pSourceGC, pWin)) - return FALSE; - if (!EnsureGC(pScreenPriv->pMaskGC, pWin)) +#ifdef ARGB_CURSOR + if (pPriv->pPicture) { - FreeGC (pScreenPriv->pSourceGC, (GContext) 0); - pScreenPriv->pSourceGC = 0; - return FALSE; + if (!EnsurePicture(pScreenPriv->pRootPicture, &pWin->drawable, pWin)) + return FALSE; + CompositePicture (PictOpOver, + pPriv->pPicture, + NULL, + pScreenPriv->pRootPicture, + 0, 0, 0, 0, + x, y, + pCursor->bits->width, + pCursor->bits->height); + } + else +#endif + { + if (!EnsureGC(pScreenPriv->pSourceGC, pWin)) + return FALSE; + if (!EnsureGC(pScreenPriv->pMaskGC, pWin)) + { + FreeGC (pScreenPriv->pSourceGC, (GContext) 0); + pScreenPriv->pSourceGC = 0; + return FALSE; + } + miDCPutBits ((DrawablePtr)pWin, pPriv, + pScreenPriv->pSourceGC, pScreenPriv->pMaskGC, + x, y, pCursor->bits->width, pCursor->bits->height, + source, mask); } - miDCPutBits ((DrawablePtr)pWin, pPriv, - pScreenPriv->pSourceGC, pScreenPriv->pMaskGC, - x, y, pCursor->bits->width, pCursor->bits->height, - source, mask); return TRUE; } @@ -554,6 +701,13 @@ miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask) { if (pTemp) (*pScreen->DestroyPixmap) (pTemp); +#ifdef ARGB_CURSOR + if (pScreenPriv->pTempPicture) + { + FreePicture (pScreenPriv->pTempPicture, 0); + pScreenPriv->pTempPicture = 0; + } +#endif pScreenPriv->pTemp = pTemp = (*pScreen->CreatePixmap) (pScreen, w, h, pScreenPriv->pSave->drawable.depth); if (!pTemp) @@ -578,24 +732,42 @@ miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask) /* * draw the cursor in the temporary pixmap */ - if (!pScreenPriv->pPixSourceGC) +#ifdef ARGB_CURSOR + if (pPriv->pPicture) { - pScreenPriv->pPixSourceGC = CreateGC ((DrawablePtr)pTemp, - GCGraphicsExposures, &gcval, &status); - if (!pScreenPriv->pPixSourceGC) + if (!EnsurePicture(pScreenPriv->pTempPicture, &pTemp->drawable, pWin)) return FALSE; + CompositePicture (PictOpOver, + pPriv->pPicture, + NULL, + pScreenPriv->pTempPicture, + 0, 0, 0, 0, + dx, dy, + pCursor->bits->width, + pCursor->bits->height); } - if (!pScreenPriv->pPixMaskGC) + else +#endif { - pScreenPriv->pPixMaskGC = CreateGC ((DrawablePtr)pTemp, - GCGraphicsExposures, &gcval, &status); + if (!pScreenPriv->pPixSourceGC) + { + pScreenPriv->pPixSourceGC = CreateGC ((DrawablePtr)pTemp, + GCGraphicsExposures, &gcval, &status); + if (!pScreenPriv->pPixSourceGC) + return FALSE; + } if (!pScreenPriv->pPixMaskGC) - return FALSE; + { + pScreenPriv->pPixMaskGC = CreateGC ((DrawablePtr)pTemp, + GCGraphicsExposures, &gcval, &status); + if (!pScreenPriv->pPixMaskGC) + return FALSE; + } + miDCPutBits ((DrawablePtr)pTemp, pPriv, + pScreenPriv->pPixSourceGC, pScreenPriv->pPixMaskGC, + dx, dy, pCursor->bits->width, pCursor->bits->height, + source, mask); } - miDCPutBits ((DrawablePtr)pTemp, pPriv, - pScreenPriv->pPixSourceGC, pScreenPriv->pPixMaskGC, - dx, dy, pCursor->bits->width, pCursor->bits->height, - source, mask); /* * copy the temporary pixmap onto the screen |