diff options
Diffstat (limited to 'miext/cw/cw_render.c')
-rw-r--r-- | miext/cw/cw_render.c | 513 |
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 */ |