Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xwin / winengine.c
CommitLineData
a09e091a
JB
1/*
2 *Copyright (C) 2001-2004 Harold L Hunt II All Rights Reserved.
3 *
4 *Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 *"Software"), to deal in the Software without restriction, including
7 *without limitation the rights to use, copy, modify, merge, publish,
8 *distribute, sublicense, and/or sell copies of the Software, and to
9 *permit persons to whom the Software is furnished to do so, subject to
10 *the following conditions:
11 *
12 *The above copyright notice and this permission notice shall be
13 *included in all copies or substantial portions of the Software.
14 *
15 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR
19 *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20 *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 *Except as contained in this notice, the name of Harold L Hunt II
24 *shall not be used in advertising or otherwise to promote the sale, use
25 *or other dealings in this Software without prior written authorization
26 *from Harold L Hunt II.
27 *
28 * Authors: Harold L Hunt II
29 */
30
31#ifdef HAVE_XWIN_CONFIG_H
32#include <xwin-config.h>
33#endif
34#include "win.h"
35#include "winmsg.h"
36
37/*
38 * Global variables for function pointers into
39 * dynamically loaded libraries
40 */
41FARPROC g_fpDirectDrawCreate = NULL;
42FARPROC g_fpDirectDrawCreateClipper = NULL;
43
44/*
45 module handle for dynamically loaded directdraw library
46*/
47static HMODULE g_hmodDirectDraw = NULL;
48
49/*
50 * Detect engines supported by current Windows version
51 * DirectDraw version and hardware
52 */
53
54void
55winDetectSupportedEngines(void)
56{
57 OSVERSIONINFO osvi;
58
59 /* Initialize the engine support flags */
60 g_dwEnginesSupported = WIN_SERVER_SHADOW_GDI;
61
62#ifdef XWIN_NATIVEGDI
63 g_dwEnginesSupported |= WIN_SERVER_NATIVE_GDI;
64#endif
65
66 /* Get operating system version information */
67 ZeroMemory(&osvi, sizeof(osvi));
68 osvi.dwOSVersionInfoSize = sizeof(osvi);
69 GetVersionEx(&osvi);
70
71 /* Do we have DirectDraw? */
72 if (g_hmodDirectDraw != NULL) {
73 LPDIRECTDRAW lpdd = NULL;
74 LPDIRECTDRAW4 lpdd4 = NULL;
75 HRESULT ddrval;
76
77 /* Was the DirectDrawCreate function found? */
78 if (g_fpDirectDrawCreate == NULL) {
79 /* No DirectDraw support */
80 return;
81 }
82
83 /* DirectDrawCreate exists, try to call it */
84 /* Create a DirectDraw object, store the address at lpdd */
85 ddrval = (*g_fpDirectDrawCreate) (NULL, (void **) &lpdd, NULL);
86 if (FAILED(ddrval)) {
87 /* No DirectDraw support */
88 winErrorFVerb(2,
89 "winDetectSupportedEngines - DirectDraw not installed\n");
90 return;
91 }
92 else {
93 /* We have DirectDraw */
94 winErrorFVerb(2,
95 "winDetectSupportedEngines - DirectDraw installed, allowing ShadowDD\n");
96 g_dwEnginesSupported |= WIN_SERVER_SHADOW_DD;
97
98#ifdef XWIN_PRIMARYFB
99 /* Allow PrimaryDD engine if NT */
100 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
101 g_dwEnginesSupported |= WIN_SERVER_PRIMARY_DD;
102 winErrorFVerb(2,
103 "winDetectSupportedEngines - Windows NT, allowing PrimaryDD\n");
104 }
105#endif
106 }
107
108 /* Try to query for DirectDraw4 interface */
109 ddrval = IDirectDraw_QueryInterface(lpdd,
110 &IID_IDirectDraw4,
111 (LPVOID *) &lpdd4);
112 if (SUCCEEDED(ddrval)) {
113 /* We have DirectDraw4 */
114 winErrorFVerb(2,
115 "winDetectSupportedEngines - DirectDraw4 installed, allowing ShadowDDNL\n");
116 g_dwEnginesSupported |= WIN_SERVER_SHADOW_DDNL;
117 }
118
119 /* Cleanup DirectDraw interfaces */
120 if (lpdd4 != NULL)
121 IDirectDraw_Release(lpdd4);
122 if (lpdd != NULL)
123 IDirectDraw_Release(lpdd);
124 }
125
126 winErrorFVerb(2,
127 "winDetectSupportedEngines - Returning, supported engines %08x\n",
128 (unsigned int) g_dwEnginesSupported);
129}
130
131/*
132 * Set the engine type, depending on the engines
133 * supported for this screen, and whether the user
134 * suggested an engine type
135 */
136
137Bool
138winSetEngine(ScreenPtr pScreen)
139{
140 winScreenPriv(pScreen);
141 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
142 HDC hdc;
143 DWORD dwBPP;
144
145 /* Get a DC */
146 hdc = GetDC(NULL);
147 if (hdc == NULL) {
148 ErrorF("winSetEngine - Couldn't get an HDC\n");
149 return FALSE;
150 }
151
152 /*
153 * pScreenInfo->dwBPP may be 0 to indicate that the current screen
154 * depth is to be used. Thus, we must query for the current display
155 * depth here.
156 */
157 dwBPP = GetDeviceCaps(hdc, BITSPIXEL);
158
159 /* Release the DC */
160 ReleaseDC(NULL, hdc);
161 hdc = NULL;
162
163 /* ShadowGDI is the only engine that supports windowed PseudoColor */
164 if (dwBPP == 8 && !pScreenInfo->fFullScreen) {
165 winErrorFVerb(2,
166 "winSetEngine - Windowed && PseudoColor => ShadowGDI\n");
167 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI;
168
169 /* Set engine function pointers */
170 winSetEngineFunctionsShadowGDI(pScreen);
171 return TRUE;
172 }
173
174 /* ShadowGDI is the only engine that supports Multi Window Mode */
175 if (FALSE
176#ifdef XWIN_MULTIWINDOWEXTWM
177 || pScreenInfo->fMWExtWM
178#endif
179#ifdef XWIN_MULTIWINDOW
180 || pScreenInfo->fMultiWindow
181#endif
182 ) {
183 winErrorFVerb(2,
184 "winSetEngine - Multi Window or Rootless => ShadowGDI\n");
185 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI;
186
187 /* Set engine function pointers */
188 winSetEngineFunctionsShadowGDI(pScreen);
189 return TRUE;
190 }
191
192 /* If the user's choice is supported, we'll use that */
193 if (g_dwEnginesSupported & pScreenInfo->dwEnginePreferred) {
194 winErrorFVerb(2, "winSetEngine - Using user's preference: %d\n",
195 (int) pScreenInfo->dwEnginePreferred);
196 pScreenInfo->dwEngine = pScreenInfo->dwEnginePreferred;
197
198 /* Setup engine function pointers */
199 switch (pScreenInfo->dwEngine) {
200 case WIN_SERVER_SHADOW_GDI:
201 winSetEngineFunctionsShadowGDI(pScreen);
202 break;
203 case WIN_SERVER_SHADOW_DD:
204 winSetEngineFunctionsShadowDD(pScreen);
205 break;
206 case WIN_SERVER_SHADOW_DDNL:
207 winSetEngineFunctionsShadowDDNL(pScreen);
208 break;
209#ifdef XWIN_PRIMARYFB
210 case WIN_SERVER_PRIMARY_DD:
211 winSetEngineFunctionsPrimaryDD(pScreen);
212 break;
213#endif
214#ifdef XWIN_NATIVEGDI
215 case WIN_SERVER_NATIVE_GDI:
216 winSetEngineFunctionsNativeGDI(pScreen);
217 break;
218#endif
219 default:
220 FatalError("winSetEngine - Invalid engine type\n");
221 }
222 return TRUE;
223 }
224
225 /* ShadowDDNL has good performance, so why not */
226 if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DDNL) {
227 winErrorFVerb(2, "winSetEngine - Using Shadow DirectDraw NonLocking\n");
228 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DDNL;
229
230 /* Set engine function pointers */
231 winSetEngineFunctionsShadowDDNL(pScreen);
232 return TRUE;
233 }
234
235 /* ShadowDD is next in line */
236 if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DD) {
237 winErrorFVerb(2, "winSetEngine - Using Shadow DirectDraw\n");
238 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DD;
239
240 /* Set engine function pointers */
241 winSetEngineFunctionsShadowDD(pScreen);
242 return TRUE;
243 }
244
245 /* ShadowGDI is next in line */
246 if (g_dwEnginesSupported & WIN_SERVER_SHADOW_GDI) {
247 winErrorFVerb(2, "winSetEngine - Using Shadow GDI DIB\n");
248 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI;
249
250 /* Set engine function pointers */
251 winSetEngineFunctionsShadowGDI(pScreen);
252 return TRUE;
253 }
254
255 return TRUE;
256}
257
258/*
259 * Get procedure addresses for DirectDrawCreate and DirectDrawCreateClipper
260 */
261
262Bool
263winGetDDProcAddresses(void)
264{
265 Bool fReturn = TRUE;
266
267 /* Load the DirectDraw library */
268 g_hmodDirectDraw = LoadLibraryEx("ddraw.dll", NULL, 0);
269 if (g_hmodDirectDraw == NULL) {
270 ErrorF("winGetDDProcAddresses - Could not load ddraw.dll\n");
271 fReturn = TRUE;
272 goto winGetDDProcAddresses_Exit;
273 }
274
275 /* Try to get the DirectDrawCreate address */
276 g_fpDirectDrawCreate = GetProcAddress(g_hmodDirectDraw, "DirectDrawCreate");
277 if (g_fpDirectDrawCreate == NULL) {
278 ErrorF("winGetDDProcAddresses - Could not get DirectDrawCreate "
279 "address\n");
280 fReturn = TRUE;
281 goto winGetDDProcAddresses_Exit;
282 }
283
284 /* Try to get the DirectDrawCreateClipper address */
285 g_fpDirectDrawCreateClipper = GetProcAddress(g_hmodDirectDraw,
286 "DirectDrawCreateClipper");
287 if (g_fpDirectDrawCreateClipper == NULL) {
288 ErrorF("winGetDDProcAddresses - Could not get "
289 "DirectDrawCreateClipper address\n");
290 fReturn = FALSE;
291 goto winGetDDProcAddresses_Exit;
292 }
293
294 /*
295 * Note: Do not unload ddraw.dll here. Do it in GiveUp
296 */
297
298 winGetDDProcAddresses_Exit:
299 /* Unload the DirectDraw library if we failed to initialize */
300 if (!fReturn && g_hmodDirectDraw != NULL) {
301 FreeLibrary(g_hmodDirectDraw);
302 g_hmodDirectDraw = NULL;
303 }
304
305 return fReturn;
306}
307
308void
309winReleaseDDProcAddresses(void)
310{
311 if (g_hmodDirectDraw != NULL) {
312 FreeLibrary(g_hmodDirectDraw);
313 g_hmodDirectDraw = NULL;
314 g_fpDirectDrawCreate = NULL;
315 g_fpDirectDrawCreateClipper = NULL;
316 }
317}