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