2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: lib/opengl32/icdload.c
5 * PURPOSE: OpenGL32 lib, ICD dll loader
12 WINE_DEFAULT_DEBUG_CHANNEL(opengl32
);
14 struct Drv_Opengl_Info
16 DWORD Version
; /*!< Driver interface version */
17 DWORD DriverVersion
; /*!< Driver version */
18 WCHAR DriverName
[256]; /*!< Driver name */
21 static CRITICAL_SECTION icdload_cs
= {NULL
, -1, 0, 0, 0, 0};
22 static struct ICD_Data
* ICD_Data_List
= NULL
;
23 static const WCHAR OpenGLDrivers_Key
[] = L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers";
25 static void APIENTRY
wglSetCurrentValue(PVOID value
)
27 IntSetCurrentICDPrivate(value
);
30 static PVOID APIENTRY
wglGetCurrentValue()
32 return IntGetCurrentICDPrivate();
35 static DHGLRC
wglGetDHGLRC(struct wgl_context
* context
)
37 return context
->dhglrc
;
40 /* Retrieves the ICD data (driver version + relevant DLL entry points) for a device context */
41 struct ICD_Data
* IntGetIcdData(HDC hdc
)
44 DWORD dwInput
, dwValueType
, Version
, DriverVersion
, Flags
;
45 struct Drv_Opengl_Info DrvInfo
;
46 struct ICD_Data
* data
;
48 WCHAR DllName
[MAX_PATH
];
49 BOOL (WINAPI
*DrvValidateVersion
)(DWORD
);
50 void (WINAPI
*DrvSetCallbackProcs
)(int nProcs
, PROC
* pProcs
);
52 /* First, see if the driver supports this */
53 dwInput
= OPENGL_GETINFO
;
63 /* Driver doesn't support opengl */
67 /* Query for the ICD DLL name and version */
78 ERR("Driver claims to support OPENGL_GETINFO escape code, but doesn't.\n");
82 /* Protect the list while we are loading*/
83 EnterCriticalSection(&icdload_cs
);
85 /* Search for it in the list of already loaded modules */
89 if(!_wcsicmp(data
->DriverName
, DrvInfo
.DriverName
))
92 TRACE("Found already loaded %p.\n", data
);
93 LeaveCriticalSection(&icdload_cs
);
99 /* It was still not loaded, look for it in the registry */
100 ret
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, OpenGLDrivers_Key
, 0, KEY_READ
, &OglKey
);
101 if(ret
!= ERROR_SUCCESS
)
103 ERR("Failed to open the OpenGLDrivers key.\n");
106 ret
= RegOpenKeyExW(OglKey
, DrvInfo
.DriverName
, 0, KEY_READ
, &DrvKey
);
107 if(ret
!= ERROR_SUCCESS
)
109 /* Some driver installer just provide the DLL name, like the Matrox G400 */
110 TRACE("No driver subkey for %S, trying to get DLL name directly.\n", DrvInfo
.DriverName
);
111 dwInput
= sizeof(DllName
);
112 ret
= RegQueryValueExW(OglKey
, DrvInfo
.DriverName
, 0, &dwValueType
, (LPBYTE
)DllName
, &dwInput
);
113 if((ret
!= ERROR_SUCCESS
) || (dwValueType
!= REG_SZ
))
115 ERR("Unable to get ICD DLL name!.\n");
119 Version
= DriverVersion
= Flags
= 0;
120 TRACE("DLL name is %S.\n", DllName
);
124 /* The driver have a subkey for the ICD */
125 TRACE("Querying details from registry for %S.\n", DrvInfo
.DriverName
);
126 dwInput
= sizeof(DllName
);
127 ret
= RegQueryValueExW(DrvKey
, L
"Dll", 0, &dwValueType
, (LPBYTE
)DllName
, &dwInput
);
128 if((ret
!= ERROR_SUCCESS
) || (dwValueType
!= REG_SZ
))
130 ERR("Unable to get ICD DLL name!.\n");
136 dwInput
= sizeof(Version
);
137 ret
= RegQueryValueExW(DrvKey
, L
"Version", 0, &dwValueType
, (LPBYTE
)&Version
, &dwInput
);
138 if((ret
!= ERROR_SUCCESS
) || (dwValueType
!= REG_DWORD
))
140 WARN("No version in driver subkey\n");
142 else if(Version
!= DrvInfo
.Version
)
144 ERR("Version mismatch between registry (%lu) and display driver (%lu).\n", Version
, DrvInfo
.Version
);
150 dwInput
= sizeof(DriverVersion
);
151 ret
= RegQueryValueExW(DrvKey
, L
"DriverVersion", 0, &dwValueType
, (LPBYTE
)&DriverVersion
, &dwInput
);
152 if((ret
!= ERROR_SUCCESS
) || (dwValueType
!= REG_DWORD
))
154 WARN("No driver version in driver subkey\n");
156 else if(DriverVersion
!= DrvInfo
.DriverVersion
)
158 ERR("Driver version mismatch between registry (%lu) and display driver (%lu).\n", DriverVersion
, DrvInfo
.DriverVersion
);
164 dwInput
= sizeof(Flags
);
165 ret
= RegQueryValueExW(DrvKey
, L
"Flags", 0, &dwValueType
, (LPBYTE
)&Flags
, &dwInput
);
166 if((ret
!= ERROR_SUCCESS
) || (dwValueType
!= REG_DWORD
))
168 WARN("No driver version in driver subkey\n");
174 TRACE("DLL name is %S, Version %lx, DriverVersion %lx, Flags %lx.\n", DllName
, Version
, DriverVersion
, Flags
);
176 /* No need for this anymore */
179 /* So far so good, allocate data */
180 data
= HeapAlloc(GetProcessHeap(), 0, sizeof(*data
));
183 ERR("Unable to allocate ICD data!\n");
187 /* Load the library */
188 data
->hModule
= LoadLibraryW(DllName
);
191 ERR("Could not load the ICD DLL: %S.\n", DllName
);
192 HeapFree(GetProcessHeap(), 0, data
);
198 * Validate version, if needed.
199 * Some drivers (at least VBOX), initialize stuff upon this call.
201 DrvValidateVersion
= (void*)GetProcAddress(data
->hModule
, "DrvValidateVersion");
202 if(DrvValidateVersion
)
204 if(!DrvValidateVersion(DrvInfo
.DriverVersion
))
206 ERR("DrvValidateVersion failed!.\n");
211 /* Pass the callbacks */
212 DrvSetCallbackProcs
= (void*)GetProcAddress(data
->hModule
, "DrvSetCallbackProcs");
213 if(DrvSetCallbackProcs
)
215 PROC callbacks
[] = {(PROC
)wglGetCurrentValue
,
216 (PROC
)wglSetCurrentValue
,
218 DrvSetCallbackProcs(3, callbacks
);
221 /* Get the DLL exports */
222 #define DRV_LOAD(x) do \
224 data->x = (void*)GetProcAddress(data->hModule, #x); \
226 ERR("%S lacks " #x "!\n", DllName); \
230 DRV_LOAD(DrvCopyContext
);
231 DRV_LOAD(DrvCreateContext
);
232 DRV_LOAD(DrvCreateLayerContext
);
233 DRV_LOAD(DrvDeleteContext
);
234 DRV_LOAD(DrvDescribeLayerPlane
);
235 DRV_LOAD(DrvDescribePixelFormat
);
236 DRV_LOAD(DrvGetLayerPaletteEntries
);
237 DRV_LOAD(DrvGetProcAddress
);
238 DRV_LOAD(DrvReleaseContext
);
239 DRV_LOAD(DrvRealizeLayerPalette
);
240 DRV_LOAD(DrvSetContext
);
241 DRV_LOAD(DrvSetLayerPaletteEntries
);
242 DRV_LOAD(DrvSetPixelFormat
);
243 DRV_LOAD(DrvShareLists
);
244 DRV_LOAD(DrvSwapBuffers
);
245 DRV_LOAD(DrvSwapLayerBuffers
);
248 /* Copy the DriverName */
249 wcscpy(data
->DriverName
, DrvInfo
.DriverName
);
252 data
->next
= ICD_Data_List
;
253 ICD_Data_List
= data
;
255 TRACE("Returning %p.\n", data
);
258 /* Unlock and return */
259 LeaveCriticalSection(&icdload_cs
);
263 LeaveCriticalSection(&icdload_cs
);
264 FreeLibrary(data
->hModule
);
265 HeapFree(GetProcessHeap(), 0, data
);