285 lines
7.3 KiB
C
285 lines
7.3 KiB
C
/*
|
|
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.2tsi 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_NULL(pScreen, &rgnDst);
|
|
|
|
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_NULL(pScreen, &rgnOther);
|
|
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_NULL(pScreen, &rgnPixmap);
|
|
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);
|
|
}
|
|
|