winengine.c revision 35c4bbdf
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 */ 41FARPROC g_fpDirectDrawCreate = NULL; 42FARPROC g_fpDirectDrawCreateClipper = NULL; 43 44/* 45 module handle for dynamically loaded directdraw library 46*/ 47static HMODULE g_hmodDirectDraw = NULL; 48 49/* 50 * Detect engines supported by current Windows version 51 * DirectDraw version and hardware 52 */ 53 54void 55winDetectSupportedEngines(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 111Bool 112winSetEngine(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#ifdef XWIN_MULTIWINDOW 154 || pScreenInfo->fMultiWindow 155#endif 156 ) { 157 winErrorFVerb(2, 158 "winSetEngine - Multi Window or Rootless => ShadowGDI\n"); 159 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; 160 161 /* Set engine function pointers */ 162 winSetEngineFunctionsShadowGDI(pScreen); 163 return TRUE; 164 } 165 166 /* If the user's choice is supported, we'll use that */ 167 if (g_dwEnginesSupported & pScreenInfo->dwEnginePreferred) { 168 winErrorFVerb(2, "winSetEngine - Using user's preference: %d\n", 169 (int) pScreenInfo->dwEnginePreferred); 170 pScreenInfo->dwEngine = pScreenInfo->dwEnginePreferred; 171 172 /* Setup engine function pointers */ 173 switch (pScreenInfo->dwEngine) { 174 case WIN_SERVER_SHADOW_GDI: 175 winSetEngineFunctionsShadowGDI(pScreen); 176 break; 177 case WIN_SERVER_SHADOW_DDNL: 178 winSetEngineFunctionsShadowDDNL(pScreen); 179 break; 180 default: 181 FatalError("winSetEngine - Invalid engine type\n"); 182 } 183 return TRUE; 184 } 185 186 /* ShadowDDNL has good performance, so why not */ 187 if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DDNL) { 188 winErrorFVerb(2, "winSetEngine - Using Shadow DirectDraw NonLocking\n"); 189 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DDNL; 190 191 /* Set engine function pointers */ 192 winSetEngineFunctionsShadowDDNL(pScreen); 193 return TRUE; 194 } 195 196 /* ShadowGDI is next in line */ 197 if (g_dwEnginesSupported & WIN_SERVER_SHADOW_GDI) { 198 winErrorFVerb(2, "winSetEngine - Using Shadow GDI DIB\n"); 199 pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; 200 201 /* Set engine function pointers */ 202 winSetEngineFunctionsShadowGDI(pScreen); 203 return TRUE; 204 } 205 206 return TRUE; 207} 208 209/* 210 * Get procedure addresses for DirectDrawCreate and DirectDrawCreateClipper 211 */ 212 213Bool 214winGetDDProcAddresses(void) 215{ 216 Bool fReturn = TRUE; 217 218 /* Load the DirectDraw library */ 219 g_hmodDirectDraw = LoadLibraryEx("ddraw.dll", NULL, 0); 220 if (g_hmodDirectDraw == NULL) { 221 ErrorF("winGetDDProcAddresses - Could not load ddraw.dll\n"); 222 fReturn = TRUE; 223 goto winGetDDProcAddresses_Exit; 224 } 225 226 /* Try to get the DirectDrawCreate address */ 227 g_fpDirectDrawCreate = GetProcAddress(g_hmodDirectDraw, "DirectDrawCreate"); 228 if (g_fpDirectDrawCreate == NULL) { 229 ErrorF("winGetDDProcAddresses - Could not get DirectDrawCreate " 230 "address\n"); 231 fReturn = TRUE; 232 goto winGetDDProcAddresses_Exit; 233 } 234 235 /* Try to get the DirectDrawCreateClipper address */ 236 g_fpDirectDrawCreateClipper = GetProcAddress(g_hmodDirectDraw, 237 "DirectDrawCreateClipper"); 238 if (g_fpDirectDrawCreateClipper == NULL) { 239 ErrorF("winGetDDProcAddresses - Could not get " 240 "DirectDrawCreateClipper address\n"); 241 fReturn = FALSE; 242 goto winGetDDProcAddresses_Exit; 243 } 244 245 /* 246 * Note: Do not unload ddraw.dll here. Do it in GiveUp 247 */ 248 249 winGetDDProcAddresses_Exit: 250 /* Unload the DirectDraw library if we failed to initialize */ 251 if (!fReturn && g_hmodDirectDraw != NULL) { 252 FreeLibrary(g_hmodDirectDraw); 253 g_hmodDirectDraw = NULL; 254 } 255 256 return fReturn; 257} 258 259void 260winReleaseDDProcAddresses(void) 261{ 262 if (g_hmodDirectDraw != NULL) { 263 FreeLibrary(g_hmodDirectDraw); 264 g_hmodDirectDraw = NULL; 265 g_fpDirectDrawCreate = NULL; 266 g_fpDirectDrawCreateClipper = NULL; 267 } 268} 269