1 /****************************************************************************
3 * SciTech Nucleus Graphics Architecture
5 * Copyright (C) 1991-1998 SciTech Software, Inc.
8 * ======================================================================
9 * |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
11 * |This copyrighted computer code contains proprietary technology |
12 * |owned by SciTech Software, Inc., located at 505 Wall Street, |
13 * |Chico, CA 95928 USA (http://www.scitechsoft.com). |
15 * |The contents of this file are subject to the SciTech Nucleus |
16 * |License; you may *not* use this file or related software except in |
17 * |compliance with the License. You may obtain a copy of the License |
18 * |at http://www.scitechsoft.com/nucleus-license.txt |
20 * |Software distributed under the License is distributed on an |
21 * |"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
22 * |implied. See the License for the specific language governing |
23 * |rights and limitations under the License. |
25 * |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
26 * ======================================================================
31 * Description: OS specific Nucleus Graphics Architecture services for
32 * the Win32 operating system environments.
34 ****************************************************************************/
42 #define WIN32_LEAN_AND_MEAN
45 /*------------------------- Global Variables ------------------------------*/
47 #define DLL_NAME "nga_w32.dll"
49 extern HANDLE _PM_hDevice;
50 static HMODULE hModDLL = NULL;
51 static ibool useRing0Driver = false;
52 static ibool haveRDTSC;
53 static GA_largeInteger countFreq;
55 /*-------------------------- Implementation -------------------------------*/
57 /****************************************************************************
59 Loads the shared "nga_w32.dll" library from disk and connects to it. This
60 library is *always* located in the same directory as the Nucleus
62 ****************************************************************************/
63 static ibool LoadSharedDLL(void)
65 char filename[PM_MAX_PATH];
66 char bpdpath[PM_MAX_PATH];
68 /* Check if we have already loaded the DLL */
73 /* Open the DLL file */
74 if (!PM_findBPD(DLL_NAME,bpdpath))
76 strcpy(filename,bpdpath);
77 strcat(filename,DLL_NAME);
78 if ((hModDLL = LoadLibrary(filename)) == NULL)
83 /****************************************************************************
85 path - Local path to the Nucleus driver files.
88 This function is used by the application program to override the location
89 of the Nucleus driver files that are loaded. Normally the loader code
90 will look in the system Nucleus directories first, then in the 'drivers'
91 directory relative to the current working directory, and finally relative
92 to the MGL_ROOT environment variable.
94 Note that for Win32 we also call into the loaded PMHELP device driver
95 as necessary to change the local Nucleus path for system wide Nucleus
97 ****************************************************************************/
98 void NAPI GA_setLocalPath(
102 DWORD outBuf[1],outCnt;
104 PM_setLocalBPDPath(path);
105 if (_PM_hDevice != INVALID_HANDLE_VALUE) {
106 inBuf[0] = (DWORD)path;
107 DeviceIoControl(_PM_hDevice, PMHELP_GASETLOCALPATH32,
108 inBuf, sizeof(inBuf), outBuf, sizeof(outBuf), &outCnt, NULL);
112 /****************************************************************************
114 Pointer to the system wide PM library imports, or the internal version if none
117 In order to support deploying new Nucleus drivers that may require updated
118 PM library functions, we check here to see if there is a system wide version
119 of the PM functions available. If so we return those functions for use with
120 the system wide Nucleus drivers, otherwise the compiled in version of the PM
121 library is used with the application local version of Nucleus.
122 ****************************************************************************/
123 PM_imports * NAPI GA_getSystemPMImports(void)
126 PM_imports * (NAPIP _GA_getSystemPMImports)(void);
128 if (LoadSharedDLL()) {
129 /* Note that Visual C++ build DLL's with only a single underscore in front
130 * of the exported name while Watcom C provides two of them. We check for
131 * both to allow working with either compiled DLL.
133 if ((_GA_getSystemPMImports = (void*)GetProcAddress(hModDLL,"_GA_getSystemPMImports")) != NULL) {
134 if ((_GA_getSystemPMImports = (void*)GetProcAddress(hModDLL,"__GA_getSystemPMImports")) != NULL) {
135 pmImp = _GA_getSystemPMImports();
136 memcpy(&_PM_imports,pmImp,MIN(_PM_imports.dwSize,pmImp->dwSize));
144 /****************************************************************************
146 gaExp - Place to store the exported functions
147 shared - True if connecting to the shared, global Nucleus driver
150 For Win32 if we are connecting to the shared, global Nucleus driver (loaded
151 at ring 0) then we need to load a special nga_w32.dll library which contains
152 thunks to call down into the Ring 0 device driver as necessary. If we are
153 connecting to the application local Nucleus drivers (ie: Nucleus on DirectDraw
154 emulation layer) then we do nothing here.
155 ****************************************************************************/
156 ibool NAPI GA_getSharedExports(
161 GA_exports * (NAPIP _GA_getSystemGAExports)(void);
163 useRing0Driver = false;
165 if (!LoadSharedDLL())
166 PM_fatalError("Unable to load " DLL_NAME "!");
167 if ((_GA_getSystemGAExports = (void*)GetProcAddress(hModDLL,"_GA_getSystemGAExports")) == NULL)
168 if ((_GA_getSystemGAExports = (void*)GetProcAddress(hModDLL,"__GA_getSystemGAExports")) == NULL)
169 PM_fatalError("Unable to load " DLL_NAME "!");
170 exp = _GA_getSystemGAExports();
171 memcpy(gaExp,exp,MIN(gaExp->dwSize,exp->dwSize));
172 useRing0Driver = true;
179 /****************************************************************************
181 Nothing special for this OS
182 ****************************************************************************/
183 ibool NAPI GA_queryFunctions(
188 static ibool (NAPIP _GA_queryFunctions)(GA_devCtx *dc,N_uint32 id,void _FAR_ *funcs) = NULL;
190 if (useRing0Driver) {
191 /* Call the version in nga_w32.dll if it is loaded */
192 if (!_GA_queryFunctions) {
193 if ((_GA_queryFunctions = (void*)GetProcAddress(hModDLL,"_GA_queryFunctions")) == NULL)
194 if ((_GA_queryFunctions = (void*)GetProcAddress(hModDLL,"__GA_queryFunctions")) == NULL)
195 PM_fatalError("Unable to get exports from " DLL_NAME "!");
197 return _GA_queryFunctions(dc,id,funcs);
199 return __GA_exports.GA_queryFunctions(dc,id,funcs);
202 /****************************************************************************
204 Nothing special for this OS
205 ****************************************************************************/
206 ibool NAPI REF2D_queryFunctions(
211 static ibool (NAPIP _REF2D_queryFunctions)(REF2D_driver *ref2d,N_uint32 id,void _FAR_ *funcs) = NULL;
213 if (useRing0Driver) {
214 /* Call the version in nga_w32.dll if it is loaded */
215 if (!_REF2D_queryFunctions) {
216 if ((_REF2D_queryFunctions = (void*)GetProcAddress(hModDLL,"_REF2D_queryFunctions")) == NULL)
217 if ((_REF2D_queryFunctions = (void*)GetProcAddress(hModDLL,"__REF2D_queryFunctions")) == NULL)
218 PM_fatalError("Unable to get exports from " DLL_NAME "!");
220 return _REF2D_queryFunctions(ref2d,id,funcs);
222 return __GA_exports.REF2D_queryFunctions(ref2d,id,funcs);
226 /****************************************************************************
228 This function initialises the high precision timing functions for the
229 Nucleus loader library.
230 ****************************************************************************/
231 ibool NAPI GA_TimerInit(void)
233 if (_GA_haveCPUID() && (_GA_getCPUIDFeatures() & CPU_HaveRDTSC) != 0) {
237 else if (QueryPerformanceFrequency((LARGE_INTEGER*)&countFreq)) {
244 /****************************************************************************
246 This function reads the high resolution timer.
247 ****************************************************************************/
248 void NAPI GA_TimerRead(
249 GA_largeInteger *value)
252 _GA_readTimeStamp(value);
254 QueryPerformanceCounter((LARGE_INTEGER*)value);