winengine.c revision 6747b715
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/* 39 * External global variables 40 */ 41 42extern const GUID _IID_IDirectDraw4; 43 44 45/* 46 * Detect engines supported by current Windows version 47 * DirectDraw version and hardware 48 */ 49 50void 51winDetectSupportedEngines (void) 52{ 53 OSVERSIONINFO osvi; 54 55 /* Initialize the engine support flags */ 56 g_dwEnginesSupported = WIN_SERVER_SHADOW_GDI; 57 58#ifdef XWIN_NATIVEGDI 59 g_dwEnginesSupported |= WIN_SERVER_NATIVE_GDI; 60#endif 61 62 /* Get operating system version information */ 63 ZeroMemory (&osvi, sizeof (osvi)); 64 osvi.dwOSVersionInfoSize = sizeof (osvi); 65 GetVersionEx (&osvi); 66 67 /* Branch on platform ID */ 68 switch (osvi.dwPlatformId) 69 { 70 case VER_PLATFORM_WIN32_NT: 71 /* Engine 4 is supported on NT only */ 72 winErrorFVerb (2, "winDetectSupportedEngines - Windows NT/2000/XP\n"); 73 break; 74 75 case VER_PLATFORM_WIN32_WINDOWS: 76 /* Engine 4 is supported on NT only */ 77 winErrorFVerb (2, "winDetectSupportedEngines - Windows 95/98/Me\n"); 78 break; 79 } 80 81 /* Do we have DirectDraw? */ 82 if (g_hmodDirectDraw != NULL) 83 { 84 LPDIRECTDRAW lpdd = NULL; 85 LPDIRECTDRAW4 lpdd4 = NULL; 86 HRESULT ddrval; 87 88 /* Was the DirectDrawCreate function found? */ 89 if (g_fpDirectDrawCreate == NULL) 90 { 91 /* No DirectDraw support */ 92 return; 93 } 94 95 /* DirectDrawCreate exists, try to call it */ 96 /* Create a DirectDraw object, store the address at lpdd */ 97 ddrval = (*g_fpDirectDrawCreate) (NULL, 98 (void**) &lpdd, 99 NULL); 100 if (FAILED (ddrval)) 101 { 102 /* No DirectDraw support */ 103 winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw not installed\n"); 104 return; 105 } 106 else 107 { 108 /* We have DirectDraw */ 109 winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw installed\n"); 110 g_dwEnginesSupported |= WIN_SERVER_SHADOW_DD; 111 112#ifdef XWIN_PRIMARYFB 113 /* Allow PrimaryDD engine if NT */ 114 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) 115 { 116 g_dwEnginesSupported |= WIN_SERVER_PRIMARY_DD; 117 winErrorFVerb (2, "winDetectSupportedEngines - Allowing PrimaryDD\n"); 118 } 119#endif 120 } 121 122 /* Try to query for DirectDraw4 interface */ 123 ddrval = IDirectDraw_QueryInterface (lpdd, 124 &IID_IDirectDraw4, 125 (LPVOID*) &lpdd4); 126 if (SUCCEEDED (ddrval)) 127 { 128 /* We have DirectDraw4 */ 129 winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw4 installed\n"); 130 g_dwEnginesSupported |= WIN_SERVER_SHADOW_DDNL; 131 } 132 133 /* Cleanup DirectDraw interfaces */ 134 if (lpdd4 != NULL) 135 IDirectDraw_Release (lpdd4); 136 if (lpdd != NULL) 137 IDirectDraw_Release (lpdd); 138 } 139 140 winErrorFVerb (2, "winDetectSupportedEngines - Returning, supported engines %08x\n", 141 (unsigned int) g_dwEnginesSupported); 142} 143 144 145/* 146 * Set the engine type, depending on the engines 147 * supported for this screen, and whether the user 148 * suggested an engine type 149 */ 150 151Bool 152winSetEngine (ScreenPtr pScreen) 153{ 154 winScreenPriv(pScreen); 155 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 156 HDC hdc; 157 DWORD dwBPP; 158 159 /* Get a DC */ 160 hdc = GetDC (NULL); 161 if (hdc == NULL) 162 { 163 ErrorF ("winSetEngine - Couldn't get an HDC\n"); 164 return FALSE; 165 } 166 167 /* 168 * pScreenInfo->dwBPP may be 0 to indicate that the current screen 169 * depth is to be used. Thus, we must query for the current display 170 * depth here. 171 */ 172 dwBPP = GetDeviceCaps (hdc, BITSPIXEL); 173 174 /* Release the DC */ 175 ReleaseDC (NULL, hdc); 176 hdc = NULL; 177 178 /* ShadowGDI is the only engine that supports windowed PseudoColor */ 179 if (dwBPP == 8 && !pScreenInfo->fFullScreen) 180 { 181 winErrorFVerb (2, "winSetEngine - Windowed && PseudoColor => ShadowGDI\n"); 182 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; 183 184 /* Set engine function pointers */ 185 winSetEngineFunctionsShadowGDI (pScreen); 186 return TRUE; 187 } 188 189 /* ShadowGDI is the only engine that supports Multi Window Mode */ 190 if ( 191#ifdef XWIN_MULTIWINDOWEXTWM 192 pScreenInfo->fMWExtWM 193#else 194 FALSE 195#endif 196#ifdef XWIN_MULTIWINDOW 197 || pScreenInfo->fMultiWindow 198#else 199 || FALSE 200#endif 201 ) 202 { 203 winErrorFVerb (2, "winSetEngine - Multi Window or Rootless => ShadowGDI\n"); 204 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; 205 206 /* Set engine function pointers */ 207 winSetEngineFunctionsShadowGDI (pScreen); 208 return TRUE; 209 } 210 211 /* If the user's choice is supported, we'll use that */ 212 if (g_dwEnginesSupported & pScreenInfo->dwEnginePreferred) 213 { 214 winErrorFVerb (2, "winSetEngine - Using user's preference: %d\n", 215 (int) pScreenInfo->dwEnginePreferred); 216 pScreenInfo->dwEngine = pScreenInfo->dwEnginePreferred; 217 218 /* Setup engine function pointers */ 219 switch (pScreenInfo->dwEngine) 220 { 221 case WIN_SERVER_SHADOW_GDI: 222 winSetEngineFunctionsShadowGDI (pScreen); 223 break; 224 case WIN_SERVER_SHADOW_DD: 225 winSetEngineFunctionsShadowDD (pScreen); 226 break; 227 case WIN_SERVER_SHADOW_DDNL: 228 winSetEngineFunctionsShadowDDNL (pScreen); 229 break; 230#ifdef XWIN_PRIMARYFB 231 case WIN_SERVER_PRIMARY_DD: 232 winSetEngineFunctionsPrimaryDD (pScreen); 233 break; 234#endif 235#ifdef XWIN_NATIVEGDI 236 case WIN_SERVER_NATIVE_GDI: 237 winSetEngineFunctionsNativeGDI (pScreen); 238 break; 239#endif 240 default: 241 FatalError ("winSetEngine - Invalid engine type\n"); 242 } 243 return TRUE; 244 } 245 246 /* ShadowDDNL has good performance, so why not */ 247 if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DDNL) 248 { 249 winErrorFVerb (2, "winSetEngine - Using Shadow DirectDraw NonLocking\n"); 250 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DDNL; 251 252 /* Set engine function pointers */ 253 winSetEngineFunctionsShadowDDNL (pScreen); 254 return TRUE; 255 } 256 257 /* ShadowDD is next in line */ 258 if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DD) 259 { 260 winErrorFVerb (2, "winSetEngine - Using Shadow DirectDraw\n"); 261 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DD; 262 263 /* Set engine function pointers */ 264 winSetEngineFunctionsShadowDD (pScreen); 265 return TRUE; 266 } 267 268 /* ShadowGDI is next in line */ 269 if (g_dwEnginesSupported & WIN_SERVER_SHADOW_GDI) 270 { 271 winErrorFVerb (2, "winSetEngine - Using Shadow GDI DIB\n"); 272 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; 273 274 /* Set engine function pointers */ 275 winSetEngineFunctionsShadowGDI (pScreen); 276 return TRUE; 277 } 278 279 return TRUE; 280} 281 282 283/* 284 * Get procedure addresses for DirectDrawCreate and DirectDrawCreateClipper 285 */ 286 287Bool 288winGetDDProcAddresses (void) 289{ 290 Bool fReturn = TRUE; 291 292 /* Load the DirectDraw library */ 293 g_hmodDirectDraw = LoadLibraryEx ("ddraw.dll", NULL, 0); 294 if (g_hmodDirectDraw == NULL) 295 { 296 ErrorF ("winGetDDProcAddresses - Could not load ddraw.dll\n"); 297 fReturn = TRUE; 298 goto winGetDDProcAddresses_Exit; 299 } 300 301 /* Try to get the DirectDrawCreate address */ 302 g_fpDirectDrawCreate = GetProcAddress (g_hmodDirectDraw, 303 "DirectDrawCreate"); 304 if (g_fpDirectDrawCreate == NULL) 305 { 306 ErrorF ("winGetDDProcAddresses - Could not get DirectDrawCreate " 307 "address\n"); 308 fReturn = TRUE; 309 goto winGetDDProcAddresses_Exit; 310 } 311 312 /* Try to get the DirectDrawCreateClipper address */ 313 g_fpDirectDrawCreateClipper = GetProcAddress (g_hmodDirectDraw, 314 "DirectDrawCreateClipper"); 315 if (g_fpDirectDrawCreateClipper == NULL) 316 { 317 ErrorF ("winGetDDProcAddresses - Could not get " 318 "DirectDrawCreateClipper address\n"); 319 fReturn = FALSE; 320 goto winGetDDProcAddresses_Exit; 321 } 322 323 /* 324 * Note: Do not unload ddraw.dll here. Do it in GiveUp 325 */ 326 327 winGetDDProcAddresses_Exit: 328 /* Unload the DirectDraw library if we failed to initialize */ 329 if (!fReturn && g_hmodDirectDraw != NULL) 330 { 331 FreeLibrary (g_hmodDirectDraw); 332 g_hmodDirectDraw = NULL; 333 } 334 335 return fReturn; 336} 337