summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/mi/midispcur.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver/mi/midispcur.c')
-rw-r--r--xc/programs/Xserver/mi/midispcur.c208
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