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 */
41 FARPROC g_fpDirectDrawCreate = NULL;
42 FARPROC g_fpDirectDrawCreateClipper = NULL;
43
44 /*
45 module handle for dynamically loaded directdraw library
46 */
47 static HMODULE g_hmodDirectDraw = NULL;
48
49 /*
50 * Detect engines supported by current Windows version
51 * DirectDraw version and hardware
52 */
53
54 void
winDetectSupportedEngines(void)55 winDetectSupportedEngines(void)
56 {
57 /* Initialize the engine support flags */
58 g_dwEnginesSupported = WIN_SERVER_SHADOW_GDI;
59
60 /* Do we have DirectDraw? */
61 if (g_hmodDirectDraw != NULL) {
62 LPDIRECTDRAW lpdd = NULL;
63 LPDIRECTDRAW4 lpdd4 = NULL;
64 HRESULT ddrval;
65
66 /* Was the DirectDrawCreate function found? */
67 if (g_fpDirectDrawCreate == NULL) {
68 /* No DirectDraw support */
69 return;
70 }
71
72 /* DirectDrawCreate exists, try to call it */
73 /* Create a DirectDraw object, store the address at lpdd */
74 ddrval = (*g_fpDirectDrawCreate) (NULL, (void **) &lpdd, NULL);
75 if (FAILED(ddrval)) {
76 /* No DirectDraw support */
77 winErrorFVerb(2,
78 "winDetectSupportedEngines - DirectDraw not installed\n");
79 return;
80 }
81
82 /* Try to query for DirectDraw4 interface */
83 ddrval = IDirectDraw_QueryInterface(lpdd,
84 &IID_IDirectDraw4,
85 (LPVOID *) &lpdd4);
86 if (SUCCEEDED(ddrval)) {
87 /* We have DirectDraw4 */
88 winErrorFVerb(2,
89 "winDetectSupportedEngines - DirectDraw4 installed, allowing ShadowDDNL\n");
90 g_dwEnginesSupported |= WIN_SERVER_SHADOW_DDNL;
91 }
92
93 /* Cleanup DirectDraw interfaces */
94 if (lpdd4 != NULL)
95 IDirectDraw_Release(lpdd4);
96 if (lpdd != NULL)
97 IDirectDraw_Release(lpdd);
98 }
99
100 winErrorFVerb(2,
101 "winDetectSupportedEngines - Returning, supported engines %08x\n",
102 (unsigned int) g_dwEnginesSupported);
103 }
104
105 /*
106 * Set the engine type, depending on the engines
107 * supported for this screen, and whether the user
108 * suggested an engine type
109 */
110
111 Bool
winSetEngine(ScreenPtr pScreen)112 winSetEngine(ScreenPtr pScreen)
113 {
114 winScreenPriv(pScreen);
115 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
116 HDC hdc;
117 DWORD dwBPP;
118
119 /* Get a DC */
120 hdc = GetDC(NULL);
121 if (hdc == NULL) {
122 ErrorF("winSetEngine - Couldn't get an HDC\n");
123 return FALSE;
124 }
125
126 /*
127 * pScreenInfo->dwBPP may be 0 to indicate that the current screen
128 * depth is to be used. Thus, we must query for the current display
129 * depth here.
130 */
131 dwBPP = GetDeviceCaps(hdc, BITSPIXEL);
132
133 /* Release the DC */
134 ReleaseDC(NULL, hdc);
135 hdc = NULL;
136
137 /* ShadowGDI is the only engine that supports windowed PseudoColor */
138 if (dwBPP == 8 && !pScreenInfo->fFullScreen) {
139 winErrorFVerb(2,
140 "winSetEngine - Windowed && PseudoColor => ShadowGDI\n");
141 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI;
142
143 /* Set engine function pointers */
144 winSetEngineFunctionsShadowGDI(pScreen);
145 return TRUE;
146 }
147
148 /* ShadowGDI is the only engine that supports Multi Window Mode */
149 if (FALSE
150 #ifdef XWIN_MULTIWINDOWEXTWM
151 || pScreenInfo->fMWExtWM
152 #endif
153 || pScreenInfo->fMultiWindow
154 ) {
155 winErrorFVerb(2,
156 "winSetEngine - Multi Window or Rootless => ShadowGDI\n");
157 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI;
158
159 /* Set engine function pointers */
160 winSetEngineFunctionsShadowGDI(pScreen);
161 return TRUE;
162 }
163
164 /* If the user's choice is supported, we'll use that */
165 if (g_dwEnginesSupported & pScreenInfo->dwEnginePreferred) {
166 winErrorFVerb(2, "winSetEngine - Using user's preference: %d\n",
167 (int) pScreenInfo->dwEnginePreferred);
168 pScreenInfo->dwEngine = pScreenInfo->dwEnginePreferred;
169
170 /* Setup engine function pointers */
171 switch (pScreenInfo->dwEngine) {
172 case WIN_SERVER_SHADOW_GDI:
173 winSetEngineFunctionsShadowGDI(pScreen);
174 break;
175 case WIN_SERVER_SHADOW_DDNL:
176 winSetEngineFunctionsShadowDDNL(pScreen);
177 break;
178 default:
179 FatalError("winSetEngine - Invalid engine type\n");
180 }
181 return TRUE;
182 }
183
184 /* ShadowDDNL has good performance, so why not */
185 if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DDNL) {
186 winErrorFVerb(2, "winSetEngine - Using Shadow DirectDraw NonLocking\n");
187 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DDNL;
188
189 /* Set engine function pointers */
190 winSetEngineFunctionsShadowDDNL(pScreen);
191 return TRUE;
192 }
193
194 /* ShadowGDI is next in line */
195 if (g_dwEnginesSupported & WIN_SERVER_SHADOW_GDI) {
196 winErrorFVerb(2, "winSetEngine - Using Shadow GDI DIB\n");
197 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI;
198
199 /* Set engine function pointers */
200 winSetEngineFunctionsShadowGDI(pScreen);
201 return TRUE;
202 }
203
204 return FALSE;
205 }
206
207 /*
208 * Get procedure addresses for DirectDrawCreate and DirectDrawCreateClipper
209 */
210
211 Bool
winGetDDProcAddresses(void)212 winGetDDProcAddresses(void)
213 {
214 Bool fReturn = TRUE;
215
216 /* Load the DirectDraw library */
217 g_hmodDirectDraw = LoadLibraryEx("ddraw.dll", NULL, 0);
218 if (g_hmodDirectDraw == NULL) {
219 ErrorF("winGetDDProcAddresses - Could not load ddraw.dll\n");
220 fReturn = TRUE;
221 goto winGetDDProcAddresses_Exit;
222 }
223
224 /* Try to get the DirectDrawCreate address */
225 g_fpDirectDrawCreate = GetProcAddress(g_hmodDirectDraw, "DirectDrawCreate");
226 if (g_fpDirectDrawCreate == NULL) {
227 ErrorF("winGetDDProcAddresses - Could not get DirectDrawCreate "
228 "address\n");
229 fReturn = TRUE;
230 goto winGetDDProcAddresses_Exit;
231 }
232
233 /* Try to get the DirectDrawCreateClipper address */
234 g_fpDirectDrawCreateClipper = GetProcAddress(g_hmodDirectDraw,
235 "DirectDrawCreateClipper");
236 if (g_fpDirectDrawCreateClipper == NULL) {
237 ErrorF("winGetDDProcAddresses - Could not get "
238 "DirectDrawCreateClipper address\n");
239 fReturn = FALSE;
240 goto winGetDDProcAddresses_Exit;
241 }
242
243 /*
244 * Note: Do not unload ddraw.dll here. Do it in GiveUp
245 */
246
247 winGetDDProcAddresses_Exit:
248 /* Unload the DirectDraw library if we failed to initialize */
249 if (!fReturn && g_hmodDirectDraw != NULL) {
250 FreeLibrary(g_hmodDirectDraw);
251 g_hmodDirectDraw = NULL;
252 }
253
254 return fReturn;
255 }
256
257 void
winReleaseDDProcAddresses(void)258 winReleaseDDProcAddresses(void)
259 {
260 if (g_hmodDirectDraw != NULL) {
261 FreeLibrary(g_hmodDirectDraw);
262 g_hmodDirectDraw = NULL;
263 g_fpDirectDrawCreate = NULL;
264 g_fpDirectDrawCreateClipper = NULL;
265 }
266 }
267