#define NEED_REPLIES
#define NEED_EVENTS
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <stdio.h>
#include <X11/X.h>
#include <X11/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 "regionstr.h"
#include "gcstruct.h"
#include "inputstr.h"
#include "validate.h"
#include <sys/time.h>
#define _MULTIBUF_SERVER_
#define _MULTIBUF_BUFFER_
#include <X11/extensions/multibufst.h>
#define MAX_BUFFERS 2
#define FRONT_BUFFER 0
#define BACK_BUFFER 1
typedef WindowRec BufferRec;
typedef WindowPtr BufferPtr;
static int bufNumInfo[MAXSCREENS];
static xMbufBufferInfo *bufInfo[MAXSCREENS];
static DevUnion *bufFrameBuffer[MAXSCREENS];
static DevUnion bufselectPlane[MAXSCREENS];
static void (* bufCopyBufferBitsFunc[MAXSCREENS])();
static void (* bufDrawSelectPlaneFunc[MAXSCREENS])();
static Bool bufMultibufferInit();
void
RegisterDoubleBufferHardware(pScreen, nInfo, pInfo, frameBuffer, selectPlane,
CopyBufferBitsFunc, DrawSelectPlaneFunc)
ScreenPtr pScreen;
int nInfo;
xMbufBufferInfo *pInfo;
DevUnion *frameBuffer;
DevUnion selectPlane;
void (* CopyBufferBitsFunc)();
void (* DrawSelectPlaneFunc)();
{
bufNumInfo[pScreen->myNum] = nInfo;
bufInfo[pScreen->myNum] = pInfo;
bufFrameBuffer[pScreen->myNum] = frameBuffer;
bufselectPlane[pScreen->myNum] = selectPlane;
bufCopyBufferBitsFunc[pScreen->myNum] = CopyBufferBitsFunc;
bufDrawSelectPlaneFunc[pScreen->myNum] = DrawSelectPlaneFunc;
RegisterMultibufferInit(pScreen, bufMultibufferInit);
}
static Bool NoopDDA_True() { return TRUE; }
static Bool bufPositionWindow();
static int bufCreateImageBuffers();
static void bufDestroyImageBuffers();
static void bufDisplayImageBuffers();
static void bufClearImageBufferArea();
static void bufDestroyBuffer();
static void bufCopyBufferBits();
static void bufDrawSelectPlane();
static void bufWrapScreenFuncs();
static void bufResetProc();
static void bufPostValidateTree();
static void bufClipNotify();
static void bufWindowExposures();
static Bool bufChangeWindowAttributes();
static void bufClearToBackground();
static void bufCopyWindow();
extern WindowPtr *WindowTable;
static Bool
bufMultibufferInit(pScreen, pMBScreen)
ScreenPtr pScreen;
mbufScreenPtr pMBScreen;
{
mbufBufferPrivPtr pMBPriv;
BoxRec box;
pMBScreen->nInfo = bufNumInfo[pScreen->myNum];
pMBScreen->pInfo = bufInfo[pScreen->myNum];
pMBScreen->CreateImageBuffers = bufCreateImageBuffers;
pMBScreen->DestroyImageBuffers = bufDestroyImageBuffers;
pMBScreen->DisplayImageBuffers = bufDisplayImageBuffers;
pMBScreen->ClearImageBufferArea = bufClearImageBufferArea;
pMBScreen->ChangeMBufferAttributes = NoopDDA_True;
pMBScreen->ChangeBufferAttributes = NoopDDA_True;
pMBScreen->DeleteBufferDrawable = bufDestroyBuffer;
pMBScreen->WrapScreenFuncs = bufWrapScreenFuncs;
pMBScreen->ResetProc = bufResetProc;
pMBPriv = (mbufBufferPrivPtr) xalloc(sizeof *pMBPriv);
if (!pMBPriv)
return (FALSE);
pMBScreen->devPrivate.ptr = (pointer) pMBPriv;
pMBPriv->frameBuffer = bufFrameBuffer[pScreen->myNum];
pMBPriv->selectPlane = bufselectPlane[pScreen->myNum];
box.x1 = 0;
box.y1 = 0;
box.x2 = pScreen->width;
box.y2 = pScreen->height;
pMBPriv->rgnChanged = TRUE;
REGION_INIT(pScreen, &pMBPriv->backBuffer, &box, 1);
REGION_INIT(pScreen, &pMBPriv->subtractRgn, &box, 1);
REGION_NULL(pScreen, &pMBPriv->unionRgn);
pMBPriv->CopyBufferBits = bufCopyBufferBitsFunc[pScreen->myNum];
pMBPriv->DrawSelectPlane = bufDrawSelectPlaneFunc[pScreen->myNum];
if (!pMBPriv->CopyBufferBits)
pMBPriv->CopyBufferBits = bufCopyBufferBits;
if (!pMBPriv->DrawSelectPlane)
pMBPriv->DrawSelectPlane = bufDrawSelectPlane;
pMBPriv->funcsWrapped = 0;
pMBPriv->inClearToBackground = FALSE;
pMBPriv->WindowExposures = NULL;
pMBPriv->CopyWindow = NULL;
pMBPriv->ClearToBackground = NULL;
pMBPriv->ClipNotify = NULL;
pMBPriv->ChangeWindowAttributes = NULL;
WRAP_SCREEN_FUNC(pScreen,pMBPriv,PostValidateTree, bufPostValidateTree);
return TRUE;
}
static void
UpdateBufferFromWindow(pBuffer, pWin)
BufferPtr pBuffer;
WindowPtr pWin;
{
pBuffer->drawable.x = pWin->drawable.x;
pBuffer->drawable.y = pWin->drawable.y;
pBuffer->drawable.width = pWin->drawable.width;
pBuffer->drawable.height = pWin->drawable.height;
pBuffer->drawable.serialNumber = NEXT_SERIAL_NUMBER;
pBuffer->parent = pWin->parent;
pBuffer->clipList = pWin->clipList;
pBuffer->borderClip = pWin->clipList;
pBuffer->winSize = pWin->winSize;
pBuffer->borderSize = pWin->borderSize;
pBuffer->origin = pWin->origin;
}
static BufferPtr
bufCreateBuffer(pScreen, pWin, bufferNum)
ScreenPtr pScreen;
WindowPtr pWin;
int bufferNum;
{
mbufBufferPrivPtr pMBPriv;
DevUnion *devPrivates;
BufferPtr pBuffer;
int i;
pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
pBuffer = AllocateWindow(pWin->drawable.pScreen);
if (!pBuffer)
return (NULL);
devPrivates = pBuffer->devPrivates;
*pBuffer = *pWin;
pBuffer->devPrivates = devPrivates;
pBuffer->drawable.type = DRAWABLE_BUFFER;
pBuffer->drawable.serialNumber = NEXT_SERIAL_NUMBER;
pBuffer->nextSib = NULL;
pBuffer->prevSib = NULL;
pBuffer->firstChild = NULL;
pBuffer->lastChild = NULL;
pBuffer->backStorage = NULL;
pBuffer->backingStore = NotUseful;
for (i=0; i < pScreen->WindowPrivateLen; i++)
pBuffer->devPrivates[i] = pWin->devPrivates[i];
pBuffer->devPrivates[frameWindowPrivateIndex] =
pMBPriv->frameBuffer[bufferNum];
return pBuffer;
}
static void
bufDestroyBuffer(pDrawable)
DrawablePtr pDrawable;
{
xfree(pDrawable);
}
static int
bufCreateImageBuffers (pWin, nbuf, ids, action, hint)
WindowPtr pWin;
int nbuf;
XID *ids;
int action;
int hint;
{
ScreenPtr pScreen;
mbufScreenPtr pMBScreen;
mbufWindowPtr pMBWindow;
mbufBufferPtr pMBBuffer;
int i;
pScreen = pWin->drawable.pScreen;
pMBScreen = MB_SCREEN_PRIV(pScreen);
pMBWindow = MB_WINDOW_PRIV(pWin);
pMBWindow->devPrivate.ptr = (pointer) REGION_CREATE(pScreen, 0,0);
if (!pMBWindow->devPrivate.ptr)
return(0);
REGION_COPY(pScreen, (RegionPtr) pMBWindow->devPrivate.ptr,
&pWin->clipList);
for (i = 0; i < nbuf; i++)
{
pMBBuffer = pMBWindow->buffers + i;
pMBBuffer->pDrawable = (DrawablePtr) bufCreateBuffer(pScreen,pWin,i);
if (!pMBBuffer->pDrawable)
break;
if (!AddResource (ids[i], MultibufferDrawableResType,
(pointer) pMBBuffer->pDrawable))
{
bufDestroyBuffer((BufferPtr) pMBBuffer->pDrawable);
break;
}
pMBBuffer->pDrawable->id = ids[i];
if ((pWin->realized) && (i != pMBWindow->displayedMultibuffer))
(* pMBScreen->ClearImageBufferArea)(pMBBuffer, 0,0, 0,0, TRUE);
}
return i;
}
static void
bufDestroyImageBuffers(pWin)
WindowPtr pWin;
{
ScreenPtr pScreen;
mbufWindowPtr pMBWindow;
pScreen = pWin->drawable.pScreen;
if (pMBWindow = MB_WINDOW_PRIV(pWin))
{
mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
if (pWin->realized && (pMBWindow->displayedMultibuffer == BACK_BUFFER))
{
(* pMBPriv->CopyBufferBits)(pMBWindow, BACK_BUFFER, FRONT_BUFFER);
REGION_SUBTRACT(pScreen, &pMBPriv->backBuffer,
&pMBPriv->backBuffer, &pWin->clipList);
(* pMBPriv->DrawSelectPlane)(pScreen, pMBPriv->selectPlane,
&pWin->clipList, FRONT_BUFFER);
}
pWin->devPrivates[frameWindowPrivateIndex] =
pMBPriv->frameBuffer[FRONT_BUFFER];
REGION_DESTROY(pScreen, (RegionPtr) pMBWindow->devPrivate.ptr);
pMBWindow->devPrivate.ptr = NULL;
}
}
static void
bufClearImageBufferArea(pMBBuffer, x,y, w,h, generateExposures)
mbufBufferPtr pMBBuffer;
short x,y;
unsigned short w,h;
Bool generateExposures;
{
BoxRec box;
RegionRec reg;
RegionPtr pBSReg = NullRegion;
ScreenPtr pScreen;
BoxPtr extents;
int x1, y1, x2, y2;
BufferPtr pBuffer;
pBuffer = (BufferPtr) pMBBuffer->pDrawable;
x1 = pBuffer->drawable.x + x;
y1 = pBuffer->drawable.y + y;
if (w)
x2 = x1 + (int) w;
else
x2 = x1 + (int) pBuffer->drawable.width - (int) x;
if (h)
y2 = y1 + h;
else
y2 = y1 + (int) pBuffer->drawable.height - (int) y;
extents = &pBuffer->clipList.extents;
if (x1 < extents->x1)
x1 = extents->x1;
if (x2 > extents->x2)
x2 = extents->x2;
if (y1 < extents->y1)
y1 = extents->y1;
if (y2 > extents->y2)
y2 = extents->y2;
if (x2 <= x1 || y2 <= y1)
{
x2 = x1 = 0;
y2 = y1 = 0;
}
box.x1 = x1;
box.x2 = x2;
box.y1 = y1;
box.y2 = y2;
pScreen = pBuffer->drawable.pScreen;
REGION_INIT(pScreen, ®, &box, 1);
if (pBuffer->backStorage)
{
pBSReg = (* pScreen->ClearBackingStore)(pBuffer, x, y, w, h,
generateExposures);
}
REGION_INTERSECT(pScreen, ®, ®, &pBuffer->clipList);
if (pBuffer->backgroundState != None)
(*pScreen->PaintWindowBackground)(pBuffer, ®, PW_BACKGROUND);
if (generateExposures)
MultibufferExpose(pMBBuffer, ®);
#ifdef _notdef
if (generateExposures)
(*pScreen->WindowExposures)(pBuffer, ®, pBSReg);
else if (pBuffer->backgroundState != None)
(*pScreen->PaintWindowBackground)(pBuffer, ®, PW_BACKGROUND);
#endif
REGION_UNINIT(pScreen, ®);
if (pBSReg)
REGION_DESTROY(pScreen, pBSReg);
}
static void
bufWrapScreenFuncs(pScreen)
ScreenPtr pScreen;
{
mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
WRAP_SCREEN_FUNC(pScreen,pMBPriv,PostValidateTree, bufPostValidateTree);
WRAP_SCREEN_FUNC(pScreen,pMBPriv,ClipNotify, bufClipNotify);
WRAP_SCREEN_FUNC(pScreen,pMBPriv,WindowExposures,bufWindowExposures);
WRAP_SCREEN_FUNC(pScreen,pMBPriv,ChangeWindowAttributes, bufChangeWindowAttributes);
WRAP_SCREEN_FUNC(pScreen,pMBPriv,ClearToBackground,bufClearToBackground);
WRAP_SCREEN_FUNC(pScreen,pMBPriv,CopyWindow,bufCopyWindow);
}
static void
bufResetProc(pScreen)
ScreenPtr pScreen;
{
mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
REGION_UNINIT(pScreen, &pMBPriv->backBuffer);
REGION_UNINIT(pScreen, &pMBPriv->subtractRgn);
REGION_UNINIT(pScreen, &pMBPriv->unionRgn);
xfree(pMBPriv);
}
static void
bufCopyBufferBits(pMBWindow, srcBufferNum, dstBufferNum)
mbufWindowPtr pMBWindow;
int srcBufferNum, dstBufferNum;
{
DrawablePtr pSrcBuffer, pDstBuffer;
GCPtr pGC;
pSrcBuffer = pMBWindow->buffers[srcBufferNum].pDrawable;
pDstBuffer = pMBWindow->buffers[dstBufferNum].pDrawable;
pGC = GetScratchGC (pDstBuffer->depth, pDstBuffer->pScreen);
if (!pGC)
return;
ValidateGC (pDstBuffer, pGC);
(* pGC->ops->CopyArea) (pSrcBuffer, pDstBuffer, pGC,
0,0, pDstBuffer->width, pDstBuffer->height, 0,0);
FreeScratchGC (pGC);
}
static void
bufDrawSelectPlane(pScreen, selectPlane, prgn, bufferNum)
ScreenPtr pScreen;
DevUnion selectPlane;
RegionPtr prgn;
long bufferNum;
{
DrawablePtr pDrawable;
GCPtr pGC;
register int i;
register BoxPtr pbox;
register xRectangle *prect;
int numRects;
XID value;
if (REGION_NUM_RECTS(prgn) == 0)
return;
pDrawable = (DrawablePtr) selectPlane.ptr;
pGC = GetScratchGC (pDrawable->depth, pScreen);
if (!pGC)
return;
prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) *
sizeof(xRectangle));
if (!prect)
{
FreeScratchGC(pGC);
return;
}
value = (XID) bufferNum;
DoChangeGC(pGC, GCForeground, &value, 0);
ValidateGC(pDrawable, pGC);
numRects = REGION_NUM_RECTS(prgn);
pbox = REGION_RECTS(prgn);
for (i= numRects; --i >= 0; pbox++, prect++)
{
prect->x = pbox->x1;
prect->y = pbox->y1;
prect->width = pbox->x2 - pbox->x1;
prect->height = pbox->y2 - pbox->y1;
}
prect -= numRects;
(* pGC->ops->PolyFillRect)(pDrawable, pGC, numRects, prect);
DEALLOCATE_LOCAL(prect);
FreeScratchGC (pGC);
}
static void
bufDisplayImageBuffers(pScreen, ppMBWindow, ppMBBuffer, nbuf)
ScreenPtr pScreen;
mbufBufferPtr *ppMBBuffer;
mbufWindowPtr *ppMBWindow;
int nbuf;
{
WindowPtr pWin;
BufferPtr pPrevBuffer, pNewBuffer;
int i, number;
mbufBufferPrivPtr pMBPriv;
mbufBufferPtr pPrevMBBuffer;
pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
for (i = 0; i < nbuf; i++)
{
number = ppMBBuffer[i]->number;
pWin = ppMBWindow[i]->pWindow;
pPrevMBBuffer = MB_DISPLAYED_BUFFER(ppMBWindow[i]);
pPrevBuffer = (BufferPtr) pPrevMBBuffer->pDrawable;
pNewBuffer = (BufferPtr) ppMBBuffer[i]->pDrawable;
if (pPrevBuffer != pNewBuffer)
{
RegionPtr backBuffer = &pMBPriv->backBuffer;
(* pMBPriv->DrawSelectPlane)(pScreen, pMBPriv->selectPlane,
&pWin->clipList, number);
if (number == BACK_BUFFER)
REGION_UNION(pScreen, backBuffer, backBuffer,
&pWin->clipList);
else
REGION_SUBTRACT(pScreen, backBuffer, backBuffer,
&pWin->clipList);
pWin->devPrivates[frameWindowPrivateIndex] =
pMBPriv->frameBuffer[number];
}
switch (ppMBWindow[i]->updateAction)
{
case MultibufferUpdateActionUndefined:
break;
case MultibufferUpdateActionBackground:
(* MB_SCREEN_PRIV(pScreen)->ClearImageBufferArea)
(pPrevMBBuffer, 0,0, 0,0, FALSE);
break;
case MultibufferUpdateActionUntouched:
break;
case MultibufferUpdateActionCopied:
if (pPrevBuffer != pNewBuffer)
{
(* pMBPriv->CopyBufferBits) (ppMBWindow[i],
ppMBBuffer[i]->number, pPrevMBBuffer->number);
}
break;
}
}
}
static void
bufPostValidateTree(pParent, pChild, kind)
WindowPtr pParent, pChild;
VTKind kind;
{
ScreenPtr pScreen;
mbufBufferPrivPtr pMBPriv;
if (pParent)
pScreen = pParent->drawable.pScreen;
else if (pChild)
pScreen = pChild->drawable.pScreen;
else
return;
pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
UNWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, PostValidateTree);
if (pScreen->PostValidateTree)
(* pScreen->PostValidateTree)(pParent, pChild, kind);
REWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, PostValidateTree);
if (pMBPriv->rgnChanged)
{
RegionRec exposed;
RegionPtr pSubtractRgn, pUnionRgn;
Bool overlap;
pMBPriv->rgnChanged = FALSE;
pSubtractRgn = &pMBPriv->subtractRgn;
pUnionRgn = &pMBPriv->unionRgn;
REGION_VALIDATE(pScreen, pSubtractRgn, &overlap);
#ifdef DEBUG
if (overlap)
FatalError("bufPostValidateTree: subtractRgn overlaps");
#endif
REGION_VALIDATE(pScreen, pUnionRgn, &overlap);
#ifdef DEBUG
if (overlap)
FatalError("bufPostValidateTree: unionRgn overlaps");
#endif
REGION_SUBTRACT(pScreen, &pMBPriv->backBuffer, &pMBPriv->backBuffer,
pSubtractRgn);
REGION_UNION(pScreen, &pMBPriv->backBuffer, &pMBPriv->backBuffer,
pUnionRgn);
REGION_NULL(pScreen, &exposed);
REGION_SUBTRACT(pScreen, &exposed, pSubtractRgn, pUnionRgn);
(* pMBPriv->DrawSelectPlane)(pScreen, pMBPriv->selectPlane,
&exposed, FRONT_BUFFER);
REGION_SUBTRACT(pScreen, &exposed, pUnionRgn, pSubtractRgn);
(* pMBPriv->DrawSelectPlane)(pScreen, pMBPriv->selectPlane,
&exposed, BACK_BUFFER);
REGION_UNINIT(pScreen, &exposed);
REGION_EMPTY(pScreen, pSubtractRgn);
REGION_EMPTY(pScreen, pUnionRgn);
}
}
static void
bufClipNotify(pWin, dx,dy)
WindowPtr pWin;
int dx,dy;
{
ScreenPtr pScreen = pWin->drawable.pScreen;
mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
mbufWindowPtr pMBWindow;
int i;
UNWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, ClipNotify);
if (pScreen->ClipNotify)
(* pScreen->ClipNotify)(pWin, dx,dy);
REWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, ClipNotify);
if (pMBWindow = MB_WINDOW_PRIV(pWin))
{
RegionPtr pOldClipList = (RegionPtr) pMBWindow->devPrivate.ptr;
if (! REGION_EQUAL(pScreen, pOldClipList, &pWin->clipList))
{
if (pMBWindow->displayedMultibuffer == BACK_BUFFER)
{
pMBPriv->rgnChanged = TRUE;
REGION_APPEND(pScreen, &pMBPriv->subtractRgn, pOldClipList);
REGION_APPEND(pScreen, &pMBPriv->unionRgn, &pWin->clipList);
}
REGION_COPY(pScreen, pOldClipList,&pWin->clipList);
}
for (i=0; i<pMBWindow->numMultibuffer; i++)
{
mbufBufferPtr pMBBuffer = pMBWindow->buffers + i;
if (pMBBuffer->clobber != pWin->visibility)
{
pMBBuffer->clobber = pWin->visibility;
MultibufferClobber(pMBBuffer);
}
UpdateBufferFromWindow(pMBBuffer->pDrawable, pWin);
}
}
}
static Bool
bufChangeWindowAttributes(pWin, mask)
WindowPtr pWin;
unsigned long mask;
{
ScreenPtr pScreen = pWin->drawable.pScreen;
mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
mbufWindowPtr pMBWindow;
Bool ret;
UNWRAP_SCREEN_FUNC(pScreen, pMBPriv, Bool, ChangeWindowAttributes);
ret = (* pScreen->ChangeWindowAttributes)(pWin, mask);
REWRAP_SCREEN_FUNC(pScreen, pMBPriv, Bool, ChangeWindowAttributes);
if (pMBWindow = MB_WINDOW_PRIV(pWin))
{
if (mask & (CWBackPixmap | CWBackPixel))
{
BufferPtr pBuffer;
int i;
for (i=0; i<pMBWindow->displayedMultibuffer; i++)
{
pBuffer = (BufferPtr) pMBWindow->buffers[i].pDrawable;
pBuffer->backgroundState = pWin->backgroundState;
pBuffer->background = pWin->background;
}
}
}
return ret;
}
static void
bufWindowExposures(pWin, prgn, other_exposed)
WindowPtr pWin;
register RegionPtr prgn, other_exposed;
{
ScreenPtr pScreen = pWin->drawable.pScreen;
mbufWindowPtr pMBWindow = MB_WINDOW_PRIV(pWin);
mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
RegionRec tmp_rgn;
int i;
Bool handleBuffers;
handleBuffers = (!pMBPriv->inClearToBackground) &&
(pWin->drawable.type == DRAWABLE_WINDOW) &&
pMBWindow && (prgn && !REGION_NIL(prgn));
if (handleBuffers)
{
REGION_NULL(pScreen, &tmp_rgn);
REGION_COPY(pScreen, &tmp_rgn, prgn);
}
UNWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, WindowExposures);
(* pScreen->WindowExposures) (pWin, prgn, other_exposed);
REWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, WindowExposures);
if (!handleBuffers)
return;
for (i=0; i<pMBWindow->numMultibuffer; i++)
{
mbufBufferPtr pMBBuffer;
BufferPtr pBuffer;
pMBBuffer = pMBWindow->buffers + i;
pBuffer = (BufferPtr) pMBBuffer->pDrawable;
if (i != pMBWindow->displayedMultibuffer)
(* pScreen->PaintWindowBackground)(pBuffer,&tmp_rgn,PW_BACKGROUND);
if ((pMBBuffer->otherEventMask | pMBBuffer->eventMask) & ExposureMask)
MultibufferExpose(pMBBuffer, &tmp_rgn);
}
REGION_UNINIT(pScreen, &tmp_rgn);
}
static void
bufClearToBackground(pWin, x,y,w,h, sendExpose)
WindowPtr pWin;
int x,y, w,h;
Bool sendExpose;
{
ScreenPtr pScreen = pWin->drawable.pScreen;
mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
pMBPriv->inClearToBackground = TRUE;
UNWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, ClearToBackground);
(* pScreen->ClearToBackground)(pWin, x,y,w,h, sendExpose);
REWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, ClearToBackground);
pMBPriv->inClearToBackground = FALSE;
}
static void
bufCopyWindow(pWin, ptOldOrg, prgnSrc)
WindowPtr pWin;
DDXPointRec ptOldOrg;
RegionPtr prgnSrc;
{
ScreenPtr pScreen = pWin->drawable.pScreen;
mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
WindowPtr pwinroot;
DevUnion save;
UNWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, CopyWindow);
pwinroot = WindowTable[pScreen->myNum];
save = pwinroot->devPrivates[frameWindowPrivateIndex];
pwinroot->devPrivates[frameWindowPrivateIndex] =
pMBPriv->frameBuffer[FRONT_BUFFER];
(* pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
REGION_TRANSLATE(pScreen, prgnSrc,
ptOldOrg.x - pWin->drawable.x,
ptOldOrg.y - pWin->drawable.y);
pwinroot->devPrivates[frameWindowPrivateIndex] =
pMBPriv->frameBuffer[BACK_BUFFER];
(* pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
pwinroot->devPrivates[frameWindowPrivateIndex] = save;
REWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, CopyWindow);
}