xref: /OK3568_Linux_fs/external/xserver/hw/xwin/winengine.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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