diff options
Diffstat (limited to 'xc/programs/Xserver/mi/midispcur.c')
-rw-r--r-- | xc/programs/Xserver/mi/midispcur.c | 208 |
1 files changed, 183 insertions, 25 deletions
diff --git a/xc/programs/Xserver/mi/midispcur.c b/xc/programs/Xserver/mi/midispcur.c index 7106a8214..dec9ce7b9 100644 --- a/xc/programs/Xserver/mi/midispcur.c +++ b/xc/programs/Xserver/mi/midispcur.c @@ -30,7 +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.6 2001/12/14 20:00:21 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/mi/midispcur.c,v 1.8 2002/08/28 19:45:08 keithp Exp $ */ #define NEED_EVENTS # include "X.h" @@ -45,6 +45,9 @@ in this Software without prior written authorization from The Open Group. # include "mipointer.h" # include "misprite.h" # include "gcstruct.h" +#ifdef ARGB_CURSOR +# include "picturestr.h" +#endif /* per-screen private data */ @@ -60,12 +63,19 @@ 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; /* @@ -126,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; @@ -144,6 +158,7 @@ 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) @@ -162,6 +177,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); } @@ -176,6 +195,46 @@ 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 ( ScreenPtr pScreen, @@ -188,6 +247,55 @@ miDCRealize ( 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) { @@ -250,8 +358,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; } @@ -312,6 +426,7 @@ miDCMakeGC( return pGC; } + static Bool miDCPutUpCursor (pScreen, pCursor, x, y, source, mask) ScreenPtr pScreen; @@ -332,18 +447,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; } @@ -567,6 +700,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) @@ -591,24 +731,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 |