323 lines
9.4 KiB
C
323 lines
9.4 KiB
C
/******************************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_
|