summaryrefslogtreecommitdiff
path: root/miext/cw/cw_render.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2004-07-31 07:52:02 +0000
committerKeith Packard <keithp@keithp.com>2004-07-31 07:52:02 +0000
commitd3566e95c1b7ac00cea6797a8a7c0fc6f965f1e3 (patch)
tree6cc6827571dd422aeded1c0979fad6280e3466b8 /miext/cw/cw_render.c
parent6ff8c33f503b2f5097d6e21c0393d27897d93261 (diff)
Rewrite render support in composite wrapper to (almost) work. FIXME:COMPOSITEWRAP
PaintWindowBackground/CopyWindow is still broken. Remove mfb from Xvfb. Use standard visual formats so Render actually works.
Diffstat (limited to 'miext/cw/cw_render.c')
-rw-r--r--miext/cw/cw_render.c513
1 files changed, 411 insertions, 102 deletions
diff --git a/miext/cw/cw_render.c b/miext/cw/cw_render.c
index a78d0ab67..4f8bed8e4 100644
--- a/miext/cw/cw_render.c
+++ b/miext/cw/cw_render.c
@@ -27,112 +27,421 @@
#ifdef RENDER
-extern int cwScreenIndex;
-
-void
-cwComposite(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
- cwScreenPtr pScreenPriv =
- (cwScreenPtr)pScreen->devPrivates[cwScreenIndex].ptr;
- DrawablePtr pSrcDraw, pMaskDraw = NULL, pDstDraw;
- DrawablePtr pBackSrcDraw, pBackMaskDraw, pBackDstDraw;
- int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
-
- pSrcDraw = pSrc->pDrawable;
- pBackSrcDraw = cwGetBackingDrawable(pSrcDraw, &src_off_x, &src_off_y);
- xSrc += src_off_x;
- ySrc += src_off_y;
- pSrc->pDrawable = pBackSrcDraw;
-
- pDstDraw = pDst->pDrawable;
- pBackDstDraw = cwGetBackingDrawable(pDstDraw, &dst_off_x, &dst_off_y);
- xDst += dst_off_x;
- yDst += dst_off_y;
- pDst->pDrawable = pBackDstDraw;
-
- if (pMask) {
- pMaskDraw = pMask->pDrawable;
- pBackMaskDraw = cwGetBackingDrawable(pMaskDraw, &mask_off_x,
- &mask_off_y);
- xMask += mask_off_x;
- yMask += mask_off_y;
- pMask->pDrawable = pBackMaskDraw;
+#define cwPsDecl(pScreen) \
+ PictureScreenPtr ps = GetPictureScreen (pScreen); \
+ cwScreenPtr pCwScreen = getCwScreen (pScreen)
+
+#define cwBackingPicture(pCwPicture, pPicture) \
+ ((pCwPicture && pCwPicture->pBackingPicture) ? \
+ pCwPicture->pBackingPicture : pPicture)
+
+#define cwPictureDecl \
+ cwPicturePtr pCwPicture = getCwPicture(pPicture); \
+ PicturePtr pBackingPicture = pCwPicture ? pCwPicture->pBackingPicture : 0
+
+#define cwSrcPictureDecl \
+ int src_picture_x_off, src_picture_y_off; \
+ PicturePtr pBackingSrcPicture = cwGetBackingPicture(pSrcPicture, \
+ &src_picture_x_off,\
+ &src_picture_y_off)
+
+#define cwDstPictureDecl \
+ int dst_picture_x_off, dst_picture_y_off; \
+ PicturePtr pBackingDstPicture = cwGetBackingPicture(pDstPicture, \
+ &dst_picture_x_off,\
+ &dst_picture_y_off)
+
+#define cwMskPictureDecl \
+ int msk_picture_x_off = 0, msk_picture_y_off = 0; \
+ PicturePtr pBackingMskPicture = (!pMskPicture ? 0 : \
+ cwGetBackingPicture(pMskPicture, \
+ &msk_picture_x_off,\
+ &msk_picture_y_off))
+
+#define cwPsUnwrap(elt) { \
+ ps->elt = pCwScreen->elt; \
+}
+
+#define cwPsWrap(elt,func) { \
+ pCwScreen->elt = ps->elt; \
+ ps->elt = func; \
+}
+
+static VisualPtr
+cwFindVisualById (ScreenPtr pScreen, VisualID visual)
+{
+ int i;
+ VisualPtr pVisual;
+ for (i = 0, pVisual = pScreen->visuals;
+ i < pScreen->numVisuals;
+ i++, pVisual++)
+ {
+ if (pVisual->vid == visual)
+ return pVisual;
}
+ return 0;
+}
+
+static PicturePtr
+cwCreateBackingPicture (PicturePtr pPicture)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
+ PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWindow);
+ VisualPtr pVisual = cwFindVisualById (pScreen, wVisual (pWindow));
+ PictFormatPtr pFormat = PictureMatchVisual (pScreen, pWindow->drawable.depth,
+ pVisual);
+ int error;
+ PicturePtr pBackingPicture = CreatePicture (0, &pPixmap->drawable, pFormat,
+ 0, 0, serverClient, &error);
+ cwPicturePtr pCwPicture = getCwPicture (pPicture);
+
+ return pCwPicture->pBackingPicture = pBackingPicture;
+}
+
+static void
+cwDestroyBackingPicture (PicturePtr pPicture)
+{
+ cwPictureDecl;
- ps->Composite = pScreenPriv->Composite;
- (*ps->Composite)(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
- xDst, yDst, width, height);
- ps->Composite = cwComposite;
-
- pSrc->pDrawable = pSrcDraw;
- pDst->pDrawable = pDstDraw;
- if (pMask)
- pMask->pDrawable = pMaskDraw;
-}
-void
-cwGlyphs(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlist,
- GlyphListPtr list,
- GlyphPtr *glyphs)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
- cwScreenPtr pScreenPriv =
- (cwScreenPtr)pScreen->devPrivates[cwScreenIndex].ptr;
- DrawablePtr pSrcDraw, pDstDraw;
- DrawablePtr pBackSrcDraw, pBackDstDraw;
- int src_off_x, src_off_y, dst_off_x, dst_off_y;
- GlyphListPtr oldList;
-
- pDstDraw = pDst->pDrawable;
- pBackDstDraw = cwGetBackingDrawable(pDstDraw, &dst_off_x, &dst_off_y);
- if (dst_off_x != 0 || dst_off_y != 0) {
- int i;
-
- oldList = list;
- list = ALLOCATE_LOCAL(nlist * sizeof(GlyphListRec));
- if (list == NULL)
- return;
- memcpy(list, oldList, nlist * sizeof(GlyphListRec));
- for (i = 0; i < nlist; i++) {
- list[i].xOff += dst_off_x;
- list[i].yOff += dst_off_y;
+ if (pBackingPicture)
+ {
+ FreePicture (pBackingPicture, 0);
+ pCwPicture->pBackingPicture = 0;
+ }
+}
+
+static PicturePtr
+cwGetBackingPicture (PicturePtr pPicture, int *x_off, int *y_off)
+{
+ cwPictureDecl;
+
+ if (pBackingPicture)
+ {
+ DrawablePtr pDrawable = pPicture->pDrawable;
+ ScreenPtr pScreen = pDrawable->pScreen;
+ WindowPtr pWin = (WindowPtr) pDrawable;
+ PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+
+ *x_off = -pPixmap->screen_x;
+ *y_off = -pPixmap->screen_y;
+
+ return pBackingPicture;
+ }
+ else
+ {
+ *x_off = *y_off = 0;
+ return pPicture;
+ }
+}
+
+static int
+cwCreatePicture (PicturePtr pPicture)
+{
+ int ret;
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+
+ cwPsUnwrap (CreatePicture);
+ setCwPicture(pPicture, 0);
+ ret = (*ps->CreatePicture) (pPicture);
+ cwPsWrap (CreatePicture, cwCreatePicture);
+ return ret;
+}
+
+static void
+cwDestroyPicture (PicturePtr pPicture)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+
+ cwPsUnwrap(DestroyPicture);
+ cwDestroyBackingPicture (pPicture);
+ (*ps->DestroyPicture) (pPicture);
+ cwPsWrap(DestroyPicture, cwDestroyPicture);
+}
+
+static void
+cwChangePicture (PicturePtr pPicture,
+ Mask mask)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwPictureDecl;
+
+ cwPsUnwrap(ChangePicture);
+ if (pBackingPicture)
+ {
+ (*ps->ChangePicture) (pBackingPicture, mask);
+ }
+ else
+ {
+ (*ps->ChangePicture) (pPicture, mask);
+ }
+ cwPsWrap(ChangePicture, cwChangePicture);
+}
+
+static void
+cwValidatePicture (PicturePtr pPicture,
+ Mask mask)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwPictureDecl;
+
+ cwPsUnwrap(ValidatePicture);
+ (*ps->ValidatePicture) (pPicture, mask);
+ if (!cwDrawableIsRedirWindow (pPicture->pDrawable))
+ {
+ if (pBackingPicture)
+ cwDestroyBackingPicture (pPicture);
+ }
+ else
+ {
+ DrawablePtr pDrawable = pPicture->pDrawable;
+ WindowPtr pWin = (WindowPtr) (pDrawable);
+ DrawablePtr pBackingDrawable;
+ int x_off, y_off;
+
+ if (pBackingPicture && pBackingPicture->pDrawable !=
+ &(*pScreen->GetWindowPixmap) ((WindowPtr) pPicture->pDrawable)->drawable)
+ {
+ cwDestroyBackingPicture (pPicture);
+ pBackingPicture = 0;
+ }
+
+ if (!pBackingPicture)
+ {
+ pBackingPicture = cwCreateBackingPicture (pPicture);
+ if (!pBackingPicture)
+ {
+ cwPsWrap(ValidatePicture, cwValidatePicture);
+ return;
+ }
+ }
+
+ pBackingDrawable = cwGetBackingDrawable (&pWin->drawable, &x_off, &y_off);
+
+ /* Check to see if a new composite clip must be generated */
+
+ if (pDrawable->serialNumber != pCwPicture->serialNumber ||
+ (mask & (CPClipXOrigin|CPClipYOrigin|CPClipMask|CPSubwindowMode)))
+ {
+ RegionPtr pCompositeClip;
+
+ pCompositeClip = REGION_CREATE(pScreen, NULL, 1);
+ /* note - CT_PIXMAP "cannot" happen because no DDX supports it*/
+ REGION_COPY (pScreen, pCompositeClip, pPicture->pCompositeClip);
+ SetPictureClipRegion (pBackingPicture, -x_off, -y_off,
+ pCompositeClip);
+ pCwPicture->serialNumber = pDrawable->serialNumber;
}
+ mask |= pCwPicture->stateChanges;
+ (*ps->ValidatePicture) (pBackingPicture, mask);
+ pCwPicture->stateChanges = 0;
+ pBackingPicture->serialNumber = pBackingDrawable->serialNumber;
+ }
+ cwPsWrap(ValidatePicture, cwValidatePicture);
+}
+
+static void
+cwComposite (CARD8 op,
+ PicturePtr pSrcPicture,
+ PicturePtr pMskPicture,
+ PicturePtr pDstPicture,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMsk,
+ INT16 yMsk,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwSrcPictureDecl;
+ cwMskPictureDecl;
+ cwDstPictureDecl;
+
+ cwPsUnwrap(Composite);
+ (*ps->Composite) (op, pBackingSrcPicture, pBackingMskPicture, pBackingDstPicture,
+ xSrc + src_picture_x_off, ySrc + src_picture_y_off,
+ xMsk + msk_picture_x_off, yMsk + msk_picture_y_off,
+ xDst + dst_picture_x_off, yDst + dst_picture_y_off,
+ width, height);
+ cwPsWrap(Composite, cwComposite);
+}
+
+static void
+cwGlyphs (CARD8 op,
+ PicturePtr pSrcPicture,
+ PicturePtr pDstPicture,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlists,
+ GlyphListPtr lists,
+ GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwSrcPictureDecl;
+ cwDstPictureDecl;
+
+ cwPsUnwrap(Glyphs);
+ if (nlists)
+ {
+ lists->xOff += dst_picture_x_off;
+ lists->yOff += dst_picture_y_off;
+ }
+ (*ps->Glyphs) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
+ xSrc + src_picture_x_off, ySrc + src_picture_y_off,
+ nlists, lists, glyphs);
+ if (nlists)
+ {
+ lists->xOff -= dst_picture_x_off;
+ lists->yOff -= dst_picture_y_off;
+ }
+ cwPsWrap(Glyphs, cwGlyphs);
+}
+
+static void
+cwCompositeRects (CARD8 op,
+ PicturePtr pDstPicture,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects)
+{
+ ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwDstPictureDecl;
+ int i;
+
+ cwPsUnwrap(CompositeRects);
+ for (i = 0; i < nRect; i++)
+ {
+ rects[i].x += dst_picture_x_off;
+ rects[i].y += dst_picture_y_off;
}
- pDst->pDrawable = pBackDstDraw;
-
- pSrcDraw = pSrc->pDrawable;
- pBackSrcDraw = cwGetBackingDrawable(pSrcDraw, &src_off_x, &src_off_y);
- xSrc += src_off_x;
- ySrc += src_off_y;
- pSrc->pDrawable = pBackSrcDraw;
-
- ps->Glyphs = pScreenPriv->Glyphs;
- (*ps->Glyphs)(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
- ps->Glyphs = cwGlyphs;
-
- pSrc->pDrawable = pSrcDraw;
- pDst->pDrawable = pDstDraw;
- if (dst_off_x != 0 || dst_off_y != 0)
- DEALLOCATE_LOCAL(list);
+ (*ps->CompositeRects) (op, pBackingDstPicture, color, nRect, rects);
+ for (i = 0; i < nRect; i++)
+ {
+ rects[i].x -= dst_picture_x_off;
+ rects[i].y -= dst_picture_y_off;
+ }
+ cwPsWrap(CompositeRects, cwCompositeRects);
+}
+
+static void
+cwTrapezoids (CARD8 op,
+ PicturePtr pSrcPicture,
+ PicturePtr pDstPicture,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps)
+{
+ ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwSrcPictureDecl;
+ cwDstPictureDecl;
+ int i;
+
+ cwPsUnwrap(Trapezoids);
+ if (dst_picture_x_off | dst_picture_y_off)
+ for (i = 0; i < ntrap; i++)
+ {
+ traps[i].top += dst_picture_y_off << 16;
+ traps[i].bottom += dst_picture_y_off << 16;
+ traps[i].left.p1.x += dst_picture_x_off << 16;
+ traps[i].left.p1.y += dst_picture_y_off << 16;
+ traps[i].left.p2.x += dst_picture_x_off << 16;
+ traps[i].left.p2.y += dst_picture_y_off << 16;
+ traps[i].right.p1.x += dst_picture_x_off << 16;
+ traps[i].right.p1.y += dst_picture_y_off << 16;
+ traps[i].right.p2.x += dst_picture_x_off << 16;
+ traps[i].right.p2.y += dst_picture_y_off << 16;
+ }
+ (*ps->Trapezoids) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
+ xSrc + src_picture_x_off, ySrc + src_picture_y_off,
+ ntrap, traps);
+ if (dst_picture_x_off | dst_picture_y_off)
+ for (i = 0; i < ntrap; i++)
+ {
+ traps[i].top -= dst_picture_y_off << 16;
+ traps[i].bottom -= dst_picture_y_off << 16;
+ traps[i].left.p1.x -= dst_picture_x_off << 16;
+ traps[i].left.p1.y -= dst_picture_y_off << 16;
+ traps[i].left.p2.x -= dst_picture_x_off << 16;
+ traps[i].left.p2.y -= dst_picture_y_off << 16;
+ traps[i].right.p1.x -= dst_picture_x_off << 16;
+ traps[i].right.p1.y -= dst_picture_y_off << 16;
+ traps[i].right.p2.x -= dst_picture_x_off << 16;
+ traps[i].right.p2.y -= dst_picture_y_off << 16;
+ }
+ cwPsWrap(Trapezoids, cwTrapezoids);
+}
+
+static void
+cwTriangles (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntri,
+ xTriangle *tris)
+{
+ /* FIXME */
+}
+
+static void
+cwTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points)
+{
+ /* FIXME */
+}
+
+static void
+cwTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points)
+{
+ /* FIXME */
+}
+
+Bool
+cwInitializeRender (ScreenPtr pScreen)
+{
+ cwPsDecl (pScreen);
+
+ if (!AllocatePicturePrivate (pScreen, cwPictureIndex, 0))
+ return FALSE;
+ cwPsWrap(CreatePicture, cwCreatePicture);
+ cwPsWrap(DestroyPicture, cwDestroyPicture);
+ cwPsWrap(ChangePicture, cwChangePicture);
+ cwPsWrap(ValidatePicture, cwValidatePicture);
+ cwPsWrap(Composite, cwComposite);
+ cwPsWrap(Glyphs, cwGlyphs);
+ cwPsWrap(CompositeRects, cwCompositeRects);
+ cwPsWrap(Trapezoids, cwTrapezoids);
+ cwPsWrap(Triangles, cwTriangles);
+ cwPsWrap(TriStrip, cwTriStrip);
+ cwPsWrap(TriFan, cwTriFan);
+ return TRUE;
}
#endif /* RENDER */