You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
774 lines
18 KiB
774 lines
18 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: engine.hxx
|
|
*
|
|
* Copyright (c) 1989-1999 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#if defined(_AMD64_)
|
|
#include "..\math\daytona\amd64\efloat.hxx"
|
|
#elif defined(_IA64_)
|
|
#include "..\math\daytona\ia64\efloat.hxx"
|
|
#elif defined(BUILD_WOW6432) && defined(_X86_)
|
|
#include "..\math\wow6432\i386\efloat.hxx"
|
|
#else
|
|
#include "..\math\daytona\i386\efloat.hxx"
|
|
#endif
|
|
|
|
#include "mutex.hxx"
|
|
|
|
#include "epointfl.hxx" // has to be here since it uses ASSERTGDI
|
|
#include "hmgr.hxx"
|
|
|
|
class RFONT;
|
|
class RFONTOBJ;
|
|
class XDCOBJ;
|
|
class DCOBJ; // Make a foward reference
|
|
typedef DCOBJ *PDCOBJ;
|
|
class SURFACE;
|
|
class EBRUSHOBJ;
|
|
class EFONTOBJ;
|
|
class CACHEOBJ;
|
|
class ECLIPOBJ;
|
|
class EPATHOBJ;
|
|
class EXFORMOBJ;
|
|
class PALETTE;
|
|
typedef PALETTE *PPALETTE;
|
|
class REGION;
|
|
class PFE;
|
|
typedef PFE *PPFE;
|
|
class PFF;
|
|
typedef PFF *PPFF;
|
|
class DC;
|
|
typedef DC *PDC;
|
|
class XLATE;
|
|
typedef XLATE *PXLATE;
|
|
class PDEV;
|
|
typedef PDEV *PPDEV;
|
|
|
|
|
|
class MATRIX
|
|
{
|
|
public:
|
|
EFLOAT efM11;
|
|
EFLOAT efM12;
|
|
EFLOAT efM21;
|
|
EFLOAT efM22;
|
|
EFLOAT efDx;
|
|
EFLOAT efDy;
|
|
FIX fxDx;
|
|
FIX fxDy;
|
|
FLONG flAccel; // accelerators
|
|
};
|
|
|
|
typedef MATRIX *PMATRIX;
|
|
|
|
/**************************************************************************\
|
|
*
|
|
\**************************************************************************/
|
|
|
|
typedef union {
|
|
LONG l;
|
|
FLOAT_LONG el;
|
|
} LONG_FLOAT;
|
|
|
|
/******************************Class***************************************\
|
|
* EPOINTFIX
|
|
*
|
|
* This is an "energized" version of the common POINTFIX.
|
|
*
|
|
* History:
|
|
*
|
|
* Tue 06-Nov-1990 -by- Paul Butzi [paulb]
|
|
* Shamelessly stole code from POINTL class
|
|
*
|
|
\**************************************************************************/
|
|
|
|
class EPOINTFIX : public _POINTFIX /* eptfx */
|
|
{
|
|
public:
|
|
// Constructor -- This one is to allow EPOINTFIX inside other classes.
|
|
|
|
EPOINTFIX() {}
|
|
|
|
// Constructor -- Fills the EPOINTFIX. If want to produce EPOINTFIX from
|
|
// LONG's x1 and y1, those ought to be converted to FIX using
|
|
// LTOFX macro before being passed to this constructor
|
|
|
|
EPOINTFIX(FIX x1,FIX y1)
|
|
{
|
|
x = x1;
|
|
y = y1;
|
|
}
|
|
|
|
// Constructor -- Fills the EPOINTFIX.
|
|
|
|
EPOINTFIX(POINTFIX& ptfx)
|
|
{
|
|
x = ptfx.x;
|
|
y = ptfx.y;
|
|
}
|
|
|
|
// Destructor -- Does nothing.
|
|
|
|
~EPOINTFIX() {}
|
|
|
|
// Operator= -- Create from a POINTL
|
|
|
|
VOID operator=(POINTL ptl)
|
|
{
|
|
x = LTOFX(ptl.x);
|
|
y = LTOFX(ptl.y);
|
|
}
|
|
|
|
// Operator= -- Create from a POINTFIX
|
|
|
|
VOID operator=(POINTFIX ptfx)
|
|
{
|
|
x = ptfx.x;
|
|
y = ptfx.y;
|
|
}
|
|
|
|
// Operator+= -- Add to another POINTFIX.
|
|
|
|
VOID operator+=(POINTFIX& ptfx)
|
|
{
|
|
x += ptfx.x;
|
|
y += ptfx.y;
|
|
}
|
|
|
|
// Operator += -- Add in a POINTL
|
|
|
|
VOID operator+=(POINTL& ptl)
|
|
{
|
|
x += LTOFX(ptl.x);
|
|
y += LTOFX(ptl.y);
|
|
}
|
|
|
|
// Operator-= -- subtract another POINTFIX.
|
|
|
|
VOID operator-=(POINTFIX& ptfx)
|
|
{
|
|
x -= ptfx.x;
|
|
y -= ptfx.y;
|
|
}
|
|
};
|
|
|
|
/*********************************Class************************************\
|
|
* EVECTORL
|
|
*
|
|
* Energized class for VECTORL.
|
|
*
|
|
* History:
|
|
* 24-Jan-1992 -by- Wendy Wu [wendywu]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
class EVECTORL : public _VECTORL /* evecl */
|
|
{
|
|
public:
|
|
// Constructor.
|
|
|
|
EVECTORL(LONG x1, LONG y1) { x = x1; y = y1; }
|
|
};
|
|
|
|
/*********************************Class************************************\
|
|
* EVECTORFX
|
|
*
|
|
* Energized class for VECTORFX.
|
|
*
|
|
* History:
|
|
* 11-Feb-1992 -by- J. Andrew Goossen [andrewgo]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
class EVECTORFX : public _VECTORFX /* evec */
|
|
{
|
|
public:
|
|
VOID operator=(const VECTORFX& vec)
|
|
{
|
|
x = vec.x;
|
|
y = vec.y;
|
|
}
|
|
VOID operator=(const POINTFIX& ptfx)
|
|
{
|
|
x = ptfx.x;
|
|
y = ptfx.y;
|
|
}
|
|
BOOL operator==(const VECTORFX& vec)
|
|
{
|
|
return(x == vec.x && y == vec.y);
|
|
}
|
|
BOOL operator!=(const VECTORFX& vec)
|
|
{
|
|
return(x != vec.x || y != vec.y);
|
|
}
|
|
VOID operator+=(const VECTORFX& vec)
|
|
{
|
|
x += vec.x;
|
|
y += vec.y;
|
|
}
|
|
VOID operator+=(const POINTFIX& ptfx)
|
|
{
|
|
x += ptfx.x;
|
|
y += ptfx.y;
|
|
}
|
|
VOID operator-=(const VECTORFX& vec)
|
|
{
|
|
x -= vec.x;
|
|
y -= vec.y;
|
|
}
|
|
VOID operator-=(const POINTFIX& ptfx)
|
|
{
|
|
x -= ptfx.x;
|
|
y -= ptfx.y;
|
|
}
|
|
};
|
|
|
|
typedef EVECTORFX *PEVECTORFX; /* pevec */
|
|
|
|
/******************************Class***************************************\
|
|
* ERECTFX
|
|
*
|
|
* Parallel of ERECTL but for POINTFIX coordinates
|
|
*
|
|
* History:
|
|
* Thu 25-Oct-1990 13:10:00 -by- Paul Butzi [paulb]
|
|
* Shamelessly stole Chuck Whitmer's code from ERECTL.HXX.
|
|
*
|
|
* Thu 25-Oct-1990 13:40:00 -by- Paul Butzi [paulb]
|
|
* Added vInclude to make bounds erectfx computation simple
|
|
\**************************************************************************/
|
|
|
|
class ERECTFX : public _RECTFX
|
|
{
|
|
public:
|
|
|
|
// Constructor -- Allows ERECTFXs inside other classes.
|
|
|
|
ERECTFX() {}
|
|
|
|
// Constructor -- Initialize the rectangle.
|
|
|
|
ERECTFX(FIX x1,FIX y1,FIX x2,FIX y2)
|
|
{
|
|
xLeft = x1;
|
|
yTop = y1;
|
|
xRight = x2;
|
|
yBottom = y2;
|
|
}
|
|
|
|
// Destructor -- Does nothing.
|
|
|
|
~ERECTFX() {}
|
|
|
|
// bEmpty -- Check if the RECTFX is empty.
|
|
|
|
BOOL bEmpty()
|
|
{
|
|
return((xLeft == xRight) || (yTop == yBottom));
|
|
}
|
|
|
|
// Operator+= -- Offset the RECTFX.
|
|
|
|
VOID operator+=(POINTFIX& ptfx)
|
|
{
|
|
xLeft += ptfx.x;
|
|
xRight += ptfx.x;
|
|
yTop += ptfx.y;
|
|
yBottom += ptfx.y;
|
|
}
|
|
|
|
// Operator+= -- Offset the RECTFX by a POINTL
|
|
|
|
VOID operator+=(POINTL& ptl)
|
|
{
|
|
xLeft += LTOFX(ptl.x);
|
|
xRight += LTOFX(ptl.x);
|
|
yTop += LTOFX(ptl.y);
|
|
yBottom += LTOFX(ptl.y);
|
|
}
|
|
|
|
// Operator-= -- Offset the RECTFX by a POINTL
|
|
|
|
VOID operator-=(POINTL& ptl)
|
|
{
|
|
xLeft -= LTOFX(ptl.x);
|
|
xRight -= LTOFX(ptl.x);
|
|
yTop -= LTOFX(ptl.y);
|
|
yBottom -= LTOFX(ptl.y);
|
|
}
|
|
|
|
// Operator+= -- Add another RECTFX. Only the destination may be empty.
|
|
|
|
VOID operator+=(RECTFX& rcl)
|
|
{
|
|
if (xLeft == xRight || yTop == yBottom)
|
|
*(RECTFX *)this = rcl;
|
|
else
|
|
{
|
|
if (rcl.xLeft < xLeft)
|
|
xLeft = rcl.xLeft;
|
|
if (rcl.yTop < yTop)
|
|
yTop = rcl.yTop;
|
|
if (rcl.xRight > xRight)
|
|
xRight = rcl.xRight;
|
|
if (rcl.yBottom > yBottom)
|
|
yBottom = rcl.yBottom;
|
|
}
|
|
}
|
|
|
|
// vOrder -- Make the rectangle well ordered.
|
|
|
|
VOID vOrder()
|
|
{
|
|
FIX l;
|
|
if (xLeft > xRight)
|
|
{
|
|
l = xLeft;
|
|
xLeft = xRight;
|
|
xRight = l;
|
|
}
|
|
if (yTop > yBottom)
|
|
{
|
|
l = yTop;
|
|
yTop = yBottom;
|
|
yBottom = l;
|
|
}
|
|
}
|
|
|
|
|
|
// vInclude -- stretch the rectangle to include a given point
|
|
|
|
VOID vInclude(POINTFIX& ptfx)
|
|
{
|
|
if (xLeft > ptfx.x)
|
|
xLeft = ptfx.x;
|
|
else if (xRight < ptfx.x)
|
|
xRight = ptfx.x;
|
|
|
|
if (yBottom < ptfx.y)
|
|
yBottom = ptfx.y;
|
|
else if (yTop > ptfx.y)
|
|
yTop = ptfx.y;
|
|
}
|
|
};
|
|
|
|
/******************************Class***************************************\
|
|
* EPOINTL.
|
|
*
|
|
* This is an "energized" version of the common POINTL.
|
|
*
|
|
* History:
|
|
*
|
|
* Fri 05-Oct-1990 -by- Bodin Dresevic [BodinD]
|
|
* update: added one more constructor and -= overloaded operators
|
|
*
|
|
* Thu 13-Sep-1990 15:11:42 -by- Charles Whitmer [chuckwh]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
class EPOINTL : public _POINTL /* eptl */
|
|
{
|
|
public:
|
|
// Constructor -- This one is to allow EPOINTLs inside other classes.
|
|
|
|
EPOINTL() {}
|
|
|
|
// Constructor -- Fills the EPOINTL.
|
|
|
|
EPOINTL(LONG x1,LONG y1)
|
|
{
|
|
x = x1;
|
|
y = y1;
|
|
}
|
|
|
|
// Constructor -- Fills the EPOINTL.
|
|
|
|
EPOINTL(POINTL& ptl)
|
|
{
|
|
x = ptl.x;
|
|
y = ptl.y;
|
|
}
|
|
|
|
// Constructor -- Fills the EPOINTL.
|
|
|
|
EPOINTL(POINTFIX& ptfx)
|
|
{
|
|
x = FXTOL(ptfx.x);
|
|
y = FXTOL(ptfx.y);
|
|
}
|
|
|
|
// Destructor -- Does nothing.
|
|
|
|
~EPOINTL() {}
|
|
|
|
// Operator+= -- Add to another POINTL.
|
|
|
|
VOID operator+=(POINTL& ptl)
|
|
{
|
|
x += ptl.x;
|
|
y += ptl.y;
|
|
}
|
|
|
|
// Operator-= -- Add to another POINTL.
|
|
|
|
VOID operator-=(POINTL& ptl)
|
|
{
|
|
x -= ptl.x;
|
|
y -= ptl.y;
|
|
}
|
|
|
|
// operator== -- checks that the two coordinates are equal
|
|
|
|
BOOL operator==(POINTL& ptl)
|
|
{
|
|
return(x == ptl.x && y == ptl.y);
|
|
}
|
|
};
|
|
|
|
/******************************Class***************************************\
|
|
* ERECTL
|
|
*
|
|
* This is an "energized" version of the common RECTL.
|
|
*
|
|
* History:
|
|
*
|
|
* Fri 05-Oct-1990 -by- Bodin Dresevic [BodinD]
|
|
* update: added one more constructor and -= overloaded operators
|
|
*
|
|
* Thu 13-Sep-1990 15:11:42 -by- Charles Whitmer [chuckwh]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
class ERECTL : public _RECTL
|
|
{
|
|
public:
|
|
// Constructor -- Allows ERECTLs inside other classes.
|
|
|
|
ERECTL() {}
|
|
|
|
// Constructor -- Initialize the rectangle.
|
|
|
|
ERECTL(LONG x1,LONG y1,LONG x2,LONG y2)
|
|
{
|
|
left = x1;
|
|
top = y1;
|
|
right = x2;
|
|
bottom = y2;
|
|
}
|
|
|
|
// Constructor -- energize given rectangle so that it can be manipulated
|
|
|
|
ERECTL(RECTL& rcl)
|
|
{
|
|
left = rcl.left ;
|
|
top = rcl.top ;
|
|
right = rcl.right ;
|
|
bottom = rcl.bottom ;
|
|
}
|
|
|
|
// Constructor -- Create given a RECTFX
|
|
|
|
ERECTL(RECTFX& rcfx)
|
|
{
|
|
left = FXTOLFLOOR(rcfx.xLeft);
|
|
top = FXTOLFLOOR(rcfx.yTop);
|
|
right = FXTOLCEILING(rcfx.xRight);
|
|
bottom = FXTOLCEILING(rcfx.yBottom);
|
|
}
|
|
|
|
// Destructor -- Does nothing.
|
|
|
|
~ERECTL() {}
|
|
|
|
// bEmpty -- Check if the RECTL is empty.
|
|
|
|
BOOL bEmpty()
|
|
{
|
|
return((left == right) || (top == bottom));
|
|
}
|
|
|
|
// bWrapped -- Check if the RECTL is empty or not well-ordered
|
|
|
|
BOOL bWrapped()
|
|
{
|
|
return((left >= right) || (top >= bottom));
|
|
}
|
|
|
|
// Operator+= -- Offset the RECTL.
|
|
|
|
VOID operator+=(POINTL& ptl)
|
|
{
|
|
left += ptl.x;
|
|
right += ptl.x;
|
|
top += ptl.y;
|
|
bottom += ptl.y;
|
|
}
|
|
|
|
// Operator-= -- Offset the RECTL.
|
|
|
|
VOID operator-=(POINTL& ptl)
|
|
{
|
|
left -= ptl.x;
|
|
right -= ptl.x;
|
|
top -= ptl.y;
|
|
bottom -= ptl.y;
|
|
}
|
|
|
|
// Operator+= -- Add another RECTL. Only the destination may be empty.
|
|
|
|
VOID operator+=(RECTL& rcl)
|
|
{
|
|
if (left == right || top == bottom)
|
|
*((RECTL *) this) = rcl;
|
|
else
|
|
{
|
|
if (rcl.left < left)
|
|
left = rcl.left;
|
|
if (rcl.top < top)
|
|
top = rcl.top;
|
|
if (rcl.right > right)
|
|
right = rcl.right;
|
|
if (rcl.bottom > bottom)
|
|
bottom = rcl.bottom;
|
|
}
|
|
}
|
|
|
|
// Operator |= -- Accumulate bounds
|
|
|
|
VOID operator|=(RECTL& rcl)
|
|
{
|
|
if (rcl.left < left)
|
|
left = rcl.left;
|
|
if (rcl.top < top)
|
|
top = rcl.top;
|
|
if (rcl.right > right)
|
|
right = rcl.right;
|
|
if (rcl.bottom > bottom)
|
|
bottom = rcl.bottom;
|
|
}
|
|
|
|
// Operator*= -- Intersect another RECTL. The result may be empty.
|
|
|
|
ERECTL& operator*= (RECTL& rcl)
|
|
{
|
|
{
|
|
if (rcl.left > left)
|
|
left = rcl.left;
|
|
if (rcl.top > top)
|
|
top = rcl.top;
|
|
if (rcl.right < right)
|
|
right = rcl.right;
|
|
if (rcl.bottom < bottom)
|
|
bottom = rcl.bottom;
|
|
|
|
if (right < left)
|
|
left = right; // Only need to collapse one pair
|
|
else
|
|
if (bottom < top)
|
|
top = bottom;
|
|
}
|
|
return(*this);
|
|
}
|
|
|
|
// vOrder -- Make the rectangle well ordered.
|
|
|
|
VOID vOrder()
|
|
{
|
|
LONG l;
|
|
if (left > right)
|
|
{
|
|
l = left;
|
|
left = right;
|
|
right = l;
|
|
}
|
|
if (top > bottom)
|
|
{
|
|
l = top;
|
|
top = bottom;
|
|
bottom = l;
|
|
}
|
|
}
|
|
|
|
// bContain -- Test if it contains another rectangle
|
|
|
|
BOOL bContain(RECTL& rcl)
|
|
{
|
|
return ((left <= rcl.left) &&
|
|
(right >= rcl.right) &&
|
|
(top <= rcl.top) &&
|
|
(bottom >= rcl.bottom));
|
|
|
|
}
|
|
|
|
// bEqual -- Test if two ERECTLs are equal to each other
|
|
|
|
BOOL bEqual(ERECTL &ercl)
|
|
{
|
|
return ((left == ercl.left) &&
|
|
(right == ercl.right) &&
|
|
(top == ercl.top) &&
|
|
(bottom == ercl.bottom));
|
|
}
|
|
};
|
|
|
|
// bIntersect -- Test if two rectangles intersect
|
|
|
|
BOOL FASTCALL bIntersect(
|
|
CONST RECTL* prcl1,
|
|
CONST RECTL* prcl2);
|
|
|
|
// bIntersect -- Test if two rectangles intersect, and return intersection
|
|
|
|
BOOL FASTCALL bIntersect(
|
|
CONST RECTL* prcl1,
|
|
CONST RECTL* prcl2,
|
|
RECTL* prclResult); // May point to same as 'prcl1' or 'prcl2'
|
|
|
|
// cIntersect -- Intersect a rectangle with a list of rectangles
|
|
|
|
ULONG cIntersect(
|
|
RECTL* prclClip,
|
|
RECTL* prclList,
|
|
LONG c);
|
|
|
|
/*********************************Class************************************\
|
|
* class MALLOCOBJ
|
|
*
|
|
* A memory allocator that clean up after itself.
|
|
*
|
|
* Public Interface:
|
|
*
|
|
* History:
|
|
* Fri 21-Feb-1992 08:08:35 by Kirk Olynyk [kirko]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
class MALLOCOBJ {
|
|
private:
|
|
PVOID pv_;
|
|
public:
|
|
MALLOCOBJ(ULONGSIZE_T cb)
|
|
{
|
|
pv_ = PALLOCMEM(cb, 'pmtG');
|
|
if (!(pv_))
|
|
{
|
|
SAVE_ERROR_CODE(ERROR_NOT_ENOUGH_MEMORY);
|
|
}
|
|
}
|
|
~MALLOCOBJ() { if (pv_) VFREEMEM(pv_); }
|
|
PVOID bValid() { return(pv_); }
|
|
PVOID pv() { return(pv_); }
|
|
};
|
|
|
|
/*********************************class************************************\
|
|
* class SEMOBJ
|
|
*
|
|
* Semaphore Class
|
|
*
|
|
* Public Interface:
|
|
* SEMOBJ(HSEMAPHORE) // Acquire semaphore
|
|
* ~SEMOBJ() // Release semaphore
|
|
*
|
|
* History:
|
|
* 05-Jul-1990 14:57:20 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
class SEMOBJ
|
|
{
|
|
private:
|
|
HSEMAPHORE hsem;
|
|
|
|
public:
|
|
SEMOBJ(HSEMAPHORE hsem_)
|
|
{
|
|
hsem = hsem_;
|
|
GreAcquireSemaphore(hsem);
|
|
}
|
|
|
|
~SEMOBJ()
|
|
{
|
|
GreReleaseSemaphore(hsem);
|
|
}
|
|
};
|
|
|
|
// Useful macro.
|
|
|
|
#define SETFLAG(b,fl,FLAG) if (b) fl|=FLAG; else fl&=~FLAG
|
|
|
|
#define INC_SURF_UNIQ(pSurfTrg) ((SURFACE *) pSurfTrg)->vStamp()
|
|
|
|
/**************************************************************************\
|
|
* ulGetNewUniqueness
|
|
*
|
|
* Increments the specified uniqueness in a multithreaded-safe way, and
|
|
* returns the new uniqueness.
|
|
*
|
|
* History:
|
|
* 29-Dec-1993 by Michael Abrash [mikeab]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
ULONG ulGetNewUniquenessF(ULONG& ulUnique);
|
|
|
|
inline ULONG ulGetNewUniqueness(ULONG volatile &ulUnique)
|
|
{
|
|
return(InterlockedIncrement((LPLONG)&ulUnique));
|
|
}
|
|
|
|
#define USE_NINEGRID_STATIC
|
|
#if defined(USE_NINEGRID_STATIC)
|
|
extern HSEMAPHORE gNineGridSem;
|
|
#endif
|
|
|
|
/**************************************************************************\
|
|
*
|
|
* Support stuff for per process AVL table of User Mode Memory allocations
|
|
* made via EngUserMemAlloc.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
RTL_GENERIC_COMPARE_RESULTS GDIEngUserMemAllocNodeCompare(RTL_AVL_TABLE *Table,
|
|
PVOID FirstStruct,
|
|
PVOID SecondStruct);
|
|
PVOID GDIEngUserMemAllocNodeAlloc(RTL_AVL_TABLE *Table, ULONG size);
|
|
VOID GDIEngUserMemAllocNodeFree(RTL_AVL_TABLE *Table, PVOID Buffer);
|
|
|
|
typedef struct _GDIENGUSERMEMALLOCNODE
|
|
{
|
|
PVOID pUserMem;
|
|
SIZE_T cj;
|
|
HANDLE hSecure;
|
|
|
|
} GDIENGUSERMEMALLOCNODE, *PGDIENGUSERMEMALLOCNODE;
|
|
|
|
/*************************************************************************\
|
|
*
|
|
* CModeChangeInProgress
|
|
*
|
|
* Used to indicate a ModeChange in progress.
|
|
*
|
|
\*************************************************************************/
|
|
|
|
class CModeChangeInProgress
|
|
{
|
|
public:
|
|
|
|
static LONG lInModeChange;
|
|
static LONG lNeedSyncFlush;
|
|
static LONG lNeedTimerFlush;
|
|
|
|
CModeChangeInProgress()
|
|
{
|
|
InterlockedIncrement(&lInModeChange);
|
|
}
|
|
|
|
void vDone();
|
|
|
|
~CModeChangeInProgress()
|
|
{
|
|
}
|
|
};
|
|
|
|
|