Leaked source code of windows server 2003
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.
 
 
 
 
 
 

270 lines
8.1 KiB

/******************************Module*Header*******************************\
* Module Name: region.hxx
*
* Definition for REGION object
*
* Created: 29-Aug-1990 10:35:44
* Author: Donald Sidoroff [donalds]
*
* Tue 10-Mar-1992 - by - Eric Kutter [erick]
* cleaned up macros a bit.
*
* Copyright (c) 1990-1999 Microsoft Corporation
\**************************************************************************/
#ifndef _REGION_HXX
#define _REGION_HXX
#define NEG_INFINITY 0x80000000
#define POS_INFINITY 0x7fffffff
#define MIN_REGION_COORD ((LONG) 0xF8000000)
#define MAX_REGION_COORD ((LONG) 0x07FFFFFF)
#define REGION_POINT_OUTSIDE 1L
#define REGION_POINT_INSIDE 2L
#define REGION_RECT_OUTSIDE 1L
#define REGION_RECT_INTERSECT 2L
#ifndef GDIFLAGS_ONLY
#define VALID_SCR(X) (!((X) & 0xF8000000) || (((X) & 0xF8000000) == 0xF8000000))
#define VALID_SCRPT(P) ((VALID_SCR((P).x)) && (VALID_SCR((P).y)))
#define VALID_SCRPPT(P) ((VALID_SCR((P)->x)) && (VALID_SCR((P)->y)))
#define VALID_SCRRC(R) ((VALID_SCR((R).left)) && (VALID_SCR((R).bottom)) && \
(VALID_SCR((R).right)) && (VALID_SCR((R).top)))
#define VALID_SCRPRC(R) ((VALID_SCR((R)->left)) && (VALID_SCR((R)->bottom)) && \
(VALID_SCR((R)->right)) && (VALID_SCR((R)->top)))
// Private REGION data structures
typedef struct _INDEX_LONG
{
LONG x;
} INDEX_LONG;
// The scans are saved in a rather odd variable sized structure. What makes
// it odd is it is traversed in two directions. Because of this the sizing
// information has to be stored at both the beginning and the end of the
// structure.
//
// Offset Field
// +00 cWalls
// +04 yTop
// +08 yBottom
// +12 ai_x[0]
// +16 ai_x[1]
// ... ...
// +?? cWalls2
//
// But since the size of the structure is unknown, the cWalls2 field is
// actually unnamed. The following scheme can be used to move through the
// list. If you have the address of the cWalls field and want to go forwards
// in the list:
//
// pscn = (PSCAN) (((PBYTE) pscn) + pscn->sizeGet());
//
// If you have the address of the cWalls field and want to go backwards in
// the list:
//
// pscn = (PSCAN) &((PTRDIFF *) pscn)[-1]; // Get prev scan's cWalls2 field
// pscn = (PSCAN) (((PBYTE) pscn) - (pscn->sizeGet() - sizeof(PTRDIFF)));
//
// There is a special scan, the 'null' scan which looks like this:
//
// cWalls = 0;
// yTop = NEG_INFINITY;
// yBottom = POS_INFINITY;
// cWalls2 = 0;
//
// We need it often and it's size is useful, so its put in a constant here
#define NULL_SCAN_SIZE (offsetof(SCAN,ai_x) + sizeof(LONG))
#define PSCNGET(pscn) ((PSCAN)(((PBYTE) pscn) + pscn->sizeGet()))
class SCAN /* scn */
{
public:
COUNT cWalls;
LONG yTop;
LONG yBottom;
INDEX_LONG ai_x[1];
public:
SCAN() {}
~SCAN() {}
ULONGSIZE_T sizeGet()
{
return(NULL_SCAN_SIZE + (sizeof(INDEX_LONG) * cWalls));
}
};
typedef SCAN *PSCAN;
// The region structure also has an unnamed field. There may be two array
// of unknown size. If the region is defined by trapezoids, we need to save
// a list of lines that define the trapezoids. After this array (which may
// be empty) we save the list of scans that define the region. We also save
// the 'head' and 'tail' of the list of scans so we can easily traverse the
// list in either direction. Also note there is a 'null' region. It only
// has a 'null' scan in it. Other useful region sizes are the single rect
// region and the 'quantum' region. Since most of our rectangular regions
// are smaller then this we will never allocate an object smaller then this.
// It looks like:
//
// +-------------------------------+
// | scan 3 |
// | scan 3 |
// | scan 3 |
// | scan 3 |
// | scan 3 |
// +-----------+-------+-----------+
// | scan 2 | | scan 2 |
// | scan 2 | not | scan 2 |
// | scan 2 | in | scan 2 |
// | scan 2 | rgn | scan 2 |
// | scan 2 | | scan 2 |
// +-----------+-------+-----------+
// | scan 1 |
// | scan 1 |
// | scan 1 |
// | scan 1 |
// | scan 1 |
// +-------------------------------+
//
// Also note that this object can only be defined for rectagular regions.
#define NULL_REGION_SIZE (offsetof(REGION,scan) + NULL_SCAN_SIZE)
#define SINGLE_REGION_SIZE (NULL_REGION_SIZE + \
NULL_SCAN_SIZE + (sizeof(INDEX_LONG) * 2) + \
NULL_SCAN_SIZE)
#define QUANTUM_REGION_SIZE (NULL_REGION_SIZE + \
NULL_SCAN_SIZE + (sizeof(INDEX_LONG) * 2) + \
NULL_SCAN_SIZE + (sizeof(INDEX_LONG) * 4) + \
NULL_SCAN_SIZE + (sizeof(INDEX_LONG) * 2) + \
NULL_SCAN_SIZE)
#define RGN_COPYOFFSET offsetof(REGION,sizeRgn)
class REGION;
typedef REGION *PREGION;
class RGNOBJ;
typedef RGNOBJ *PRGNOBJ;
/**************************************************************************\
*
\**************************************************************************/
class RGNLOGENTRY
{
public:
PVOID teb;
HOBJ hrgn;
PREGION prgn;
PSZ pszOperation;
ULONG_PTR lRes; // used to return ULONG or HANDLE or pointer
ULONG_PTR lParm1; // used to pass in HANDLE or pointer or ULONG
ULONG_PTR lParm2;
ULONG_PTR lParm3;
PVOID pvCaller;
PVOID pvCallersCaller;
};
class RGNLOG
{
public:
#if DBG
RGNLOGENTRY *plog;
RGNLOG(HRGN hrgn,PREGION prgn,PSZ psz,ULONG_PTR l1 = 0, ULONG_PTR l2 = 0, ULONG_PTR l3 = 0);
RGNLOG(PREGION prgn,PSZ psz,ULONG_PTR l1 = 0, ULONG_PTR l2 = 0, ULONG_PTR l3 = 0);
VOID vRet(ULONG_PTR l) {plog->lRes = l;}
#else
RGNLOG(HRGN hrgn,PREGION prgn,PSZ psz,ULONG_PTR l1 = 0, ULONG_PTR l2 = 0, ULONG_PTR l3 = 0) {}
RGNLOG(PREGION prgn,PSZ psz,ULONG_PTR l1 = 0, ULONG_PTR l2 = 0, ULONG_PTR l3 = 0) {}
VOID vRet(ULONG_PTR l) {}
#endif
};
extern "C" LONG iLog;
extern HRGN hrgnDefault;
extern REGION *prgnDefault;
/********************************Structure*********************************\
*
* REGION
*
* Description:
*
* Size and unique infoemation followed by a variable length array
* of SCAN data
*
* Fields:
*
* sizeObj - Size of object
* iUnique - Uniqueness stamp
* cRefs - Region is saved this many levels deep
* pscnTail - Points past last scan
* sizeRgn - Size of region
* cScans - Number of scans
* rcl - Bounding box
* scan - variable length array of scans
*
\**************************************************************************/
class REGION : public OBJECT /* rgn */
{
private:
static ULONG ulUniqueREGION;
friend BOOLEAN InitializeGre(VOID);
public:
ULONGSIZE_T sizeObj;
ULONG iUnique;
COUNT cRefs;
PSCAN pscnTail;
// fields below here get copied in vCopy, fields above here are untouched.
ULONGSIZE_T sizeRgn;
COUNT cScans;
RECTL rcl;
SCAN scan;
public:
REGION() {}
~REGION() {}
PSCAN pscnHead() {return(&scan);}
VOID vStamp()
{
iUnique = ulGetNewUniqueness(ulUniqueREGION);
}
VOID vDeleteREGION()
{
RGNLOG rl(this,"REGION::vDeleteREGION");
if ((this != NULL) &&
(this != prgnDefault))
{
FREEOBJ(this,RGN_TYPE);
}
}
};
#endif GDIFLAGS_ONLY
#endif // #ifndef _REGION_HXX