📄 dglcontext.c
字号:
/****************************************************************************** Mesa 3-D graphics library* Direct3D Driver Interface** ========================================================================** Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved.** Permission is hereby granted, free of charge, to any person obtaining a* copy of this software and associated documentation files (the "Software"),* to deal in the Software without restriction, including without limitation* the rights to use, copy, modify, merge, publish, distribute, sublicense,* and/or sell copies of the Software, and to permit persons to whom the* Software is furnished to do so, subject to the following conditions:** The above copyright notice and this permission notice shall be included* in all copies or substantial portions of the Software.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL* SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE* SOFTWARE.** ======================================================================** Language: ANSI C* Environment: Windows 9x (Win32)** Description: Context handling.*****************************************************************************/#include "dglcontext.h"// Get compile errors without this. KeithH//#include "scitech.h" // ibool, etc.#ifdef _USE_GLD3_WGL#include "gld_driver.h"extern void _gld_mesa_warning(GLcontext *, char *);extern void _gld_mesa_fatal(GLcontext *, char *);#endif // _USE_GLD3_WGL// TODO: Clean out old DX6-specific code from GLD 2.x CAD driver// if it is no longer being built as part of GLDirect. (DaveM)// ***********************************************************************#define GLDERR_NONE 0#define GLDERR_MEM 1#define GLDERR_DDRAW 2#define GLDERR_D3D 3#define GLDERR_BPP 4char szResourceWarning[] ="GLDirect does not have enough video memory resources\n""to support the requested OpenGL rendering context.\n\n""You may have to reduce the current display resolution\n""to obtain satisfactory OpenGL performance.\n";char szDDrawWarning[] ="GLDirect is unable to initialize DirectDraw for the\n""requested OpenGL rendering context.\n\n""You will have to check the DirectX control panel\n""for further information.\n";char szD3DWarning[] ="GLDirect is unable to initialize Direct3D for the\n""requested OpenGL rendering context.\n\n""You may have to change the display mode resolution\n""color depth or check the DirectX control panel for\n""further information.\n";char szBPPWarning[] ="GLDirect is unable to use the selected color depth for\n""the requested OpenGL rendering context.\n\n""You will have to change the display mode resolution\n""color depth with the Display Settings control panel.\n";int nContextError = GLDERR_NONE;// ***********************************************************************#define VENDORID_ATI 0x1002static DWORD devATIRagePro[] = { 0x4742, // 3D RAGE PRO BGA AGP 1X/2X 0x4744, // 3D RAGE PRO BGA AGP 1X only 0x4749, // 3D RAGE PRO BGA PCI 33 MHz 0x4750, // 3D RAGE PRO PQFP PCI 33 MHz 0x4751, // 3D RAGE PRO PQFP PCI 33 MHz limited 3D 0x4C42, // 3D RAGE LT PRO BGA-312 AGP 133 MHz 0x4C44, // 3D RAGE LT PRO BGA-312 AGP 66 MHz 0x4C49, // 3D RAGE LT PRO BGA-312 PCI 33 MHz 0x4C50, // 3D RAGE LT PRO BGA-256 PCI 33 MHz 0x4C51, // 3D RAGE LT PRO BGA-256 PCI 33 MHz limited 3D};static DWORD devATIRageIIplus[] = { 0x4755, // 3D RAGE II+ 0x4756, // 3D RAGE IIC PQFP PCI 0x4757, // 3D RAGE IIC BGA AGP 0x475A, // 3D RAGE IIC PQFP AGP 0x4C47, // 3D RAGE LT-G};// ***********************************************************************#ifndef _USE_GLD3_WGLextern DGL_mesaFuncs mesaFuncs;#endifextern DWORD dwLogging;#ifdef GLD_THREADS#pragma message("compiling DGLCONTEXT.C vars for multi-threaded support")CRITICAL_SECTION CriticalSection; // for serialized accessDWORD dwTLSCurrentContext = 0xFFFFFFFF; // TLS index for current contextDWORD dwTLSPixelFormat = 0xFFFFFFFF; // TLS index for current pixel format#endifHGLRC iCurrentContext = 0; // Index of current context (static)BOOL bContextReady = FALSE; // Context state ready ?DGL_ctx ctxlist[DGL_MAX_CONTEXTS]; // Context list// ***********************************************************************static BOOL bHaveWin95 = FALSE;static BOOL bHaveWinNT = FALSE;static BOOL bHaveWin2K = FALSE;/****************************************************************************REMARKS:Detect the installed OS type.****************************************************************************/static void DetectOS(void){ OSVERSIONINFO VersionInformation; LPOSVERSIONINFO lpVersionInformation = &VersionInformation; VersionInformation.dwOSVersionInfoSize = sizeof(VersionInformation); GetVersionEx(lpVersionInformation); switch (VersionInformation.dwPlatformId) { case VER_PLATFORM_WIN32_WINDOWS: bHaveWin95 = TRUE; bHaveWinNT = FALSE; bHaveWin2K = FALSE; break; case VER_PLATFORM_WIN32_NT: bHaveWin95 = FALSE; if (VersionInformation.dwMajorVersion <= 4) { bHaveWinNT = TRUE; bHaveWin2K = FALSE; } else { bHaveWinNT = FALSE; bHaveWin2K = TRUE; } break; case VER_PLATFORM_WIN32s: bHaveWin95 = FALSE; bHaveWinNT = FALSE; bHaveWin2K = FALSE; break; }}// ***********************************************************************HWND hWndEvent = NULL; // event monitor windowHWND hWndLastActive = NULL; // last active client windowLONG __stdcall GLD_EventWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);// ***********************************************************************// Checks if the HGLRC is valid in range of context list.BOOL dglIsValidContext( HGLRC a){ return ((int)a > 0 && (int)a <= DGL_MAX_CONTEXTS);}// ***********************************************************************// Convert a HGLRC to a pointer into the context list.DGL_ctx* dglGetContextAddress( const HGLRC a){ if (dglIsValidContext(a)) return &ctxlist[(int)a-1]; return NULL;}// ***********************************************************************// Return the current HGLRC (however it may be stored for multi-threading).HGLRC dglGetCurrentContext(void){#ifdef GLD_THREADS HGLRC hGLRC; // load from thread-specific instance if (glb.bMultiThreaded) { // protect against calls from arbitrary threads __try { hGLRC = (HGLRC)TlsGetValue(dwTLSCurrentContext); } __except(EXCEPTION_EXECUTE_HANDLER) { hGLRC = iCurrentContext; } } // load from global static var else { hGLRC = iCurrentContext; } return hGLRC;#else return iCurrentContext;#endif}// ***********************************************************************// Set the current HGLRC (however it may be stored for multi-threading).void dglSetCurrentContext(HGLRC hGLRC){#ifdef GLD_THREADS // store in thread-specific instance if (glb.bMultiThreaded) { // protect against calls from arbitrary threads __try { TlsSetValue(dwTLSCurrentContext, (LPVOID)hGLRC); } __except(EXCEPTION_EXECUTE_HANDLER) { iCurrentContext = hGLRC; } } // store in global static var else { iCurrentContext = hGLRC; }#else iCurrentContext = hGLRC;#endif}// ***********************************************************************// Return the current HDC only for a currently active HGLRC.HDC dglGetCurrentDC(void){ HGLRC hGLRC; DGL_ctx* lpCtx; hGLRC = dglGetCurrentContext(); if (hGLRC) { lpCtx = dglGetContextAddress(hGLRC); return lpCtx->hDC; } return 0;}// ***********************************************************************void dglInitContextState(){ int i; WNDCLASS wc;#ifdef GLD_THREADS // Allocate thread local storage indexes for current context and pixel format dwTLSCurrentContext = TlsAlloc(); dwTLSPixelFormat = TlsAlloc();#endif dglSetCurrentContext(NULL); // No current rendering context // Clear all context data ZeroMemory(ctxlist, sizeof(ctxlist[0]) * DGL_MAX_CONTEXTS); for (i=0; i<DGL_MAX_CONTEXTS; i++) ctxlist[i].bAllocated = FALSE; // Flag context as unused // This section of code crashes the dll in circumstances where the app // creates and destroys contexts./* // Register the class for our event monitor window wc.style = 0; wc.lpfnWndProc = GLD_EventWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = GetModuleHandle(NULL); wc.hIcon = LoadIcon(GetModuleHandle(NULL), IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = "GLDIRECT"; RegisterClass(&wc); // Create the non-visible window to monitor all broadcast messages hWndEvent = CreateWindowEx( WS_EX_TOOLWINDOW,"GLDIRECT","GLDIRECT",WS_POPUP, 0,0,0,0, NULL,NULL,GetModuleHandle(NULL),NULL);*/#ifdef GLD_THREADS // Create a critical section object for serializing access to // DirectDraw and DDStereo create/destroy functions in multiple threads if (glb.bMultiThreaded) InitializeCriticalSection(&CriticalSection);#endif // Context state is now initialized and ready bContextReady = TRUE;}// ***********************************************************************void dglDeleteContextState(){ int i; static BOOL bOnceIsEnough = FALSE; // Only call once, from either DGL_exitDriver(), or DLL_PROCESS_DETACH if (bOnceIsEnough) return; bOnceIsEnough = TRUE; for (i=0; i<DGL_MAX_CONTEXTS; i++) { if (ctxlist[i].bAllocated == TRUE) { ddlogPrintf(DDLOG_WARN, "** Context %i not deleted - cleaning up.", (i+1)); dglDeleteContext((HGLRC)(i+1)); } } // Context state is no longer ready bContextReady = FALSE; // If executed when DLL unloads, DDraw objects may be invalid. // So catch any page faults with this exception handler.__try { // Release final DirectDraw interfaces if (glb.bDirectDrawPersistant) {// RELEASE(glb.lpGlobalPalette);// RELEASE(glb.lpDepth4);// RELEASE(glb.lpBack4);// RELEASE(glb.lpPrimary4);// RELEASE(glb.lpDD4); }}__except(EXCEPTION_EXECUTE_HANDLER) { ddlogPrintf(DDLOG_WARN, "Exception raised in dglDeleteContextState.");} // Destroy our event monitor window if (hWndEvent) { DestroyWindow(hWndEvent); hWndEvent = hWndLastActive = NULL; }#ifdef GLD_THREADS // Destroy the critical section object if (glb.bMultiThreaded) DeleteCriticalSection(&CriticalSection); // Release thread local storage indexes for current HGLRC and pixel format TlsFree(dwTLSPixelFormat); TlsFree(dwTLSCurrentContext);#endif}// ***********************************************************************// Application Window message handler interceptionstatic LONG __stdcall dglWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ DGL_ctx* lpCtx = NULL; LONG lpfnWndProc = 0L; int i; HGLRC hGLRC; RECT rect; PAINTSTRUCT ps; BOOL bQuit = FALSE; BOOL bMain = FALSE; LONG rc; // Get the window's message handler *before* it is unhooked in WM_DESTROY // Is this the main window? if (hwnd == glb.hWndActive) { bMain = TRUE; lpfnWndProc = glb.lpfnWndProc; } // Search for DGL context matching window handle for (i=0; i<DGL_MAX_CONTEXTS; i++) { if (ctxlist[i].hWnd == hwnd) { lpCtx = &ctxlist[i]; lpfnWndProc = lpCtx->lpfnWndProc; break; } } // Not one of ours... if (!lpfnWndProc) return DefWindowProc(hwnd, msg, wParam, lParam); // Intercept messages amd process *before* passing on to window switch (msg) {#ifdef _USE_GLD3_WGL case WM_DISPLAYCHANGE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -