Merge branch 'mesa_7_6_branch'
[mesa.git] / src / mesa / drivers / windows / gldirect / dll_main.c
1 /****************************************************************************
2 *
3 * Mesa 3-D graphics library
4 * Direct3D Driver Interface
5 *
6 * ========================================================================
7 *
8 * Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved.
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
25 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 *
28 * ======================================================================
29 *
30 * Language: ANSI C
31 * Environment: Windows 9x (Win32)
32 *
33 * Description: Win32 DllMain functions.
34 *
35 ****************************************************************************/
36
37 // INITGUID must only be defined once.
38 // Don't put it in a shared header file!
39 // GLD3 uses dxguid.lib, so INITGUID must *not* be used!
40 #ifndef _USE_GLD3_WGL
41 #define INITGUID
42 #endif // _USE_GLD3_WGL
43
44 #include "dllmain.h"
45
46 //#include "snap/graphics.h"
47 //#include "drvlib/os/os.h"
48
49 #ifdef _USE_GLD3_WGL
50 typedef void (APIENTRY *LPDGLSPLASHSCREEN)(int, int, char*);
51 #include "gld_driver.h"
52 #endif
53
54 // ***********************************************************************
55
56 BOOL bInitialized = FALSE; // callback driver initialized?
57 BOOL bExited = FALSE; // callback driver exited this instance?
58 HINSTANCE hInstanceDll = NULL; // DLL instance handle
59
60 static BOOL bDriverValidated = FALSE; // prior validation status
61 static BOOL bSplashScreen = TRUE; // Splash Screen ?
62 static BOOL bValidINIFound = FALSE; // Have we found a valid INI file?
63
64 HHOOK hKeyHook = NULL; // global keyboard handler hook
65
66 // Multi-threaded support needs to be reflected in Mesa code. (DaveM)
67 int _gld_bMultiThreaded = FALSE;
68
69 // ***********************************************************************
70
71 DWORD dwLogging = 0; // Logging flag
72 DWORD dwDebugLevel = 0; // Log debug level
73
74 char szLogPath[_MAX_PATH] = {"\0"}; // Log file path
75 char szSNAPPath[_MAX_PATH] = {"\0"}; // SNAP driver path
76
77 #ifndef _USE_GLD3_WGL
78 DGL_wglFuncs wglFuncs = {
79 sizeof(DGL_wglFuncs),
80 DGL_ChoosePixelFormat,
81 DGL_CopyContext,
82 DGL_CreateContext,
83 DGL_CreateLayerContext,
84 DGL_DeleteContext,
85 DGL_DescribeLayerPlane,
86 DGL_DescribePixelFormat,
87 DGL_GetCurrentContext,
88 DGL_GetCurrentDC,
89 DGL_GetDefaultProcAddress,
90 DGL_GetLayerPaletteEntries,
91 DGL_GetPixelFormat,
92 DGL_GetProcAddress,
93 DGL_MakeCurrent,
94 DGL_RealizeLayerPalette,
95 DGL_SetLayerPaletteEntries,
96 DGL_SetPixelFormat,
97 DGL_ShareLists,
98 DGL_SwapBuffers,
99 DGL_SwapLayerBuffers,
100 DGL_UseFontBitmapsA,
101 DGL_UseFontBitmapsW,
102 DGL_UseFontOutlinesA,
103 DGL_UseFontOutlinesW,
104 };
105
106 DGL_mesaFuncs mesaFuncs = {
107 sizeof(DGL_mesaFuncs),
108 };
109 #endif // _USE_GLD3_WGL
110
111 // ***********************************************************************
112
113 typedef struct {
114 DWORD dwDriver; // 0=SciTech SW, 1=Direct3D SW, 2=Direct3D HW
115 BOOL bMipmapping; // 0=off, 1=on
116 BOOL bMultitexture; // 0=off, 1=on
117 BOOL bWaitForRetrace; // 0=off, 1=on
118 BOOL bFullscreenBlit; // 0=off, 1=on
119 BOOL bFastFPU; // 0=off, 1=on
120 BOOL bDirectDrawPersistant;// 0=off, 1=on
121 BOOL bPersistantBuffers; // 0=off, 1=on
122 DWORD dwLogging; // 0=off, 1=normal, 2=crash-proof
123 DWORD dwLoggingSeverity; // 0=all, 1=warnings+errors, 2=errors only
124 BOOL bMessageBoxWarnings;// 0=off, 1=on
125 BOOL bMultiThreaded; // 0=off, 1=on
126 BOOL bAppCustomizations; // 0=off, 1=on
127 BOOL bHotKeySupport; // 0=off, 1=on
128 BOOL bSplashScreen; // 0=off, 1=on
129
130 #ifdef _USE_GLD3_WGL
131 //
132 // New for GLDirect 3.0
133 //
134 DWORD dwAdapter; // DX8 adpater ordinal
135 DWORD dwTnL; // Transform & Lighting type
136 DWORD dwMultisample; // DX8 multisample type
137 #endif // _USE_GLD3_WGL
138 } INI_settings;
139
140 static INI_settings ini;
141
142 // ***********************************************************************
143
144 BOOL APIENTRY DGL_initDriver(
145 #ifdef _USE_GLD3_WGL
146 void)
147 {
148 #else
149 DGL_wglFuncs *lpWglFuncs,
150 DGL_mesaFuncs *lpMesaFuncs)
151 {
152 // Check for valid pointers
153 if ((lpWglFuncs == NULL) || (lpMesaFuncs == NULL))
154 return FALSE;
155
156 // Check for valid structs
157 if (lpWglFuncs->dwSize != sizeof(DGL_wglFuncs)) {
158 return FALSE;
159 }
160
161 // Check for valid structs
162 if (lpMesaFuncs->dwSize != sizeof(DGL_mesaFuncs)) {
163 return FALSE;
164 }
165
166 // Copy the Mesa functions
167 memcpy(&mesaFuncs, lpMesaFuncs, sizeof(DGL_mesaFuncs));
168
169 // Pass back the wgl functions
170 memcpy(lpWglFuncs, &wglFuncs, sizeof(DGL_wglFuncs));
171 #endif // _USE_GLD3_WGL
172
173 // Finally initialize the callback driver
174 if (!dglInitDriver())
175 return FALSE;
176
177 return TRUE;
178 };
179
180 // ***********************************************************************
181
182 BOOL ReadINIFile(
183 HINSTANCE hInstance)
184 {
185 char szModuleFilename[MAX_PATH];
186 char szSystemDirectory[MAX_PATH];
187 const char szSectionName[] = "Config";
188 char szINIFile[MAX_PATH];
189 int pos;
190
191 // Now using the DLL module handle. KeithH, 24/May/2000.
192 // Addendum: GetModuleFileName(NULL, ... returns process filename,
193 // GetModuleFileName(hModule, ... returns DLL filename,
194
195 // Get the dll path and filename.
196 GetModuleFileName(hInstance, &szModuleFilename[0], MAX_PATH); // NULL for current process
197 // Get the System directory.
198 GetSystemDirectory(&szSystemDirectory[0], MAX_PATH);
199
200 // Test to see if DLL is in system directory.
201 if (strnicmp(szModuleFilename, szSystemDirectory, strlen(szSystemDirectory))==0) {
202 // DLL *is* in system directory.
203 // Return FALSE to indicate that registry keys should be read.
204 return FALSE;
205 }
206
207 // Compose filename of INI file
208 strcpy(szINIFile, szModuleFilename);
209 pos = strlen(szINIFile);
210 while (szINIFile[pos] != '\\') {
211 pos--;
212 }
213 szINIFile[pos+1] = '\0';
214 // Use run-time DLL path for log file too
215 strcpy(szLogPath, szINIFile);
216 szLogPath[pos] = '\0';
217 // Complete full INI file path
218 strcat(szINIFile, "gldirect.ini");
219
220 // Read settings from private INI file.
221 // Note that defaults are contained in the calls.
222 ini.dwDriver = GetPrivateProfileInt(szSectionName, "dwDriver", 2, szINIFile);
223 ini.bMipmapping = GetPrivateProfileInt(szSectionName, "bMipmapping", 1, szINIFile);
224 ini.bMultitexture = GetPrivateProfileInt(szSectionName, "bMultitexture", 1, szINIFile);
225 ini.bWaitForRetrace = GetPrivateProfileInt(szSectionName, "bWaitForRetrace", 0, szINIFile);
226 ini.bFullscreenBlit = GetPrivateProfileInt(szSectionName, "bFullscreenBlit", 0, szINIFile);
227 ini.bFastFPU = GetPrivateProfileInt(szSectionName, "bFastFPU", 1, szINIFile);
228 ini.bDirectDrawPersistant = GetPrivateProfileInt(szSectionName, "bPersistantDisplay", 0, szINIFile);
229 ini.bPersistantBuffers = GetPrivateProfileInt(szSectionName, "bPersistantResources", 0, szINIFile);
230 ini.dwLogging = GetPrivateProfileInt(szSectionName, "dwLogging", 0, szINIFile);
231 ini.dwLoggingSeverity = GetPrivateProfileInt(szSectionName, "dwLoggingSeverity", 0, szINIFile);
232 ini.bMessageBoxWarnings = GetPrivateProfileInt(szSectionName, "bMessageBoxWarnings", 0, szINIFile);
233 ini.bMultiThreaded = GetPrivateProfileInt(szSectionName, "bMultiThreaded", 0, szINIFile);
234 ini.bAppCustomizations = GetPrivateProfileInt(szSectionName, "bAppCustomizations", 1, szINIFile);
235 ini.bHotKeySupport = GetPrivateProfileInt(szSectionName, "bHotKeySupport", 0, szINIFile);
236 ini.bSplashScreen = GetPrivateProfileInt(szSectionName, "bSplashScreen", 1, szINIFile);
237
238 #ifdef _USE_GLD3_WGL
239 // New for GLDirect 3.x
240 ini.dwAdapter = GetPrivateProfileInt(szSectionName, "dwAdapter", 0, szINIFile);
241 // dwTnL now defaults to zero (chooses TnL at runtime). KeithH
242 ini.dwTnL = GetPrivateProfileInt(szSectionName, "dwTnL", 0, szINIFile);
243 ini.dwMultisample = GetPrivateProfileInt(szSectionName, "dwMultisample", 0, szINIFile);
244 #endif
245
246 return TRUE;
247 }
248
249 // ***********************************************************************
250
251 BOOL dllReadRegistry(
252 HINSTANCE hInstance)
253 {
254 // Read settings from INI file, if available
255 bValidINIFound = FALSE;
256 if (ReadINIFile(hInstance)) {
257 const char *szRendering[3] = {
258 "SciTech Software Renderer",
259 "Direct3D MMX Software Renderer",
260 "Direct3D Hardware Renderer"
261 };
262 // Set globals
263 glb.bPrimary = 1;
264 glb.bHardware = (ini.dwDriver == 2) ? 1 : 0;
265 #ifndef _USE_GLD3_WGL
266 memset(&glb.ddGuid, 0, sizeof(glb.ddGuid));
267 glb.d3dGuid = (ini.dwDriver == 2) ? IID_IDirect3DHALDevice : IID_IDirect3DRGBDevice;
268 #endif // _USE_GLD3_WGL
269 strcpy(glb.szDDName, "Primary");
270 strcpy(glb.szD3DName, szRendering[ini.dwDriver]);
271 glb.dwRendering = ini.dwDriver;
272 glb.bUseMipmaps = ini.bMipmapping;
273 glb.bMultitexture = ini.bMultitexture;
274 glb.bWaitForRetrace = ini.bWaitForRetrace;
275 glb.bFullscreenBlit = ini.bFullscreenBlit;
276 glb.bFastFPU = ini.bFastFPU;
277 glb.bDirectDrawPersistant = ini.bDirectDrawPersistant;
278 glb.bPersistantBuffers = ini.bPersistantBuffers;
279 dwLogging = ini.dwLogging;
280 dwDebugLevel = ini.dwLoggingSeverity;
281 glb.bMessageBoxWarnings = ini.bMessageBoxWarnings;
282 glb.bMultiThreaded = ini.bMultiThreaded;
283 glb.bAppCustomizations = ini.bAppCustomizations;
284 glb.bHotKeySupport = ini.bHotKeySupport;
285 bSplashScreen = ini.bSplashScreen;
286 #ifdef _USE_GLD3_WGL
287 // New for GLDirect 3.x
288 glb.dwAdapter = ini.dwAdapter;
289 glb.dwDriver = ini.dwDriver;
290 glb.dwTnL = ini.dwTnL;
291 glb.dwMultisample = ini.dwMultisample;
292 #endif
293 bValidINIFound = TRUE;
294 return TRUE;
295 }
296 // Read settings from registry
297 else {
298 HKEY hReg;
299 DWORD cbValSize;
300 DWORD dwType = REG_SZ; // Registry data type for strings
301 BOOL bRegistryError;
302 BOOL bSuccess;
303
304 #define REG_READ_DWORD(a, b) \
305 cbValSize = sizeof(b); \
306 if (ERROR_SUCCESS != RegQueryValueEx( hReg, (a), \
307 NULL, NULL, (LPBYTE)&(b), &cbValSize )) \
308 bRegistryError = TRUE;
309
310 #define REG_READ_DEVICEID(a, b) \
311 cbValSize = MAX_DDDEVICEID_STRING; \
312 if(ERROR_SUCCESS != RegQueryValueEx(hReg, (a), 0, &dwType, \
313 (LPBYTE)&(b), &cbValSize)) \
314 bRegistryError = TRUE;
315
316 #define REG_READ_STRING(a, b) \
317 cbValSize = sizeof((b)); \
318 if(ERROR_SUCCESS != RegQueryValueEx(hReg, (a), 0, &dwType, \
319 (LPBYTE)&(b), &cbValSize)) \
320 bRegistryError = TRUE;
321
322 // Read settings from the registry.
323
324 // Open the registry key for the current user if it exists.
325 bSuccess = (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,
326 DIRECTGL_REG_SETTINGS_KEY,
327 0,
328 KEY_READ,
329 &hReg));
330 // Otherwise open the registry key for the local machine.
331 if (!bSuccess)
332 bSuccess = (ERROR_SUCCESS == RegOpenKeyEx(DIRECTGL_REG_KEY_ROOT,
333 DIRECTGL_REG_SETTINGS_KEY,
334 0,
335 KEY_READ,
336 &hReg));
337 if (!bSuccess)
338 return FALSE;
339
340 bRegistryError = FALSE;
341
342 REG_READ_DWORD(DIRECTGL_REG_SETTING_PRIMARY, glb.bPrimary);
343 REG_READ_DWORD(DIRECTGL_REG_SETTING_D3D_HW, glb.bHardware);
344 #ifndef _USE_GLD3_WGL
345 REG_READ_DWORD(DIRECTGL_REG_SETTING_DD_GUID, glb.ddGuid);
346 REG_READ_DWORD(DIRECTGL_REG_SETTING_D3D_GUID, glb.d3dGuid);
347 #endif // _USE_GLD3_WGL
348 REG_READ_DWORD(DIRECTGL_REG_SETTING_LOGGING, dwLogging);
349 REG_READ_DWORD(DIRECTGL_REG_SETTING_DEBUGLEVEL, dwDebugLevel);
350 REG_READ_DWORD(DIRECTGL_REG_SETTING_RENDERING, glb.dwRendering);
351 REG_READ_DWORD(DIRECTGL_REG_SETTING_MULTITEXTURE, glb.bMultitexture);
352 REG_READ_DWORD(DIRECTGL_REG_SETTING_WAITFORRETRACE, glb.bWaitForRetrace);
353 REG_READ_DWORD(DIRECTGL_REG_SETTING_FULLSCREENBLIT, glb.bFullscreenBlit);
354 REG_READ_DWORD(DIRECTGL_REG_SETTING_USEMIPMAPS, glb.bUseMipmaps);
355
356 REG_READ_DEVICEID(DIRECTGL_REG_SETTING_DD_NAME, glb.szDDName);
357 REG_READ_DEVICEID(DIRECTGL_REG_SETTING_D3D_NAME, glb.szD3DName);
358
359 REG_READ_DWORD(DIRECTGL_REG_SETTING_MSGBOXWARNINGS, glb.bMessageBoxWarnings);
360 REG_READ_DWORD(DIRECTGL_REG_SETTING_PERSISTDISPLAY, glb.bDirectDrawPersistant);
361 REG_READ_DWORD(DIRECTGL_REG_SETTING_PERSISTBUFFERS, glb.bPersistantBuffers);
362 REG_READ_DWORD(DIRECTGL_REG_SETTING_FASTFPU, glb.bFastFPU);
363 REG_READ_DWORD(DIRECTGL_REG_SETTING_HOTKEYS, glb.bHotKeySupport);
364 REG_READ_DWORD(DIRECTGL_REG_SETTING_MULTITHREAD, glb.bMultiThreaded);
365 REG_READ_DWORD(DIRECTGL_REG_SETTING_APPCUSTOM, glb.bAppCustomizations);
366 REG_READ_DWORD(DIRECTGL_REG_SETTING_SPLASHSCREEN, bSplashScreen);
367
368 #ifdef _USE_GLD3_WGL
369 // New for GLDirect 3.x
370 glb.dwDriver = glb.dwRendering;
371 REG_READ_DWORD(DIRECTGL_REG_SETTING_ADAPTER, glb.dwAdapter);
372 REG_READ_DWORD(DIRECTGL_REG_SETTING_TNL, glb.dwTnL);
373 REG_READ_DWORD(DIRECTGL_REG_SETTING_MULTISAMPLE, glb.dwMultisample);
374 #endif
375
376 RegCloseKey(hReg);
377
378 // Open the global registry key for GLDirect
379 bSuccess = (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
380 DIRECTGL_REG_SETTINGS_KEY,
381 0,
382 KEY_READ,
383 &hReg));
384 if (bSuccess) {
385 // Read the installation path for GLDirect
386 REG_READ_STRING("InstallLocation",szLogPath);
387 RegCloseKey(hReg);
388 }
389
390 if (bRegistryError || !bSuccess)
391 return FALSE;
392 else
393
394 return TRUE;
395
396 #undef REG_READ_DWORD
397 #undef REG_READ_DEVICEID
398 #undef REG_READ_STRING
399 }
400 }
401
402 // ***********************************************************************
403
404 BOOL dllWriteRegistry(
405 void )
406 {
407 HKEY hReg;
408 DWORD dwCreateDisposition, cbValSize;
409 BOOL bRegistryError = FALSE;
410
411 #define REG_WRITE_DWORD(a, b) \
412 cbValSize = sizeof(b); \
413 if (ERROR_SUCCESS != RegSetValueEx( hReg, (a), \
414 0, REG_DWORD, (LPBYTE)&(b), cbValSize )) \
415 bRegistryError = TRUE;
416
417 if (ERROR_SUCCESS == RegCreateKeyEx( DIRECTGL_REG_KEY_ROOT, DIRECTGL_REG_SETTINGS_KEY,
418 0, NULL, 0, KEY_WRITE, NULL, &hReg,
419 &dwCreateDisposition )) {
420 RegFlushKey(hReg); // Make sure keys are written to disk
421 RegCloseKey(hReg);
422 hReg = NULL;
423 }
424
425 if (bRegistryError)
426 return FALSE;
427 else
428 return TRUE;
429
430 #undef REG_WRITE_DWORD
431 }
432
433 // ***********************************************************************
434
435 void dglInitHotKeys(HINSTANCE hInstance)
436 {
437 // Hot-Key support at all?
438 if (!glb.bHotKeySupport)
439 return;
440
441 // Install global keyboard interceptor
442 hKeyHook = SetWindowsHookEx(WH_KEYBOARD, dglKeyProc, hInstance, 0);
443 }
444
445 // ***********************************************************************
446
447 void dglExitHotKeys(void)
448 {
449 // Hot-Key support at all?
450 if (!glb.bHotKeySupport)
451 return;
452
453 // Remove global keyboard interceptor
454 if (hKeyHook)
455 UnhookWindowsHookEx(hKeyHook);
456 hKeyHook = NULL;
457 }
458
459 // ***********************************************************************
460
461 // Note: This app-customization step must be performed in both the main
462 // OpenGL32 driver and the callback driver DLLs for multithreading option.
463 void dglSetAppCustomizations(void)
464 {
465 char szModuleFileName[MAX_PATH];
466 int iSize = MAX_PATH;
467
468 // Get the currently loaded EXE filename.
469 GetModuleFileName(NULL, &szModuleFileName[0], MAX_PATH); // NULL for current process
470 strupr(szModuleFileName);
471 iSize = strlen(szModuleFileName);
472
473 // Check for specific EXEs and adjust global settings accordingly
474
475 // NOTE: In GLD3.x "bDirectDrawPersistant" corresponds to IDirect3D8 and
476 // "bPersistantBuffers" corresponds to IDirect3DDevice8. KeithH
477
478 // Case 1: 3DStudio must be multi-threaded
479 // Added: Discreet GMAX (3DStudio MAX 4 for gamers. KeithH)
480 if (strstr(szModuleFileName, "3DSMAX.EXE")
481 || strstr(szModuleFileName, "3DSVIZ.EXE")
482 || strstr(szModuleFileName, "GMAX.EXE")) {
483 glb.bMultiThreaded = TRUE;
484 glb.bDirectDrawPersistant = FALSE;
485 glb.bPersistantBuffers = FALSE;
486 return;
487 }
488
489 // Case 2: Solid Edge must use pre-allocated resources for all GLRCs
490 if (strstr(szModuleFileName, "PART.EXE")
491 || strstr(szModuleFileName, "ASSEMBL.EXE")
492 || strstr(szModuleFileName, "DRAFT.EXE")
493 || strstr(szModuleFileName, "SMARTVW.EXE")
494 || strstr(szModuleFileName, "SMETAL.EXE")) {
495 glb.bMultiThreaded = FALSE;
496 glb.bDirectDrawPersistant = TRUE;
497 glb.bPersistantBuffers = FALSE;
498 return;
499 }
500
501 // Case 3: Sudden Depth creates and destroys GLRCs on paint commands
502 if (strstr(szModuleFileName, "SUDDEPTH.EXE")
503 || strstr(szModuleFileName, "SUDDEMO.EXE")) {
504 glb.bMultiThreaded = FALSE;
505 glb.bDirectDrawPersistant = TRUE;
506 glb.bPersistantBuffers = TRUE;
507 glb.bFullscreenBlit = TRUE;
508 return;
509 }
510
511 // Case 4: StereoGraphics test apps create and destroy GLRCs on paint commands
512 if (strstr(szModuleFileName, "REDBLUE.EXE")
513 || strstr(szModuleFileName, "DIAGNOSE.EXE")) {
514 glb.bMultiThreaded = FALSE;
515 glb.bDirectDrawPersistant = TRUE;
516 glb.bPersistantBuffers = TRUE;
517 return;
518 }
519
520 // Case 5: Pipes screen savers share multiple GLRCs for same window
521 if (strstr(szModuleFileName, "PIPES.SCR")
522 || (strstr(szModuleFileName, "PIPES") && strstr(szModuleFileName, ".SCR"))) {
523 glb.bMultiThreaded = FALSE;
524 glb.bDirectDrawPersistant = TRUE;
525 glb.bPersistantBuffers = TRUE;
526 return;
527 }
528
529 // Case 6: AutoVue uses sub-viewport ops which are temporarily broken in stereo window
530 if (strstr(szModuleFileName, "AVWIN.EXE")) {
531 glb.bMultiThreaded = FALSE;
532 glb.bDirectDrawPersistant = TRUE;
533 glb.bPersistantBuffers = TRUE;
534 return;
535 }
536 // Case 7: Quake3 is waiting for DDraw objects to be released at exit
537 if (strstr(szModuleFileName, "QUAKE")) {
538 glb.bMultiThreaded = FALSE;
539 glb.bDirectDrawPersistant = FALSE;
540 glb.bPersistantBuffers = FALSE;
541 glb.bFullscreenBlit = FALSE;
542 return;
543 }
544 // Case 8: Reflection GLX server is unable to switch contexts at run-time
545 if (strstr(szModuleFileName, "RX.EXE")) {
546 glb.bMultiThreaded = FALSE;
547 glb.bMessageBoxWarnings = FALSE;
548 return;
549 }
550 // Case 9: Original AutoCAD 2000 must share DDraw objects across GLRCs
551 if (strstr(szModuleFileName, "ACAD.EXE")) {
552 glb.bFastFPU = FALSE;
553 if (GetModuleHandle("wopengl6.hdi") != NULL) {
554 glb.bMultiThreaded = FALSE;
555 glb.bDirectDrawPersistant = TRUE;
556 glb.bPersistantBuffers = FALSE;
557 }
558 return;
559 }
560 }
561
562 // ***********************************************************************
563
564 BOOL dglInitDriver(void)
565 {
566 UCHAR szExeName[MAX_PATH];
567 const char *szRendering[] = {
568 "Mesa Software",
569 "Direct3D RGB SW",
570 "Direct3D HW",
571 };
572 static BOOL bWarnOnce = FALSE;
573
574 // Already initialized?
575 if (bInitialized)
576 return TRUE;
577
578 // Moved from DllMain DLL_PROCESS_ATTACH:
579
580 // (Re-)Init defaults
581 dglInitGlobals();
582
583 // Read registry or INI file settings
584 if (!dllReadRegistry(hInstanceDll)) {
585 if (!bWarnOnce)
586 MessageBox( NULL, "GLDirect has not been configured.\n\n"
587 "Please run the configuration program\n"
588 "before using GLDirect with applications.\n",
589 "GLDirect", MB_OK | MB_ICONWARNING);
590 bWarnOnce = TRUE;
591 return FALSE;
592 }
593
594 #ifdef _USE_GLD3_WGL
595 // Must do this as early as possible.
596 // Need to read regkeys/ini-file first though.
597 gldInitDriverPointers(glb.dwDriver);
598
599 // Create private driver globals
600 _gldDriver.CreatePrivateGlobals();
601 #endif
602 // Overide settings with application customizations
603 if (glb.bAppCustomizations)
604 dglSetAppCustomizations();
605
606 //#ifndef _USE_GLD3_WGL
607 // Set the global memory type to either sysmem or vidmem
608 glb.dwMemoryType = glb.bHardware ? DDSCAPS_VIDEOMEMORY : DDSCAPS_SYSTEMMEMORY;
609 //#endif
610
611 // Multi-threaded support overides persistant display support
612 if (glb.bMultiThreaded)
613 glb.bDirectDrawPersistant = glb.bPersistantBuffers = FALSE;
614
615 // Multi-threaded support needs to be reflected in Mesa code. (DaveM)
616 _gld_bMultiThreaded = glb.bMultiThreaded;
617
618 // Start logging
619 ddlogPathOption(szLogPath);
620 ddlogWarnOption(glb.bMessageBoxWarnings);
621 ddlogOpen((DDLOG_loggingMethodType)dwLogging,
622 (DDLOG_severityType)dwDebugLevel);
623
624 // Obtain the name of the calling app
625 ddlogMessage(DDLOG_SYSTEM, "Driver : SciTech GLDirect 4.0\n");
626 GetModuleFileName(NULL, szExeName, sizeof(szExeName));
627 ddlogPrintf(DDLOG_SYSTEM, "Executable : %s", szExeName);
628
629 ddlogPrintf(DDLOG_SYSTEM, "DirectDraw device: %s", glb.szDDName);
630 ddlogPrintf(DDLOG_SYSTEM, "Direct3D driver : %s", glb.szD3DName);
631
632 ddlogPrintf(DDLOG_SYSTEM, "Rendering type : %s", szRendering[glb.dwRendering]);
633
634 ddlogPrintf(DDLOG_SYSTEM, "Multithreaded : %s", glb.bMultiThreaded ? "Enabled" : "Disabled");
635 ddlogPrintf(DDLOG_SYSTEM, "Display resources: %s", glb.bDirectDrawPersistant ? "Persistant" : "Instanced");
636 ddlogPrintf(DDLOG_SYSTEM, "Buffer resources : %s", glb.bPersistantBuffers ? "Persistant" : "Instanced");
637
638 dglInitContextState();
639 dglBuildPixelFormatList();
640 //dglBuildTextureFormatList();
641
642 // D3D callback driver is now successfully initialized
643 bInitialized = TRUE;
644 // D3D callback driver is now ready to be exited
645 bExited = FALSE;
646
647 return TRUE;
648 }
649
650 // ***********************************************************************
651
652 void dglExitDriver(void)
653 {
654
655 // Only need to clean up once per instance:
656 // May be called implicitly from DLL_PROCESS_DETACH,
657 // or explicitly from DGL_exitDriver().
658 if (bExited)
659 return;
660 bExited = TRUE;
661
662 // DDraw objects may be invalid when DLL unloads.
663 __try {
664
665 // Clean-up sequence (moved from DLL_PROCESS_DETACH)
666 #ifndef _USE_GLD3_WGL
667 dglReleaseTextureFormatList();
668 #endif
669 dglReleasePixelFormatList();
670 dglDeleteContextState();
671
672 #ifdef _USE_GLD3_WGL
673 _gldDriver.DestroyPrivateGlobals();
674 #endif
675
676 }
677 __except(EXCEPTION_EXECUTE_HANDLER) {
678 ddlogPrintf(DDLOG_WARN, "Exception raised in dglExitDriver.");
679 }
680
681 // Close the log file
682 ddlogClose();
683 }
684
685 // ***********************************************************************
686
687 int WINAPI DllMain(
688 HINSTANCE hInstance,
689 DWORD fdwReason,
690 PVOID pvReserved)
691 {
692 switch (fdwReason) {
693 case DLL_PROCESS_ATTACH:
694 // Cache DLL instance handle
695 hInstanceDll = hInstance;
696
697 // Flag that callback driver has yet to be initialized
698 bInitialized = bExited = FALSE;
699
700 #ifndef _USE_GLD3_WGL
701 // Init internal Mesa function pointers
702 memset(&mesaFuncs, 0, sizeof(DGL_mesaFuncs));
703 #endif // _USE_GLD3_WGL
704
705 // Init defaults
706 dglInitGlobals();
707
708 // Defer rest of DLL initialization to 1st WGL function call
709 break;
710
711 case DLL_PROCESS_DETACH:
712 // Call exit clean-up sequence
713 dglExitDriver();
714 break;
715 }
716
717 return TRUE;
718 }
719
720 // ***********************************************************************
721
722 void APIENTRY DGL_exitDriver(void)
723 {
724 // Call exit clean-up sequence
725 dglExitDriver();
726 }
727
728 // ***********************************************************************
729
730 void APIENTRY DGL_reinitDriver(void)
731 {
732 // Force init sequence again
733 bInitialized = bExited = FALSE;
734 dglInitDriver();
735 }
736
737 // ***********************************************************************
738
739 int WINAPI DllInitialize(
740 HINSTANCE hInstance,
741 DWORD fdwReason,
742 PVOID pvReserved)
743 {
744 // Some Watcom compiled executables require this.
745 return DllMain(hInstance, fdwReason, pvReserved);
746 }
747
748 // ***********************************************************************
749
750 void DGL_LoadSplashScreen(int piReg, char* pszUser)
751 {
752 HINSTANCE hSplashDll = NULL;
753 LPDGLSPLASHSCREEN dglSplashScreen = NULL;
754 static BOOL bOnce = FALSE;
755 static int iReg = 0;
756 static char szUser[255] = {"\0"};
757
758 // Display splash screen at all?
759 if (!bSplashScreen)
760 return;
761
762 // Only display splash screen once
763 if (bOnce)
764 return;
765 bOnce = TRUE;
766
767 // Make local copy of string for passing to DLL
768 if (pszUser)
769 strcpy(szUser, pszUser);
770 iReg = piReg;
771
772 // Load Splash Screen DLL
773 // (If it fails to load for any reason, we don't care...)
774 hSplashDll = LoadLibrary("gldsplash.dll");
775 if (hSplashDll) {
776 // Execute the Splash Screen function
777 dglSplashScreen = (LPDGLSPLASHSCREEN)GetProcAddress(hSplashDll, "GLDSplashScreen");
778 if (dglSplashScreen)
779 (*dglSplashScreen)(1, iReg, szUser);
780 // Don't unload the DLL since splash screen dialog is modeless now
781 }
782 }
783
784 // ***********************************************************************
785
786 BOOL dglValidate()
787 {
788 char *szCaption = "SciTech GLDirect Driver";
789 UINT uType = MB_OK | MB_ICONEXCLAMATION;
790
791 #ifdef _USE_GLD3_WGL
792 // (Re)build pixelformat list
793 if (glb.bPixelformatsDirty)
794 _gldDriver.BuildPixelformatList();
795 #endif
796
797 // Check to see if we have already validated
798 if (bDriverValidated && bInitialized)
799 return TRUE;
800
801 // Since all (most) the WGL functions must be validated at this point,
802 // this also insure that the callback driver is completely initialized.
803 if (!bInitialized)
804 if (!dglInitDriver()) {
805 MessageBox(NULL,
806 "The GLDirect driver could not initialize.\n\n"
807 "Please run the configuration program to\n"
808 "properly configure the driver, or else\n"
809 "re-run the installation program.", szCaption, uType);
810 _exit(1); // Bail
811 }
812
813 return TRUE;
814 }
815
816 // ***********************************************************************
817