diff options
Diffstat (limited to 'hw/xfree86/xf8_32wid/cfbwindow.c')
-rw-r--r-- | hw/xfree86/xf8_32wid/cfbwindow.c | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/hw/xfree86/xf8_32wid/cfbwindow.c b/hw/xfree86/xf8_32wid/cfbwindow.c new file mode 100644 index 000000000..74db57649 --- /dev/null +++ b/hw/xfree86/xf8_32wid/cfbwindow.c @@ -0,0 +1,284 @@ +/* + Copyright (C) 1999. The XFree86 Project Inc. + + Written by David S. Miller (davem@redhat.com) + + Based largely upon the xf8_16bpp module which is + Mark Vojkovich's work. +*/ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32wid/cfbwindow.c,v 1.2 2001/10/28 03:34:09 tsi Exp $ */ + +#include "X.h" +#include "scrnintstr.h" +#include "windowstr.h" +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb32.h" +#include "cfb8_32wid.h" +#include "mistruct.h" +#include "regionstr.h" +#include "cfbmskbits.h" +#include "xf86.h" + +/* We don't bother with cfb's fastBackground/Border so we don't + need to use the Window privates */ + +Bool +cfb8_32WidCreateWindow(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + cfb8_32WidScreenPtr pScreenPriv = + CFB8_32WID_GET_SCREEN_PRIVATE(pScreen); + cfbPrivWin *pPrivWin = cfbGetWindowPrivate(pWin); + + pPrivWin->fastBackground = FALSE; + pPrivWin->fastBorder = FALSE; + + if (!pScreenPriv->WIDOps->WidAlloc(pWin)) + return FALSE; + + return TRUE; +} + + +Bool +cfb8_32WidDestroyWindow(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + cfb8_32WidScreenPtr pScreenPriv = + CFB8_32WID_GET_SCREEN_PRIVATE(pScreen); + + pScreenPriv->WIDOps->WidFree(pWin); + return TRUE; +} + +Bool +cfb8_32WidPositionWindow(WindowPtr pWin, int x, int y) +{ + return TRUE; +} + +static void +SegregateChildrenBpp(WindowPtr pWin, RegionPtr pReg, int subtract, int bpp, int other_bpp) +{ + WindowPtr pChild; + + for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { + if (pChild->drawable.bitsPerPixel == bpp) { + if (subtract) { + REGION_SUBTRACT(pWin->drawable.pScreen, pReg, + pReg, &pChild->borderClip); + } else { + REGION_UNION(pWin->drawable.pScreen, pReg, + pReg, &pChild->borderClip); + } + if (pChild->firstChild) + SegregateChildrenBpp(pChild, pReg, + !subtract, other_bpp, bpp); + } else { + if (pChild->firstChild) + SegregateChildrenBpp(pChild, pReg, + subtract, bpp, other_bpp); + } + } +} + +void +cfb8_32WidCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + cfb8_32WidScreenPtr pScreenPriv = + CFB8_32WID_GET_SCREEN_PRIVATE(pScreen); + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + PixmapPtr pPixChildren; + DDXPointPtr ppt, pptSrc; + RegionRec rgnDst, rgnOther, rgnPixmap; + BoxPtr pbox; + int i, nbox, dx, dy, other_bpp; + + REGION_INIT(pScreen, &rgnDst, NullBox, 0); + + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy); + REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc); + + if ((nbox = REGION_NUM_RECTS(&rgnDst)) == 0) { + /* Nothing to render. */ + REGION_UNINIT(pScreen, &rgnDst); + return; + } + + /* First, copy the WID plane for the whole area. */ + pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)); + if(pptSrc) { + pbox = REGION_RECTS(&rgnDst); + for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) { + ppt->x = pbox->x1 + dx; + ppt->y = pbox->y1 + dy; + } + + pScreenPriv->WIDOps->WidCopyArea((DrawablePtr)pScreenPriv->pixWid, + &rgnDst, pptSrc); + + DEALLOCATE_LOCAL(pptSrc); + } + + /* Next, we copy children which have a different + * bpp than pWin into a temporary pixmap. We will + * toss this pixmap back onto the framebuffer before + * we return. + */ + if (pWin->drawable.bitsPerPixel == 8) + other_bpp = pScrn->bitsPerPixel; + else + other_bpp = 8; + + REGION_INIT(pScreen, &rgnOther, NullBox, 0); + SegregateChildrenBpp(pWin, &rgnOther, 0, + other_bpp, pWin->drawable.bitsPerPixel); + pPixChildren = NULL; + if (REGION_NOTEMPTY(pScreen, &rgnOther)) { + REGION_INTERSECT(pScreen, &rgnOther, &rgnOther, prgnSrc); + nbox = REGION_NUM_RECTS(&rgnOther); + if (nbox) { + int width = rgnOther.extents.x2 - rgnOther.extents.x1; + int height = rgnOther.extents.y2 - rgnOther.extents.y1; + int depth = (other_bpp == 8) ? 8 : pScrn->depth; + + if (other_bpp == 8) + pPixChildren = cfbCreatePixmap(pScreen, width, height, depth); + else + pPixChildren = cfb32CreatePixmap(pScreen, width, height, depth); + } + if (nbox && + pPixChildren && + (pptSrc = (DDXPointPtr) ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) { + pbox = REGION_RECTS(&rgnOther); + for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) { + ppt->x = pbox->x1 + dx; + ppt->y = pbox->y1 + dy; + } + + REGION_INIT(pScreen, &rgnPixmap, NullBox, 0); + REGION_COPY(pScreen, &rgnPixmap, &rgnOther); + REGION_TRANSLATE(pScreen, &rgnPixmap, -(rgnOther.extents.x1), -(rgnOther.extents.y1)); + + if (other_bpp == 8) + cfbDoBitbltCopy((DrawablePtr)pScreenPriv->pix8, + (DrawablePtr)pPixChildren, + GXcopy, &rgnPixmap, pptSrc, ~0L); + else + cfb32DoBitbltCopy((DrawablePtr)pScreenPriv->pix32, + (DrawablePtr)pPixChildren, + GXcopy, &rgnPixmap, pptSrc, ~0L); + + REGION_UNINIT(pScreen, &rgnPixmap); + + DEALLOCATE_LOCAL(pptSrc); + } + + REGION_SUBTRACT(pScreen, &rgnDst, &rgnDst, &rgnOther); + } + + /* Now copy the parent along with all child windows using the same depth. */ + nbox = REGION_NUM_RECTS(&rgnDst); + if(nbox && + (pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) { + pbox = REGION_RECTS(&rgnDst); + for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) { + ppt->x = pbox->x1 + dx; + ppt->y = pbox->y1 + dy; + } + + if (pWin->drawable.bitsPerPixel == 8) + cfbDoBitbltCopy((DrawablePtr)pScreenPriv->pix8, + (DrawablePtr)pScreenPriv->pix8, + GXcopy, &rgnDst, pptSrc, ~0L); + else + cfb32DoBitbltCopy((DrawablePtr)pScreenPriv->pix32, + (DrawablePtr)pScreenPriv->pix32, + GXcopy, &rgnDst, pptSrc, ~0L); + + DEALLOCATE_LOCAL(pptSrc); + } + + REGION_UNINIT(pScreen, &rgnDst); + + if (pPixChildren) { + nbox = REGION_NUM_RECTS(&rgnOther); + pptSrc = (DDXPointPtr) ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)); + if (pptSrc) { + pbox = REGION_RECTS(&rgnOther); + for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) { + ppt->x = pbox->x1 - rgnOther.extents.x1; + ppt->y = pbox->y1 - rgnOther.extents.y1; + } + + if (other_bpp == 8) + cfbDoBitbltCopy((DrawablePtr)pPixChildren, + (DrawablePtr)pScreenPriv->pix8, + GXcopy, &rgnOther, pptSrc, ~0L); + else + cfb32DoBitbltCopy((DrawablePtr)pPixChildren, + (DrawablePtr)pScreenPriv->pix32, + GXcopy, &rgnOther, pptSrc, ~0L); + + DEALLOCATE_LOCAL(pptSrc); + } + + if (other_bpp == 8) + cfbDestroyPixmap(pPixChildren); + else + cfb32DestroyPixmap(pPixChildren); + } + REGION_UNINIT(pScreen, &rgnOther); +} + +Bool +cfb8_32WidChangeWindowAttributes(WindowPtr pWin, unsigned long mask) +{ + return TRUE; +} + +void +cfb8_32WidWindowExposures(WindowPtr pWin, RegionPtr pReg, RegionPtr pOtherReg) +{ + /* Fill in the WID channel before rendering of + * the exposed window area. + */ + if (REGION_NUM_RECTS(pReg)) { + ScreenPtr pScreen = pWin->drawable.pScreen; + cfb8_32WidScreenPtr pScreenPriv = + CFB8_32WID_GET_SCREEN_PRIVATE(pScreen); + + pScreenPriv->WIDOps->WidFillBox((DrawablePtr)pScreenPriv->pixWid, + (DrawablePtr)pWin, + REGION_NUM_RECTS(pReg), REGION_RECTS(pReg)); + } + + miWindowExposures(pWin, pReg, pOtherReg); +} + +void +cfb8_32WidPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what) +{ + if (what == PW_BORDER) { + ScreenPtr pScreen = pWin->drawable.pScreen; + cfb8_32WidScreenPtr pScreenPriv = + CFB8_32WID_GET_SCREEN_PRIVATE(pScreen); + + pScreenPriv->WIDOps->WidFillBox((DrawablePtr)pScreenPriv->pixWid, + (DrawablePtr)pWin, + REGION_NUM_RECTS(pRegion), + REGION_RECTS(pRegion)); + } + + if (pWin->drawable.bitsPerPixel == 8) + cfbPaintWindow(pWin, pRegion, what); + else + cfb32PaintWindow(pWin, pRegion, what); +} + |