#define NEED_REPLIES
#define NEED_EVENTS
#include "X.h"
#include "Xproto.h"
#include "misc.h"
#include "os.h"
#include "windowstr.h"
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "extnsionst.h"
#include "dixstruct.h"
#include "resource.h"
#include "opaque.h"
#include "dbestruct.h"
#include "regionstr.h"
#include "gcstruct.h"
#include "inputstr.h"
#define PSZ 8
#include "cfb.h"
#undef PSZ
#include "cfb32.h"
#include "xf86_ansic.h"
#include "xf86.h"
#include "ffb.h"
#include "ffb_fifo.h"
#include "ffb_rcache.h"
static int FFBDbePrivPrivGeneration = 0;
static int FFBDbeWindowPrivPrivIndex = -1;
static RESTYPE dbeDrawableResType;
static RESTYPE dbeWindowPrivResType;
static int dbeScreenPrivIndex = -1;
static int dbeWindowPrivIndex = -1;
#define FFB_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv) \
(((FFBDbeWindowPrivPrivIndex < 0) || (!pDbeWindowPriv)) ? \
NULL : \
((FFBDbeWindowPrivPrivPtr) \
((pDbeWindowPriv)->devPrivates[FFBDbeWindowPrivPrivIndex].ptr)))
#define FFB_DBE_WINDOW_PRIV_PRIV_FROM_WINDOW(pWin) \
FFB_DBE_WINDOW_PRIV_PRIV(DBE_WINDOW_PRIV(pWin))
typedef struct _FFBDbeWindowPrivPrivRec {
int HwAccelerated;
int HwCurrentBuf;
PixmapPtr pBackBuffer;
PixmapPtr pFrontBuffer;
DbeWindowPrivPtr pDbeWindowPriv;
} FFBDbeWindowPrivPrivRec, *FFBDbeWindowPrivPrivPtr;
static Bool
FFBDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo *pScrVisInfo)
{
XdbeVisualInfo *visInfo;
DepthPtr pDepth;
int i, j, k, count;
for (i = 0, count = 0; i < pScreen->numDepths; i++)
count += pScreen->allowedDepths[i].numVids;
if (!(visInfo = (XdbeVisualInfo *)xalloc(count * sizeof(XdbeVisualInfo))))
return FALSE;
for (i = 0, k = 0; i < pScreen->numDepths; i++) {
pDepth = &pScreen->allowedDepths[i];
for (j = 0; j < pDepth->numVids; j++) {
visInfo[k].visual = pDepth->vids[j];
visInfo[k].depth = pDepth->depth;
visInfo[k].perflevel = 0;
k++;
}
}
pScrVisInfo->count = count;
pScrVisInfo->visinfo = visInfo;
return TRUE;
}
static void
FFBDbeUpdateWidPlane(WindowPtr pWin, GCPtr pGC)
{
FFBPtr pFfb = GET_FFB_FROM_SCREEN(pWin->drawable.pScreen);
CreatorPrivWinPtr pFfbPrivWin = CreatorGetWindowPrivate(pWin);
RegionPtr prgnClip;
BoxPtr pboxClipped, pboxClippedBase;
unsigned int fbc;
int numRects;
int x, y, w, h;
x = pWin->drawable.x;
y = pWin->drawable.y;
w = pWin->drawable.width;
h = pWin->drawable.height;
fbc = pFfbPrivWin->fbc_base;
fbc = (fbc & ~FFB_FBC_WB_MASK) | FFB_FBC_WB_AB;
fbc = (fbc & ~FFB_FBC_XE_MASK) | FFB_FBC_XE_ON;
fbc = (fbc & ~FFB_FBC_RGBE_MASK) | FFB_FBC_RGBE_OFF;
prgnClip = cfbGetCompositeClip(pGC);
numRects = REGION_NUM_RECTS (prgnClip);
pboxClippedBase = (BoxPtr) ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
if (!pboxClippedBase)
return;
pboxClipped = pboxClippedBase;
{
int x1, y1, x2, y2, bx2, by2;
BoxRec box;
BoxPtr pextent;
pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
x1 = pextent->x1;
y1 = pextent->y1;
x2 = pextent->x2;
y2 = pextent->y2;
if ((box.x1 = x) < x1)
box.x1 = x1;
if ((box.y1 = y) < y1)
box.y1 = y1;
bx2 = (int) x + (int) w;
if (bx2 > x2)
bx2 = x2;
box.x2 = bx2;
by2 = (int) y + (int) h;
if (by2 > y2)
by2 = y2;
box.y2 = by2;
if ((box.x1 < box.x2) && (box.y1 < box.y2)) {
int n = REGION_NUM_RECTS (prgnClip);
BoxPtr pbox = REGION_RECTS(prgnClip);
while(n--) {
pboxClipped->x1 = max(box.x1, pbox->x1);
pboxClipped->y1 = max(box.y1, pbox->y1);
pboxClipped->x2 = min(box.x2, pbox->x2);
pboxClipped->y2 = min(box.y2, pbox->y2);
pbox++;
if(pboxClipped->x1 < pboxClipped->x2 &&
pboxClipped->y1 < pboxClipped->y2)
pboxClipped++;
}
}
}
if (pboxClipped != pboxClippedBase) {
ffb_fbcPtr ffb = pFfb->regs;
int num = (pboxClipped - pboxClippedBase);
FFB_ATTR_RAW(pFfb,
FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID,
FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK,
pGC->planemask,
((FFB_ROP_EDIT_BIT | pGC->alu) | (FFB_ROP_NEW << 8)),
FFB_DRAWOP_RECTANGLE,
pGC->fgPixel,
fbc, pFfbPrivWin->wid);
pboxClipped = pboxClippedBase;
while (num--) {
int xx, yy, ww, hh;
xx = pboxClipped->x1;
yy = pboxClipped->y1;
ww = (pboxClipped->x2 - xx);
hh = (pboxClipped->y2 - yy);
FFBFifo(pFfb, 4);
FFB_WRITE64(&ffb->by, yy, xx);
FFB_WRITE64_2(&ffb->bh, hh, ww);
}
}
DEALLOCATE_LOCAL (pboxClippedBase);
}
static int
FFBDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction)
{
ScreenPtr pScreen;
FFBPtr pFfb;
DbeWindowPrivPtr pDbeWindowPriv;
FFBDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
DbeScreenPrivPtr pDbeScreenPriv;
GCPtr pGC;
xRectangle clearRect;
pScreen = pWin->drawable.pScreen;
pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
pFfb = GET_FFB_FROM_SCREEN(pScreen);
pDbeWindowPrivPriv = FFB_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
if (pDbeWindowPriv->nBufferIDs == 0) {
pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
pDbeWindowPrivPriv->pDbeWindowPriv = pDbeWindowPriv;
if (!pFfb->NoAccel && pFfb->has_double_buffer) {
CreatorPrivWinPtr pFfbPrivWin;
unsigned int wid, fbc;
if (!AddResource(bufId, dbeDrawableResType,
(pointer)&pWin->drawable)) {
FreeResource(bufId, RT_NONE);
return BadAlloc;
}
pFfbPrivWin = CreatorGetWindowPrivate(pWin);
wid = FFBWidUnshare(pFfb, pFfbPrivWin->wid);
if (wid == (unsigned int)-1)
return BadAlloc;
pFfbPrivWin->wid = wid;
pDbeWindowPriv->devPrivates[FFBDbeWindowPrivPrivIndex].ptr =
(pointer)pDbeWindowPrivPriv;
pDbeWindowPrivPriv->HwAccelerated = 1;
pDbeWindowPrivPriv->HwCurrentBuf = 1;
pDbeWindowPrivPriv->pFrontBuffer = NULL;
pDbeWindowPrivPriv->pBackBuffer = NULL;
fbc = pFfbPrivWin->fbc_base;
fbc &= ~(FFB_FBC_WB_MASK | FFB_FBC_RB_MASK);
fbc |= (FFB_FBC_WB_B | FFB_FBC_RB_B);
pFfbPrivWin->fbc_base = fbc;
pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) {
ValidateGC(&pWin->drawable, pGC);
FFBDbeUpdateWidPlane(pWin, pGC);
}
clearRect.x = clearRect.y = 0;
clearRect.width = pWin->drawable.width;
clearRect.height = pWin->drawable.height;
if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) {
ValidateGC(&pWin->drawable, pGC);
(*pGC->ops->PolyFillRect)(&pWin->drawable, pGC, 1, &clearRect);
}
FreeScratchGC(pGC);
} else {
if (!(pDbeWindowPrivPriv->pFrontBuffer =
(*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width,
pDbeWindowPriv->height,
pWin->drawable.depth)))
return BadAlloc;
if (!(pDbeWindowPrivPriv->pBackBuffer =
(*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width,
pDbeWindowPriv->height,
pWin->drawable.depth))) {
(*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer);
return BadAlloc;
}
if (!AddResource(bufId, dbeDrawableResType,
(pointer)pDbeWindowPrivPriv->pBackBuffer)) {
FreeResource(bufId, RT_NONE);
return(BadAlloc);
}
pDbeWindowPriv->devPrivates[FFBDbeWindowPrivPrivIndex].ptr =
(pointer)pDbeWindowPrivPriv;
pDbeWindowPrivPriv->HwAccelerated = 0;
pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) {
ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC);
clearRect.x = clearRect.y = 0;
clearRect.width = pDbeWindowPrivPriv->pBackBuffer->drawable.width;
clearRect.height = pDbeWindowPrivPriv->pBackBuffer->drawable.height;
(*pGC->ops->PolyFillRect)(
(DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC, 1,
&clearRect);
}
FreeScratchGC(pGC);
}
} else {
pointer cookie;
if (pDbeWindowPrivPriv->HwAccelerated != 0)
cookie = (pointer)&pWin->drawable;
else
cookie = (pointer)pDbeWindowPrivPriv->pBackBuffer;
if (!AddResource(bufId, dbeDrawableResType, cookie))
return BadAlloc;
}
return Success;
}
static void
FFBDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv)
{
FFBDbeWindowPrivPrivPtr pDbeWindowPrivPriv =
FFB_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
pointer cookie;
int i;
if (pDbeWindowPrivPriv->HwAccelerated != 0)
cookie = (pointer) &pDbeWindowPriv->pWindow->drawable;
else
cookie = (pointer) pDbeWindowPrivPriv->pBackBuffer;
for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++)
ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType, cookie);
}
static int
FFBDbeSwapBuffers(ClientPtr client, int *pNumWindows, DbeSwapInfoPtr swapInfo)
{
FFBDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
DbeScreenPrivPtr pDbeScreenPriv;
PixmapPtr pTmpBuffer;
xRectangle clearRect;
WindowPtr pWin;
GCPtr pGC;
pWin = swapInfo[0].pWindow;
pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
pDbeWindowPrivPriv = FFB_DBE_WINDOW_PRIV_PRIV_FROM_WINDOW(pWin);
pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
if (pDbeWindowPrivPriv->HwAccelerated != 0) {
FFBPtr pFfb = GET_FFB_FROM_SCREEN(pWin->drawable.pScreen);
CreatorPrivWinPtr pFfbPrivWin = CreatorGetWindowPrivate(pWin);
unsigned int fbc;
int visible;
FFBWait(pFfb, pFfb->regs);
visible = 0;
if (pWin->viewable &&
pWin->visibility != VisibilityFullyObscured)
visible = 1;
FFBWidChangeBuffer(pFfb, pFfbPrivWin->wid, visible);
pDbeWindowPrivPriv->HwCurrentBuf ^= 1;
fbc = pFfbPrivWin->fbc_base;
fbc &= ~(FFB_FBC_WB_MASK | FFB_FBC_RB_MASK);
if (pDbeWindowPrivPriv->HwCurrentBuf == 0)
fbc |= FFB_FBC_WB_A | FFB_FBC_RB_A;
else
fbc |= FFB_FBC_WB_B | FFB_FBC_RB_B;
if (swapInfo[0].swapAction == XdbeCopied) {
unsigned int fbc_front_to_back;
fbc_front_to_back = fbc & ~FFB_FBC_RB_MASK;
if (pDbeWindowPrivPriv->HwCurrentBuf == 0)
fbc_front_to_back |= FFB_FBC_RB_B;
else
fbc_front_to_back |= FFB_FBC_RB_A;
pFfbPrivWin->fbc_base = fbc_front_to_back;
ValidateGC(&pWin->drawable, pGC);
(*pGC->ops->CopyArea)(&pWin->drawable,
&pWin->drawable,
pGC,
0, 0,
pWin->drawable.width,
pWin->drawable.height,
0, 0);
} else if (swapInfo[0].swapAction == XdbeBackground) {
if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) {
ValidateGC(&pWin->drawable, pGC);
clearRect.x = 0;
clearRect.y = 0;
clearRect.width = pWin->drawable.width;
clearRect.height = pWin->drawable.height;
(*pGC->ops->PolyFillRect)(&pWin->drawable, pGC,
1, &clearRect);
}
}
pFfbPrivWin->fbc_base = fbc;
} else {
if (swapInfo[0].swapAction == XdbeUntouched) {
ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer, pGC);
(*pGC->ops->CopyArea)((DrawablePtr)pWin,
(DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer,
pGC, 0, 0, pWin->drawable.width,
pWin->drawable.height, 0, 0);
}
ValidateGC((DrawablePtr)pWin, pGC);
(*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
(DrawablePtr)pWin, pGC, 0, 0,
pWin->drawable.width, pWin->drawable.height,
0, 0);
if (swapInfo[0].swapAction == XdbeBackground) {
if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) {
ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
pGC);
clearRect.x = 0;
clearRect.y = 0;
clearRect.width =
pDbeWindowPrivPriv->pBackBuffer->drawable.width;
clearRect.height =
pDbeWindowPrivPriv->pBackBuffer->drawable.height;
(*pGC->ops->PolyFillRect)(
(DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
pGC, 1, &clearRect);
}
} else if (swapInfo[0].swapAction == XdbeUntouched) {
pTmpBuffer = pDbeWindowPrivPriv->pBackBuffer;
pDbeWindowPrivPriv->pBackBuffer =
pDbeWindowPrivPriv->pFrontBuffer;
pDbeWindowPrivPriv->pFrontBuffer = pTmpBuffer;
FFBDbeAliasBuffers(pDbeWindowPrivPriv->pDbeWindowPriv);
}
}
if (*pNumWindows > 1) {
swapInfo[0].pWindow = swapInfo[*pNumWindows - 1].pWindow;
swapInfo[0].swapAction = swapInfo[*pNumWindows - 1].swapAction;
swapInfo[*pNumWindows - 1].pWindow = (WindowPtr)NULL;
swapInfo[*pNumWindows - 1].swapAction = 0;
} else {
swapInfo[0].pWindow = (WindowPtr)NULL;
swapInfo[0].swapAction = 0;
}
(*pNumWindows)--;
FreeScratchGC(pGC);
return Success;
}
static void
FFBDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv, XID bufId)
{
WindowPtr pWin = pDbeWindowPriv->pWindow;
FFBDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
if (pDbeWindowPriv->nBufferIDs != 0) {
return;
}
pDbeWindowPrivPriv = FFB_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
if (pDbeWindowPrivPriv->HwAccelerated != 0) {
FFBPtr pFfb = GET_FFB_FROM_SCREEN(pWin->drawable.pScreen);
CreatorPrivWinPtr pFfbPrivWin = CreatorGetWindowPrivate(pWin);
xRectangle clearRect;
unsigned int fbc;
GCPtr pGC;
pFfbPrivWin->wid = FFBWidReshare(pFfb, pFfbPrivWin->wid);
fbc = pFfbPrivWin->fbc_base;
fbc &= ~(FFB_FBC_WB_MASK | FFB_FBC_RB_MASK);
fbc |= FFB_FBC_WB_A | FFB_FBC_RB_A;
pFfbPrivWin->fbc_base =
(fbc & ~FFB_FBC_RGBE_MASK) | FFB_FBC_RGBE_OFF;
pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
clearRect.x = clearRect.y = 0;
clearRect.width = pWin->drawable.width;
clearRect.height = pWin->drawable.height;
ValidateGC(&pWin->drawable, pGC);
FFBDbeUpdateWidPlane(pWin, pGC);
(*pGC->ops->PolyFillRect)(&pWin->drawable, pGC, 1, &clearRect);
FreeScratchGC(pGC);
pFfbPrivWin->fbc_base = fbc;
} else {
if (pDbeWindowPrivPriv->pFrontBuffer)
(*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)(
pDbeWindowPrivPriv->pFrontBuffer);
if (pDbeWindowPrivPriv->pBackBuffer)
(*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)(
pDbeWindowPrivPriv->pBackBuffer);
}
}
static Bool
FFBDbePositionWindow(WindowPtr pWin, int x, int y)
{
ScreenPtr pScreen;
DbeScreenPrivPtr pDbeScreenPriv;
DbeWindowPrivPtr pDbeWindowPriv;
FFBDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
int width, height;
int dx, dy, dw, dh;
int sourcex, sourcey;
int destx, desty;
int savewidth, saveheight;
PixmapPtr pFrontBuffer;
PixmapPtr pBackBuffer;
Bool clear;
GCPtr pGC;
xRectangle clearRect;
Bool ret;
pScreen = pWin->drawable.pScreen;
pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
ret = (*pScreen->PositionWindow)(pWin, x, y);
pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
pScreen->PositionWindow = FFBDbePositionWindow;
if (!(pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)))
return ret;
if (pDbeWindowPriv->width == pWin->drawable.width &&
pDbeWindowPriv->height == pWin->drawable.height)
return ret;
width = pWin->drawable.width;
height = pWin->drawable.height;
dx = pWin->drawable.x - pDbeWindowPriv->x;
dy = pWin->drawable.y - pDbeWindowPriv->y;
dw = width - pDbeWindowPriv->width;
dh = height - pDbeWindowPriv->height;
GravityTranslate (0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty);
clear = ((pDbeWindowPriv->width < (unsigned short)width ) ||
(pDbeWindowPriv->height < (unsigned short)height) ||
(pWin->bitGravity == ForgetGravity));
sourcex = 0;
sourcey = 0;
savewidth = pDbeWindowPriv->width;
saveheight = pDbeWindowPriv->height;
if (destx < 0) {
savewidth += destx;
sourcex -= destx;
destx = 0;
}
if (destx + savewidth > width)
savewidth = width - destx;
if (desty < 0) {
saveheight += desty;
sourcey -= desty;
desty = 0;
}
if (desty + saveheight > height)
saveheight = height - desty;
pDbeWindowPriv->width = width;
pDbeWindowPriv->height = height;
pDbeWindowPriv->x = pWin->drawable.x;
pDbeWindowPriv->y = pWin->drawable.y;
pGC = GetScratchGC (pWin->drawable.depth, pScreen);
if (clear) {
if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) {
clearRect.x = 0;
clearRect.y = 0;
clearRect.width = width;
clearRect.height = height;
} else {
clear = FALSE;
}
}
pDbeWindowPrivPriv = FFB_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
if (pDbeWindowPrivPriv->HwAccelerated != 0) {
ValidateGC(&pWin->drawable, pGC);
FFBDbeUpdateWidPlane(pWin, pGC);
if (clear) {
CreatorPrivWinPtr pFfbPrivWin = CreatorGetWindowPrivate(pWin);
unsigned int fbc, orig_fbc;
ValidateGC(&pWin->drawable, pGC);
(*pGC->ops->PolyFillRect)(&pWin->drawable, pGC,
1, &clearRect);
orig_fbc = fbc = pFfbPrivWin->fbc_base;
fbc &= ~(FFB_FBC_WB_MASK);
if (pDbeWindowPrivPriv->HwCurrentBuf == 0)
fbc |= FFB_FBC_WB_B;
else
fbc |= FFB_FBC_WB_A;
pFfbPrivWin->fbc_base = fbc;
if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) {
ValidateGC(&pWin->drawable, pGC);
clearRect.x = 0;
clearRect.y = 0;
clearRect.width = width;
clearRect.height = height;
(*pGC->ops->PolyFillRect)(&pWin->drawable, pGC,
1, &clearRect);
}
pFfbPrivWin->fbc_base = orig_fbc;
}
FreeScratchGC(pGC);
} else {
pFrontBuffer = (*pScreen->CreatePixmap)(pScreen, width, height,
pWin->drawable.depth);
pBackBuffer = (*pScreen->CreatePixmap)(pScreen, width, height,
pWin->drawable.depth);
if (!pFrontBuffer || !pBackBuffer) {
if (pFrontBuffer)
(*pScreen->DestroyPixmap)(pFrontBuffer);
if (pBackBuffer)
(*pScreen->DestroyPixmap)(pBackBuffer);
while (pDbeWindowPriv) {
FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
}
FreeScratchGC(pGC);
return FALSE;
} else {
ValidateGC((DrawablePtr)pFrontBuffer, pGC);
if (clear) {
(*pGC->ops->PolyFillRect)((DrawablePtr)pFrontBuffer, pGC, 1,
&clearRect);
(*pGC->ops->PolyFillRect)((DrawablePtr)pBackBuffer , pGC, 1,
&clearRect);
}
if (pWin->bitGravity != ForgetGravity) {
(*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer,
(DrawablePtr)pFrontBuffer, pGC,
sourcex, sourcey,
savewidth, saveheight,
destx, desty);
(*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
(DrawablePtr)pBackBuffer, pGC,
sourcex, sourcey,
savewidth, saveheight, destx, desty);
}
(*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer);
(*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pBackBuffer);
pDbeWindowPrivPriv->pFrontBuffer = pFrontBuffer;
pDbeWindowPrivPriv->pBackBuffer = pBackBuffer;
FFBDbeAliasBuffers(pDbeWindowPriv);
FreeScratchGC(pGC);
}
}
return ret;
}
static void
FFBDbeResetProc(ScreenPtr pScreen)
{
DbeScreenPrivPtr pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
}
static Bool
FFBDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv)
{
ScrnInfoPtr pScrn;
FFBPtr pFfb;
pScrn = xf86Screens[pScreen->myNum];
pFfb = GET_FFB_FROM_SCRN(pScrn);
xf86Msg(X_INFO, "%s: Setting up double-buffer acceleration.\n",
pFfb->psdp->device);
dbeDrawableResType = pDbeScreenPriv->dbeDrawableResType;
dbeWindowPrivResType = pDbeScreenPriv->dbeWindowPrivResType;
dbeScreenPrivIndex = pDbeScreenPriv->dbeScreenPrivIndex;
dbeWindowPrivIndex = pDbeScreenPriv->dbeWindowPrivIndex;
if (FFBDbePrivPrivGeneration != serverGeneration) {
FFBDbeWindowPrivPrivIndex = (*pDbeScreenPriv->AllocWinPrivPrivIndex)();
if (!(*pDbeScreenPriv->AllocWinPrivPriv)(pScreen,
FFBDbeWindowPrivPrivIndex,
sizeof(FFBDbeWindowPrivPrivRec)))
return FALSE;
FFBDbePrivPrivGeneration = serverGeneration;
}
pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
pScreen->PositionWindow = FFBDbePositionWindow;
pDbeScreenPriv->GetVisualInfo = FFBDbeGetVisualInfo;
pDbeScreenPriv->AllocBackBufferName = FFBDbeAllocBackBufferName;
pDbeScreenPriv->SwapBuffers = FFBDbeSwapBuffers;
pDbeScreenPriv->BeginIdiom = 0;
pDbeScreenPriv->EndIdiom = 0;
pDbeScreenPriv->ResetProc = FFBDbeResetProc;
pDbeScreenPriv->WinPrivDelete = FFBDbeWinPrivDelete;
pDbeScreenPriv->ValidateBuffer = (void (*)())NoopDDA;
return TRUE;
}
extern void DbeRegisterFunction(ScreenPtr pScreen, Bool (*funct)(ScreenPtr, DbeScreenPrivPtr));
Bool
FFBDbePreInit(ScreenPtr pScreen)
{
DbeRegisterFunction(pScreen, FFBDbeInit);
return TRUE;
}