xenocara/xserver/hw/xfree86/xaa/xaaOverlay.c
2006-11-26 18:13:41 +00:00

309 lines
8.2 KiB
C

#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include "misc.h"
#include "xf86.h"
#include "xf86_OSproc.h"
#include <X11/X.h>
#include "scrnintstr.h"
#include "windowstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"
#include "xaawrap.h"
#include "gcstruct.h"
#include "pixmapstr.h"
#include "mioverlay.h"
#ifdef PANORAMIX
#include "panoramiX.h"
#include "panoramiXsrv.h"
#endif
static void
XAACopyWindow8_32(
WindowPtr pWin,
DDXPointRec ptOldOrg,
RegionPtr prgnSrc
){
DDXPointPtr pptSrc, ppt;
RegionRec rgnDst;
BoxPtr pbox;
int dx, dy, nbox;
WindowPtr pwinRoot;
ScreenPtr pScreen = pWin->drawable.pScreen;
XAAInfoRecPtr infoRec =
GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
Bool doUnderlay = miOverlayCopyUnderlay(pScreen);
RegionPtr borderClip = &pWin->borderClip;
Bool freeReg = FALSE;
if (!infoRec->pScrn->vtSema || !infoRec->ScreenToScreenBitBlt ||
(infoRec->ScreenToScreenBitBltFlags & NO_PLANEMASK))
{
XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
if(infoRec->pScrn->vtSema && infoRec->NeedToSync) {
(*infoRec->Sync)(infoRec->pScrn);
infoRec->NeedToSync = FALSE;
}
(*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAACopyWindow8_32);
return;
}
pwinRoot = WindowTable[pScreen->myNum];
if(doUnderlay)
freeReg = miOverlayCollectUnderlayRegions(pWin, &borderClip);
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, borderClip, prgnSrc);
pbox = REGION_RECTS(&rgnDst);
nbox = REGION_NUM_RECTS(&rgnDst);
if(!nbox ||
!(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
REGION_UNINIT(pScreen, &rgnDst);
return;
}
ppt = pptSrc;
while(nbox--) {
ppt->x = pbox->x1 + dx;
ppt->y = pbox->y1 + dy;
ppt++; pbox++;
}
infoRec->ScratchGC.planemask = doUnderlay ? 0x00ffffff : 0xff000000;
infoRec->ScratchGC.alu = GXcopy;
XAADoBitBlt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
&(infoRec->ScratchGC), &rgnDst, pptSrc);
DEALLOCATE_LOCAL(pptSrc);
REGION_UNINIT(pScreen, &rgnDst);
if(freeReg)
REGION_DESTROY(pScreen, borderClip);
}
static void
XAAPaintWindow8_32(
WindowPtr pWin,
RegionPtr prgn,
int what
){
ScreenPtr pScreen = pWin->drawable.pScreen;
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
int nBox = REGION_NUM_RECTS(prgn);
BoxPtr pBox = REGION_RECTS(prgn);
PixmapPtr pPix = NULL;
int depth = pWin->drawable.depth;
int fg = 0, pm;
if(!infoRec->pScrn->vtSema) goto BAILOUT;
switch (what) {
case PW_BACKGROUND:
switch(pWin->backgroundState) {
case None: return;
case ParentRelative:
do { pWin = pWin->parent; }
while(pWin->backgroundState == ParentRelative);
(*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, what);
return;
case BackgroundPixel:
fg = pWin->background.pixel;
break;
case BackgroundPixmap:
pPix = pWin->background.pixmap;
break;
}
break;
case PW_BORDER:
if (pWin->borderIsPixel)
fg = pWin->border.pixel;
else /* pixmap */
pPix = pWin->border.pixmap;
break;
default: return;
}
if(depth == 8) {
pm = 0xff000000;
fg <<= 24;
} else
pm = 0x00ffffff;
if(!pPix) {
if(infoRec->FillSolidRects &&
!(infoRec->FillSolidRectsFlags & NO_PLANEMASK) &&
(!(infoRec->FillSolidRectsFlags & RGB_EQUAL) ||
(depth == 8) || CHECK_RGB_EQUAL(fg)))
{
(*infoRec->FillSolidRects)(infoRec->pScrn, fg, GXcopy,
pm, nBox, pBox);
return;
}
} else { /* pixmap */
XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
WindowPtr pBgWin = pWin;
int xorg, yorg;
if (what == PW_BORDER) {
for (pBgWin = pWin;
pBgWin->backgroundState == ParentRelative;
pBgWin = pBgWin->parent);
}
xorg = pBgWin->drawable.x;
yorg = pBgWin->drawable.y;
#ifdef PANORAMIX
if(!noPanoramiXExtension) {
int index = pScreen->myNum;
if(WindowTable[index] == pBgWin) {
xorg -= panoramiXdataPtr[index].x;
yorg -= panoramiXdataPtr[index].y;
}
}
#endif
if(IS_OFFSCREEN_PIXMAP(pPix) && infoRec->FillCacheBltRects) {
XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec);
pCache->x = pPriv->offscreenArea->box.x1;
pCache->y = pPriv->offscreenArea->box.y1;
pCache->w = pCache->orig_w =
pPriv->offscreenArea->box.x2 - pCache->x;
pCache->h = pCache->orig_h =
pPriv->offscreenArea->box.y2 - pCache->y;
pCache->trans_color = -1;
(*infoRec->FillCacheBltRects)(infoRec->pScrn, GXcopy, pm,
nBox, pBox, xorg, yorg, pCache);
return;
}
if(pPriv->flags & DIRTY) {
pPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
}
if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
(infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
XAACheckTileReducibility(pPix, infoRec->CanDoMono8x8);
}
if(pPriv->flags & REDUCIBLE_TO_8x8) {
if((pPriv->flags & REDUCIBLE_TO_2_COLOR) &&
infoRec->CanDoMono8x8 && infoRec->FillMono8x8PatternRects &&
!(infoRec->FillMono8x8PatternRectsFlags & NO_PLANEMASK) &&
!(infoRec->FillMono8x8PatternRectsFlags & TRANSPARENCY_ONLY) &&
(!(infoRec->FillMono8x8PatternRectsFlags & RGB_EQUAL) ||
(CHECK_RGB_EQUAL(pPriv->fg) && CHECK_RGB_EQUAL(pPriv->bg))))
{
(*infoRec->FillMono8x8PatternRects)(infoRec->pScrn,
pPriv->fg, pPriv->bg, GXcopy, pm, nBox, pBox,
pPriv->pattern0, pPriv->pattern1, xorg, yorg);
return;
}
if(infoRec->CanDoColor8x8 && infoRec->FillColor8x8PatternRects &&
!(infoRec->FillColor8x8PatternRectsFlags & NO_PLANEMASK))
{
XAACacheInfoPtr pCache = (*infoRec->CacheColor8x8Pattern)(
infoRec->pScrn, pPix, -1, -1);
(*infoRec->FillColor8x8PatternRects) (infoRec->pScrn,
GXcopy, pm, nBox, pBox, xorg, yorg, pCache);
return;
}
}
if(infoRec->UsingPixmapCache && infoRec->FillCacheBltRects &&
!(infoRec->FillCacheBltRectsFlags & NO_PLANEMASK) &&
(pPix->drawable.height <= infoRec->MaxCacheableTileHeight) &&
(pPix->drawable.width <= infoRec->MaxCacheableTileWidth))
{
XAACacheInfoPtr pCache =
(*infoRec->CacheTile)(infoRec->pScrn, pPix);
(*infoRec->FillCacheBltRects)(infoRec->pScrn, GXcopy, pm,
nBox, pBox, xorg, yorg, pCache);
return;
}
if(infoRec->FillImageWriteRects &&
!(infoRec->FillImageWriteRectsFlags & NO_PLANEMASK))
{
(*infoRec->FillImageWriteRects) (infoRec->pScrn, GXcopy,
pm, nBox, pBox, xorg, yorg, pPix);
return;
}
}
if(infoRec->NeedToSync) {
(*infoRec->Sync)(infoRec->pScrn);
infoRec->NeedToSync = FALSE;
}
BAILOUT:
if(what == PW_BACKGROUND) {
XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBackground);
(*pScreen->PaintWindowBackground) (pWin, prgn, what);
XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBackground, XAAPaintWindow8_32);
} else {
XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBorder);
(*pScreen->PaintWindowBorder) (pWin, prgn, what);
XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBorder, XAAPaintWindow8_32);
}
}
static void
XAASetColorKey8_32(
ScreenPtr pScreen,
int nbox,
BoxPtr pbox
){
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
ScrnInfoPtr pScrn = infoRec->pScrn;
/* I'm counting on writes being clipped away while switched away.
If this isn't going to be true then I need to be wrapping instead. */
if(!infoRec->pScrn->vtSema) return;
(*infoRec->FillSolidRects)(pScrn, pScrn->colorKey << 24, GXcopy,
0xff000000, nbox, pbox);
SET_SYNC_FLAG(infoRec);
}
void
XAASetupOverlay8_32Planar(ScreenPtr pScreen)
{
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
int i;
pScreen->PaintWindowBackground = XAAPaintWindow8_32;
pScreen->PaintWindowBorder = XAAPaintWindow8_32;
pScreen->CopyWindow = XAACopyWindow8_32;
if(!(infoRec->FillSolidRectsFlags & NO_PLANEMASK))
miOverlaySetTransFunction(pScreen, XAASetColorKey8_32);
infoRec->FullPlanemask = ~0;
for(i = 0; i < 32; i++) /* haven't thought about this much */
infoRec->FullPlanemasks[i] = ~0;
}