Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

322 lines
9.4 KiB

/******************************Module*Header*******************************\
* Module Name: glgenwin.h
*
* Client side replacement for WNDOBJ. Tracks window state (size, location,
* clip region, etc.).
*
* Created: 12-Jan-1995 00:31:42
* Author: Gilman Wong [gilmanw]
*
* Copyright (c) 1994 Microsoft Corporation
*
\**************************************************************************/
#ifndef _GLGENWIN_H_
#define _GLGENWIN_H_
// Tracks lock/unlock calls on windows if defined. This is always
// on for checked builds.
#define TRACK_WINCRIT
#if DBG && !defined(TRACK_WINCRIT)
#define TRACK_WINCRIT
#endif
// Not defined in NT 3.51!
typedef ULONG FLONG;
/*
* GLGENscan structure
*
* Represents a single scan of a region. Consists of a top, a bottom
* and an even number of walls.
*
* Part of the GLGENscanData structure.
*/
typedef struct GLGENscanRec GLGENscan;
typedef struct GLGENscanRec
{
// Accelerator points to next GLGENscan in the array (we could compute).
GLGENscan *pNext;
ULONG cWalls;
LONG top;
LONG bottom;
#ifdef _IA64_
LONG pad;
#endif
LONG alWalls[1]; // array of walls
} GLGENscan;
/*
* GLGENscanData structure
*
* Scan line oriented version of the visible region info in the RGNDATA
* structure.
*/
typedef struct GLGENscanDataRec
{
ULONG cScans;
GLGENscan aScans[1]; // array of scans
} GLGENscanData;
/*
* GLGENlayerInfo structure
*
* Information about an overlay/underlay.
*/
typedef struct GLGENlayerInfo
{
LONG cPalEntries;
COLORREF pPalEntries[1];
} GLGENlayerInfo;
/*
* GLGENlayers structure
*
*
*/
typedef struct GLGENlayers
{
GLGENlayerInfo *overlayInfo[15];
GLGENlayerInfo *underlayInfo[15];
} GLGENlayers;
/*
* Identifying information for a window
*/
#define GLWID_ERROR 0
#define GLWID_HWND 1
#define GLWID_HDC 2
#define GLWID_DDRAW 3
typedef struct IDirectDrawSurface *LPDIRECTDRAWSURFACE;
typedef struct _GLWINDOWID
{
int iType;
HWND hwnd;
HDC hdc;
LPDIRECTDRAWSURFACE pdds;
} GLWINDOWID;
#define CLC_TRIVIAL 0
#define CLC_RECT 1
#define CLC_COMPLEX 2
/*
* GLGENwindows structure
*
* Substitute for the NT DDI's WNDOBJ service. This structure is used to
* track the current state of a window (size, location, clipping). A
* semaphore protected linked list of these is kept globally per-process.
*/
typedef struct GLGENwindowRec GLGENwindow;
typedef struct GLGENwindowRec
{
struct __GLGENbuffersRec *buffers; // Buffer information
int clipComplexity; // Clipping area complexity
RECTL rclBounds; // Clip area bounds
RECTL rclClient; // Window client rect
GLGENwindow *pNext; // linked list
GLWINDOWID gwid; // Identifying information
int ipfd; // pixel format assigned to this window
int ipfdDevMax; // max. device pixel format
WNDPROC pfnOldWndProc; // original WndProc function
ULONG ulPaletteUniq; // uniq palette id
ULONG ulFlags;
// These fields are used for direct screen access
LPDIRECTDRAWCLIPPER pddClip;// DirectDraw clipper assocated with window
UINT cjrgndat; // size of RGNDATA struct
RGNDATA *prgndat; // pointer to RGNDATA struct
// Scan version of RGNDATA.
UINT cjscandat; // size of GLGENscanData struct
GLGENscanData *pscandat; // pointer to GLGENscanData struct
// Installable client drivers ONLY.
PVOID pvDriver; // pointer to GLDRIVER for window
// Layer palettes for MCD drivers ONLY.
GLGENlayers *plyr; // pointer to GLGENlayers for window
// non-NULL only if overlays for MCD are
// actively in use
// DirectDraw surface vtbl pointer for doing DDraw surface validation
void *pvSurfaceVtbl;
// DirectDraw surface locked if DIRECTSCREEN is set
LPDIRECTDRAWSURFACE pddsDirectScreen;
void *pvDirectScreen;
void *pvDirectScreenLock;
// MCD server-side handle for this window
ULONG_PTR dwMcdWindow;
//
// Reference counting and serialization.
//
// Count of things holding a pointer to this window.
LONG lUsers;
// All accesses to this window's data must occur under this lock.
CRITICAL_SECTION sem;
// Context that is currently holding this window's lock.
struct __GLGENcontextRec *gengc;
// Thread that is currently holding this window's lock and
// recursion count on this window's lock. This information may
// be in the critical section but to be cross-platform we
// maintain it ourselves.
DWORD owningThread;
DWORD lockRecursion;
} GLGENwindow;
/*
* GLGENwindow::ulFlags
*
* GLGENWIN_DIRECTSCREEN Direct screen access locks are held
* GLGENWIN_OTHERPROCESS The window handle is from another process
* GLGENWIN_DRIVERSET pvDriver has been set
*/
#define GLGENWIN_DIRECTSCREEN 0x00000001
#define GLGENWIN_OTHERPROCESS 0x00000002
#define GLGENWIN_DRIVERSET 0x00000004
/*
* Global header node for the linked list of GLGENwindow structures.
* The semaphore in the header node is used as the list access semaphore.
*/
extern GLGENwindow gwndHeader;
/*
* GLGENwindow list management functions.
*/
// Retrieves the GLGENwindow that corresponds to the specified HWND.
// NULL if failure.
// Increments lUsers
extern GLGENwindow * APIENTRY pwndGetFromHWND(HWND hwnd);
// Retrieves the GLGENwindow that corresponds to the specified HDC.
// NULL if failure.
// Increments lUsers
extern GLGENwindow * APIENTRY pwndGetFromMemDC(HDC hdc);
// Retrieves the GLGENwindow that corresponds to the specified DDraw surface.
// NULL if failure.
// Increments lUsers
GLGENwindow *pwndGetFromDdraw(LPDIRECTDRAWSURFACE pdds);
// General retrieval
// NULL if failure.
// Increments lUsers
extern GLGENwindow * APIENTRY pwndGetFromID(GLWINDOWID *pgwid);
// Allocates a new GLGENwindow structure and puts it into the linked list.
// NULL if failure.
// Starts lUsers at 1
extern GLGENwindow * APIENTRY pwndNew(GLGENwindow *pwndInit);
// Creates a GLGENwindow for the given information
extern GLGENwindow * APIENTRY CreatePwnd(GLWINDOWID *pgwid, int ipfd,
int ipfdDevMax, DWORD dwObjectType,
RECTL *prcl, BOOL *pbNew);
// Cleans up resources for a GLGENwindow
// NULL if success; pointer to GLGENwindow structure if failure.
extern GLGENwindow * APIENTRY pwndFree(GLGENwindow *pwnd,
BOOL bExitProcess);
// Removes an active GLGENwindow from the window list and
// waits for a safe time to clean it up, then pwndFrees it
extern void APIENTRY pwndCleanup(GLGENwindow *pwnd);
// Decrements lUsers
#if DBG
extern void APIENTRY pwndRelease(GLGENwindow *pwnd);
#else
#define pwndRelease(pwnd) \
InterlockedDecrement(&(pwnd)->lUsers)
#endif
// Unlocks pwnd->sem and does pwndRelease
extern void APIENTRY pwndUnlock(GLGENwindow *pwnd,
struct __GLGENcontextRec *gengc);
// Removes and deletes all GLGENwindow structures from the linked list.
// Must *ONLY* be called from process detach (GLUnInitializeProcess).
extern VOID APIENTRY vCleanupWnd(VOID);
// Retrieves layer information for the specified layer of the pwnd.
// Allocates if necessary.
extern GLGENlayerInfo * APIENTRY plyriGet(GLGENwindow *pwnd, HDC hdc, int iLayer);
void APIENTRY WindowIdFromHdc(HDC hdc, GLWINDOWID *pgwid);
//
// Begin/end direct screen access
//
extern BOOL BeginDirectScreenAccess(struct __GLGENcontextRec *gengc,
GLGENwindow *pwnd,
PIXELFORMATDESCRIPTOR *ppfd);
extern VOID EndDirectScreenAccess(GLGENwindow *pwnd);
//
// Debugging support for tracking lock/unlock on a window.
//
#if DBG || defined(TRACK_WINCRIT)
// Don't use ASSERTOPENGL so this can be used on free builds.
#define ASSERT_WINCRIT(pwnd) \
if ((pwnd)->owningThread != GetCurrentThreadId()) \
{ \
DbgPrint("Window 0x%08lX owned by 0x%X, not 0x%X\n", \
(pwnd), (pwnd)->owningThread, GetCurrentThreadId()); \
DebugBreak(); \
}
#define ASSERT_NOT_WINCRIT(pwnd) \
if ((pwnd)->owningThread == GetCurrentThreadId()) \
{ \
DbgPrint("Window 0x%08lX already owned by 0x%X\n", \
(pwnd), (pwnd)->owningThread); \
DebugBreak(); \
}
// Asserts that the current thread can recursively take the given
// wincrit. For this to be true it must be unowned or owned by
// the same thread.
#define ASSERT_COMPATIBLE_WINCRIT(pwnd) \
if ((pwnd)->owningThread != 0 && \
(pwnd)->owningThread != GetCurrentThreadId()) \
{ \
DbgPrint("Window 0x%08lX owned by 0x%X, not 0x%X\n", \
(pwnd), (pwnd)->owningThread, GetCurrentThreadId()); \
DebugBreak(); \
}
#else
#define ASSERT_WINCRIT(pwnd)
#define ASSERT_NOT_WINCRIT(pwnd)
#define ASSERT_COMPATIBLE_WINCRIT(pwnd)
#endif
// Use both GC and non-GC forms so it's possible to write macros
// for both cases if we want to in the future.
void ENTER_WINCRIT_GC(GLGENwindow *pwnd, struct __GLGENcontextRec *gengc);
void LEAVE_WINCRIT_GC(GLGENwindow *pwnd, struct __GLGENcontextRec *gengc);
#define ENTER_WINCRIT(pwnd) ENTER_WINCRIT_GC(pwnd, NULL)
#define LEAVE_WINCRIT(pwnd) LEAVE_WINCRIT_GC(pwnd, NULL)
#endif //_GLGENWIN_H_