Commit d690556d authored by Eric Anholt's avatar Eric Anholt

Integrate COMPOSITEWRAP branch including composite wrapper. This code still

    has several issues, including:
- CopyWindow and PaintWindow wrappers missing (will be done soon)
- Some segfaults seen in the Render wrappers.
- Xprt server build breaks with Composite.
- DDXs must be recompiled for Composite due to VisualRec size change.
- Composite bugs pointed out by Deron Johnson in email.
Also, reorder XFixes initialization according to comments by Keith which
    are also in xserver CVS.
parent 8763cca7
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* $Id$
*
* Copyright © 2003 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _COMPINT_H_
#define _COMPINT_H_
#include "misc.h"
#include "scrnintstr.h"
#include "os.h"
#include "regionstr.h"
#include "validate.h"
#include "windowstr.h"
#include "input.h"
#include "resource.h"
#include "colormapst.h"
#include "cursorstr.h"
#include "dixstruct.h"
#include "gcstruct.h"
#include "servermd.h"
#include "dixevents.h"
#include "globals.h"
#include "picturestr.h"
#include "extnsionst.h"
#include "mi.h"
#include "damage.h"
#include "damageextint.h"
#include "xfixes.h"
#include <X11/extensions/compositeproto.h>
#include <assert.h>
typedef struct _CompClientWindow {
struct _CompClientWindow *next;
XID id;
int update;
} CompClientWindowRec, *CompClientWindowPtr;
typedef struct _CompWindow {
RegionRec borderClip;
DamagePtr damage; /* for automatic update mode */
Bool damageRegistered;
Bool damaged;
int update;
CompClientWindowPtr clients;
int oldx;
int oldy;
PixmapPtr pOldPixmap;
int borderClipX, borderClipY;
} CompWindowRec, *CompWindowPtr;
#define COMP_ORIGIN_INVALID 0x80000000
typedef struct _CompSubwindows {
int update;
CompClientWindowPtr clients;
} CompSubwindowsRec, *CompSubwindowsPtr;
extern int CompPixmapPrivateIndex;
#define NUM_COMP_ALTERNATE_VISUALS 2
typedef struct _CompScreen {
PositionWindowProcPtr PositionWindow;
CopyWindowProcPtr CopyWindow;
CreateWindowProcPtr CreateWindow;
DestroyWindowProcPtr DestroyWindow;
RealizeWindowProcPtr RealizeWindow;
UnrealizeWindowProcPtr UnrealizeWindow;
PaintWindowProcPtr PaintWindowBackground;
ClipNotifyProcPtr ClipNotify;
/*
* Called from ConfigureWindow, these
* three track changes to the offscreen storage
* geometry
*/
MoveWindowProcPtr MoveWindow;
ResizeWindowProcPtr ResizeWindow;
ChangeBorderWidthProcPtr ChangeBorderWidth;
/*
* Reparenting has an effect on Subwindows redirect
*/
ReparentWindowProcPtr ReparentWindow;
ScreenBlockHandlerProcPtr BlockHandler;
CloseScreenProcPtr CloseScreen;
Bool damaged;
XID alternateVisuals[NUM_COMP_ALTERNATE_VISUALS];
} CompScreenRec, *CompScreenPtr;
#define HasCompRedirect(w) (wPixmap(w) != wPixmap(w->parent))
#define wScreen(w) ((w)->drawable.pScreen)
#define wPixmap(w) (*(wScreen(w)->GetWindowPixmap) (w))
extern int CompScreenPrivateIndex;
extern int CompWindowPrivateIndex;
extern int CompSubwindowsPrivateIndex;
#define GetCompScreen(s) ((CompScreenPtr) ((s)->devPrivates[CompScreenPrivateIndex].ptr))
#define GetCompWindow(w) ((CompWindowPtr) ((w)->devPrivates[CompWindowPrivateIndex].ptr))
#define GetCompSubwindows(w) ((CompSubwindowsPtr) ((w)->devPrivates[CompSubwindowsPrivateIndex].ptr))
extern RESTYPE CompositeClientWindowType;
extern RESTYPE CompositeClientSubwindowsType;
/*
* compalloc.c
*/
void
compReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure);
Bool
compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update);
void
compFreeClientWindow (WindowPtr pWin, XID id);
int
compUnredirectWindow (ClientPtr pClient, WindowPtr pWin, int update);
int
compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update);
void
compFreeClientSubwindows (WindowPtr pWin, XID id);
int
compUnredirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update);
int
compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin);
int
compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin);
Bool
compAllocPixmap (WindowPtr pWin);
void
compFreePixmap (WindowPtr pWin);
Bool
compReallocPixmap (WindowPtr pWin, int x, int y,
unsigned int w, unsigned int h, int bw);
/*
* compext.c
*/
void
CompositeExtensionInit (void);
/*
* compinit.c
*/
Bool
compScreenInit (ScreenPtr pScreen);
/*
* compwindow.c
*/
#ifdef NDEBUG
#define compCheckTree(s)
#else
void
compCheckTree (ScreenPtr pScreen);
#endif
void
compSetPixmap (WindowPtr pWin, PixmapPtr pPixmap);
Bool
compCheckRedirect (WindowPtr pWin);
Bool
compPositionWindow (WindowPtr pWin, int x, int y);
Bool
compRealizeWindow (WindowPtr pWin);
Bool
compUnrealizeWindow (WindowPtr pWin);
void
compPaintWindowBackground (WindowPtr pWin, RegionPtr pRegion, int what);
void
compClipNotify (WindowPtr pWin, int dx, int dy);
void
compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind);
void
compResizeWindow (WindowPtr pWin, int x, int y,
unsigned int w, unsigned int h, WindowPtr pSib);
void
compChangeBorderWidth (WindowPtr pWin, unsigned int border_width);
void
compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent);
Bool
compCreateWindow (WindowPtr pWin);
Bool
compDestroyWindow (WindowPtr pWin);
void
compSetRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion);
RegionPtr
compGetRedirectBorderClip (WindowPtr pWin);
void
compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
void
compWindowUpdate (WindowPtr pWin);
#endif /* _COMPINT_H_ */
This diff is collapsed.
/* $XdotOrg$ */
/* $XdotOrg: xc/programs/Xserver/dix/colormap.c,v 1.2.2.1 2004/07/30 06:54:41 anholt Exp $ */
/* $XFree86: xc/programs/Xserver/dix/colormap.c,v 3.11 2003/11/03 05:10:59 tsi Exp $ */
/***********************************************************
......@@ -190,7 +190,15 @@ static void FindColorInRootCmap (
#define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1)
#define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 1)
#define NUMBLUE(vis) ((vis->blueMask >> vis->offsetBlue) + 1)
#define RGBMASK(vis) (vis->redMask | vis->greenMask | vis->blueMask)
#ifdef COMPOSITE
#define NUMALPHA(vis) ((vis->alphaMask >> vis->offsetAlpha) + 1)
#define ALPHAMASK(vis) (vis->alphaMask)
#else
#define NUMALPHA(vis) 0
#define ALPHAMASK(vis) 0
#endif
#define RGBMASK(vis) (vis->redMask | vis->greenMask | vis->blueMask | ALPHAMASK(vis))
/* GetNextBitsOrBreak(bits, mask, base) --
* (Suggestion: First read the macro, then read this explanation.
......@@ -866,6 +874,9 @@ AllocColor (pmap, pred, pgreen, pblue, pPix, client)
*pPix = (pixR << pVisual->offsetRed) |
(pixG << pVisual->offsetGreen) |
(pixB << pVisual->offsetBlue);
#ifdef COMPOSITE
*pPix |= pVisual->alphaMask;
#endif
*pred = pmap->red[pixR].co.local.red;
*pgreen = pmap->green[pixG].co.local.green;
*pblue = pmap->blue[pixB].co.local.blue;
......@@ -956,6 +967,9 @@ AllocColor (pmap, pred, pgreen, pblue, pPix, client)
return (BadAlloc);
}
*pPix = pixR | pixG | pixB;
#ifdef COMPOSITE
*pPix |= pVisual->alphaMask;
#endif
break;
}
......@@ -1928,6 +1942,10 @@ AllocDirect (client, pmap, c, r, g, b, contig, pixels, prmask, pgmask, pbmask)
}
pmap->numPixelsBlue[client] += npixB;
pmap->freeBlue -= npixB;
#ifdef COMPOSITE
for (pDst = pixels; pDst < pixels + c; pDst++)
*pDst |= pmap->pVisual->alphaMask;
#endif
DEALLOCATE_LOCAL(ppixBlue);
DEALLOCATE_LOCAL(ppixGreen);
......
/* $XdotOrg: xc/programs/Xserver/dix/window.c,v 1.4 2004/07/29 23:43:39 kem Exp $ */
/* $XdotOrg: xc/programs/Xserver/dix/window.c,v 1.4.2.1 2004/07/30 06:54:41 anholt Exp $ */
/* $Xorg: window.c,v 1.4 2001/02/09 02:04:41 xorgcvs Exp $ */
/*
......@@ -291,6 +291,9 @@ SetWindowToDefaults(register WindowPtr pWin)
pWin->srcBuffer = DBE_FRONT_BUFFER;
pWin->dstBuffer = DBE_FRONT_BUFFER;
#endif
#ifdef COMPOSITE
pWin->redirectDraw = 0;
#endif
}
static void
......@@ -1661,6 +1664,19 @@ void
SetWinSize (pWin)
register WindowPtr pWin;
{
#ifdef COMPOSITE
if (pWin->redirectDraw)
{
BoxRec box;
box.x1 = pWin->drawable.x;
box.y1 = pWin->drawable.y;
box.x2 = pWin->drawable.x + pWin->drawable.width;
box.y2 = pWin->drawable.y + pWin->drawable.height;
REGION_RESET (pScreen, &pWin->winSize, &box);
}
else
#endif
ClippedRegionFromBox(pWin->parent, &pWin->winSize,
pWin->drawable.x, pWin->drawable.y,
(int)pWin->drawable.width,
......@@ -1691,6 +1707,19 @@ SetBorderSize (pWin)
if (HasBorder (pWin)) {
bw = wBorderWidth (pWin);
#ifdef COMPOSITE
if (pWin->redirectDraw)
{
BoxRec box;
box.x1 = pWin->drawable.x - bw;
box.y1 = pWin->drawable.y - bw;
box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
box.y2 = pWin->drawable.y + pWin->drawable.height + bw;
REGION_RESET (pScreen, &pWin->borderSize, &box);
}
else
#endif
ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
pWin->drawable.x - bw, pWin->drawable.y - bw,
(int)(pWin->drawable.width + (bw<<1)),
......
......@@ -79,6 +79,10 @@ typedef struct _Pixmap {
#ifdef PIXPRIV
DevUnion *devPrivates; /* real devPrivates like gcs & windows */
#endif
#ifdef COMPOSITE
short screen_x;
short screen_y;
#endif
} PixmapRec;
#endif /* PIXMAPSTRUCT_H */
......@@ -75,6 +75,10 @@ typedef struct _Visual {
* it may have more or fewer */
unsigned long redMask, greenMask, blueMask;
int offsetRed, offsetGreen, offsetBlue;
#ifdef COMPOSITE
unsigned long alphaMask;
int offsetAlpha;
#endif
} VisualRec;
typedef struct _Depth {
......
......@@ -135,6 +135,9 @@ typedef struct _Window {
#define DBE_BACK_BUFFER 0
unsigned dstBuffer:1; /* destination buffer for rendering */
unsigned srcBuffer:1; /* source buffer for rendering */
#endif
#ifdef COMPOSITE
unsigned redirectDraw:1; /* rendering is redirected from here */
#endif
DevUnion *devPrivates;
} WindowRec;
......
......@@ -495,6 +495,16 @@ extern int miShapedWindowIn(
int /*y*/
);
typedef void
(*SetRedirectBorderClipProcPtr) (WindowPtr pWindow, RegionPtr pRegion);
typedef RegionPtr
(*GetRedirectBorderClipProcPtr) (WindowPtr pWindow);
void
miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
GetRedirectBorderClipProcPtr getBorderClip);
extern int miValidateTree(
WindowPtr /*pParent*/,
WindowPtr /*pChild*/,
......
/* $XdotOrg: xc/programs/Xserver/mi/miinitext.c,v 1.6 2004/07/31 01:37:47 stukreit Exp $ */
/* $XdotOrg: xc/programs/Xserver/mi/miinitext.c,v 1.7 2004/07/31 04:23:21 kem Exp $ */
/* $XFree86: xc/programs/Xserver/mi/miinitext.c,v 3.67 2003/01/12 02:44:27 dawes Exp $ */
/***********************************************************
......@@ -282,6 +282,9 @@ extern void XFixesExtensionInit(INITARGS);
#ifdef DAMAGE
extern void DamageExtensionInit(INITARGS);
#endif
#ifdef COMPOSITE
extern void CompositeExtensionInit(INITARGS);
#endif
/* The following is only a small first step towards run-time
* configurable extensions.
......@@ -456,6 +459,10 @@ InitExtensions(argc, argv)
DPSExtensionInit();
#endif
#endif
#ifdef XFIXES
/* must be before Render to layer DisplayCursor correctly */
XFixesExtensionInit();
#endif
#ifdef RENDER
if (!noRenderExtension) RenderExtensionInit();
#endif
......@@ -471,12 +478,12 @@ InitExtensions(argc, argv)
#ifdef XEVIE
if (!noXevieExtension) XevieExtensionInit();
#endif
#ifdef XFIXES
XFixesExtensionInit();
#endif
#ifdef DAMAGE
DamageExtensionInit();
#endif
#ifdef COMPOSITE
CompositeExtensionInit ();
#endif
}
void
......@@ -590,6 +597,10 @@ static ExtensionModule staticExtensions[] = {
#ifdef PANORAMIX
{ PanoramiXExtensionInit, PANORAMIX_PROTOCOL_NAME, &noPanoramiXExtension, NULL, NULL },
#endif
#ifdef XFIXES
/* must be before Render to layer DisplayCursor correctly */
{ XFixesExtensionInit, "XFIXES", NULL, NULL, NULL },
#endif
#ifdef XF86BIGFONT
{ XFree86BigfontExtensionInit, XF86BIGFONTNAME, NULL, NULL, NULL },
#endif
......@@ -602,9 +613,9 @@ static ExtensionModule staticExtensions[] = {
#ifdef DAMAGE
{ DamageExtensionInit, "DAMAGE", NULL, NULL },
#endif
#ifdef XFIXES
{ XFixesExtensionInit, "XFIXES", NULL, NULL },
#endif
#ifdef COMPOSITE
{ CompositeExtensionInit, "COMPOSITE", NULL, NULL },
#endif
#ifdef XEVIE
{ XevieExtensionInit, "XEVIE", &noXevieExtension, NULL },
#endif
......
/* $Xorg: mivaltree.c,v 1.4 2001/02/09 02:05:22 xorgcvs Exp $ */
/* $XdotOrg$ */
/* $XdotOrg: xc/programs/Xserver/mi/mivaltree.c,v 1.2.2.1 2004/07/30 06:54:42 anholt Exp $ */
/*
* mivaltree.c --
* Functions for recalculating window clip lists. Main function
......@@ -167,6 +167,17 @@ miShapedWindowIn (pScreen, universe, bounding, rect, x, y)
}
#endif
static GetRedirectBorderClipProcPtr miGetRedirectBorderClipProc;
static SetRedirectBorderClipProcPtr miSetRedirectBorderClipProc;
void
miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
GetRedirectBorderClipProcPtr getBorderClip)
{
miSetRedirectBorderClipProc = setBorderClip;
miGetRedirectBorderClipProc = getBorderClip;
}
#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
HasBorder(w) && \
(w)->backgroundState == ParentRelative)
......@@ -264,6 +275,18 @@ miComputeClips (
((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
SendVisibilityNotify(pParent);
#ifdef COMPOSITE
/*
* In redirected drawing case, reset universe to borderSize
*/
if (pParent->redirectDraw)
{
if (miSetRedirectBorderClipProc)
(*miSetRedirectBorderClipProc) (pParent, universe);
REGION_COPY(pScreen, universe, &pParent->borderSize);
}
#endif
dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
......@@ -640,7 +663,12 @@ miValidateTree (pParent, pChild, kind)
{
if (pWin->valdata)
{
REGION_APPEND( pScreen, &totalClip, &pWin->borderClip);
RegionPtr pBorderClip = &pWin->borderClip;
#ifdef COMPOSITE
if (pWin->redirectDraw && miGetRedirectBorderClipProc)
pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
#endif
REGION_APPEND( pScreen, &totalClip, pBorderClip );
if (pWin->viewable)
viewvals++;
}
......@@ -654,7 +682,12 @@ miValidateTree (pParent, pChild, kind)
{
if (pWin->valdata)
{
REGION_APPEND( pScreen, &totalClip, &pWin->borderClip);
RegionPtr pBorderClip = &pWin->borderClip;
#ifdef COMPOSITE
if (pWin->redirectDraw && miGetRedirectBorderClipProc)
pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
#endif
REGION_APPEND( pScreen, &totalClip, pBorderClip );
if (pWin->viewable)
viewvals++;
}
......
This diff is collapsed.
/*
* Copyright 2004 Eric Anholt
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Eric Anholt not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Eric Anholt makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Header$ */
#include "picturestr.h"
/*
* One of these structures is allocated per GC that gets used with a window with
* backing pixmap.
*/
typedef struct {
GCPtr pBackingGC; /* Copy of the GC but with graphicsExposures
* set FALSE and the clientClip set to
* clip output to the valid regions of the
* backing pixmap. */
int guarantee; /* GuaranteeNothing, etc. */
unsigned long serialNumber; /* clientClip computed time */
unsigned long stateChanges; /* changes in parent gc since last copy */
GCOps *wrapOps; /* wrapped ops */
GCFuncs *wrapFuncs; /* wrapped funcs */
} cwGCRec, *cwGCPtr;
extern int cwGCIndex;
#define getCwGC(pGC) ((cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr)
#define setCwGC(pGC,p) ((pGC)->devPrivates[cwGCIndex].ptr = (pointer) (p))
typedef struct {
PicturePtr pBackingPicture;
unsigned long serialNumber; /* clientClip computed time */
unsigned long stateChanges; /* changes in parent gc since last copy */
} cwPictureRec, *cwPicturePtr;
extern int cwPictureIndex;
#define getCwPicture(pPicture) ((cwPicturePtr)(pPicture)->devPrivates[cwPictureIndex].ptr)
#define setCwPicture(pPicture,p) ((pPicture)->devPrivates[cwPictureIndex].ptr = (pointer) (p))
#define cwDrawableIsRedirWindow(pDraw) ((pDraw)->type == DRAWABLE_WINDOW && \
((WindowPtr)(pDraw))->redirectDraw)
typedef struct {
/*
* screen func wrappers
*/
CloseScreenProcPtr CloseScreen;
GetImageProcPtr GetImage;
GetSpansProcPtr GetSpans;
CreateGCProcPtr CreateGC;
DestroyWindowProcPtr DestroyWindow;
StoreColorsProcPtr StoreColors;
InitIndexedProcPtr InitIndexed;
CloseIndexedProcPtr CloseIndexed;
UpdateIndexedProcPtr UpdateIndexed;
#ifdef RENDER
CreatePictureProcPtr CreatePicture;
DestroyPictureProcPtr DestroyPicture;
ChangePictureClipProcPtr ChangePictureClip;
DestroyPictureClipProcPtr DestroyPictureClip;
ChangePictureProcPtr ChangePicture;
ValidatePictureProcPtr ValidatePicture;
CompositeProcPtr Composite;
GlyphsProcPtr Glyphs;
CompositeRectsProcPtr CompositeRects;
TrapezoidsProcPtr Trapezoids;
TrianglesProcPtr Triangles;
TriStripProcPtr TriStrip;
TriFanProcPtr TriFan;
RasterizeTrapezoidProcPtr RasterizeTrapezoid;
#if 0
AddTrapsProcPtr AddTraps;
#endif
#endif
} cwScreenRec, *cwScreenPtr;
extern int cwScreenIndex;
#define getCwScreen(pScreen) ((cwScreenPtr)(pScreen)->devPrivates[cwScreenIndex].ptr)
#define setCwScreen(pScreen,p) ((cwScreenPtr)(pScreen)->devPrivates[cwScreenIndex].ptr = (p))
#define CW_COPY_OFFSET_XYPOINTS(ppt_trans, ppt, npt) do { \
short *_origpt = (short *)(ppt); \
short *_transpt = (short *)(ppt_trans); \
int _i; \
for (_i = 0; _i < npt; _i++) { \
*_transpt++ = *_origpt++ + dst_off_x; \
*_transpt++ = *_origpt++ + dst_off_y; \
} \
} while (0)
#define CW_COPY_OFFSET_RECTS(prect_trans, prect, nrect) do { \
short *_origpt = (short *)(prect); \
short *_transpt = (short *)(prect_trans); \
int _i; \