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