|
|
/******************************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_
|