winengine.c revision 1b5d61b8
105b261ecSmrg/* 205b261ecSmrg *Copyright (C) 2001-2004 Harold L Hunt II All Rights Reserved. 305b261ecSmrg * 405b261ecSmrg *Permission is hereby granted, free of charge, to any person obtaining 505b261ecSmrg * a copy of this software and associated documentation files (the 605b261ecSmrg *"Software"), to deal in the Software without restriction, including 705b261ecSmrg *without limitation the rights to use, copy, modify, merge, publish, 805b261ecSmrg *distribute, sublicense, and/or sell copies of the Software, and to 905b261ecSmrg *permit persons to whom the Software is furnished to do so, subject to 1005b261ecSmrg *the following conditions: 1105b261ecSmrg * 1205b261ecSmrg *The above copyright notice and this permission notice shall be 1305b261ecSmrg *included in all copies or substantial portions of the Software. 1405b261ecSmrg * 1505b261ecSmrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1605b261ecSmrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1705b261ecSmrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1805b261ecSmrg *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR 1905b261ecSmrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 2005b261ecSmrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 2105b261ecSmrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2205b261ecSmrg * 2305b261ecSmrg *Except as contained in this notice, the name of Harold L Hunt II 2405b261ecSmrg *shall not be used in advertising or otherwise to promote the sale, use 2505b261ecSmrg *or other dealings in this Software without prior written authorization 2605b261ecSmrg *from Harold L Hunt II. 2705b261ecSmrg * 2805b261ecSmrg * Authors: Harold L Hunt II 2905b261ecSmrg */ 3005b261ecSmrg 3105b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H 3205b261ecSmrg#include <xwin-config.h> 3305b261ecSmrg#endif 3405b261ecSmrg#include "win.h" 3505b261ecSmrg#include "winmsg.h" 3605b261ecSmrg 3705b261ecSmrg/* 389ace9065Smrg * Global variables for function pointers into 399ace9065Smrg * dynamically loaded libraries 4005b261ecSmrg */ 4135c4bbdfSmrgFARPROC g_fpDirectDrawCreate = NULL; 4235c4bbdfSmrgFARPROC g_fpDirectDrawCreateClipper = NULL; 4305b261ecSmrg 449ace9065Smrg/* 459ace9065Smrg module handle for dynamically loaded directdraw library 469ace9065Smrg*/ 479ace9065Smrgstatic HMODULE g_hmodDirectDraw = NULL; 4805b261ecSmrg 4905b261ecSmrg/* 5005b261ecSmrg * Detect engines supported by current Windows version 5105b261ecSmrg * DirectDraw version and hardware 5205b261ecSmrg */ 5305b261ecSmrg 5405b261ecSmrgvoid 5535c4bbdfSmrgwinDetectSupportedEngines(void) 5605b261ecSmrg{ 5735c4bbdfSmrg /* Initialize the engine support flags */ 5835c4bbdfSmrg g_dwEnginesSupported = WIN_SERVER_SHADOW_GDI; 5935c4bbdfSmrg 6035c4bbdfSmrg /* Do we have DirectDraw? */ 6135c4bbdfSmrg if (g_hmodDirectDraw != NULL) { 6235c4bbdfSmrg LPDIRECTDRAW lpdd = NULL; 6335c4bbdfSmrg LPDIRECTDRAW4 lpdd4 = NULL; 6435c4bbdfSmrg HRESULT ddrval; 6535c4bbdfSmrg 6635c4bbdfSmrg /* Was the DirectDrawCreate function found? */ 6735c4bbdfSmrg if (g_fpDirectDrawCreate == NULL) { 6835c4bbdfSmrg /* No DirectDraw support */ 6935c4bbdfSmrg return; 7035c4bbdfSmrg } 7135c4bbdfSmrg 7235c4bbdfSmrg /* DirectDrawCreate exists, try to call it */ 7335c4bbdfSmrg /* Create a DirectDraw object, store the address at lpdd */ 7435c4bbdfSmrg ddrval = (*g_fpDirectDrawCreate) (NULL, (void **) &lpdd, NULL); 7535c4bbdfSmrg if (FAILED(ddrval)) { 7635c4bbdfSmrg /* No DirectDraw support */ 7735c4bbdfSmrg winErrorFVerb(2, 7835c4bbdfSmrg "winDetectSupportedEngines - DirectDraw not installed\n"); 7935c4bbdfSmrg return; 8035c4bbdfSmrg } 8135c4bbdfSmrg 8235c4bbdfSmrg /* Try to query for DirectDraw4 interface */ 8335c4bbdfSmrg ddrval = IDirectDraw_QueryInterface(lpdd, 8435c4bbdfSmrg &IID_IDirectDraw4, 8535c4bbdfSmrg (LPVOID *) &lpdd4); 8635c4bbdfSmrg if (SUCCEEDED(ddrval)) { 8735c4bbdfSmrg /* We have DirectDraw4 */ 8835c4bbdfSmrg winErrorFVerb(2, 8935c4bbdfSmrg "winDetectSupportedEngines - DirectDraw4 installed, allowing ShadowDDNL\n"); 9035c4bbdfSmrg g_dwEnginesSupported |= WIN_SERVER_SHADOW_DDNL; 9135c4bbdfSmrg } 9235c4bbdfSmrg 9335c4bbdfSmrg /* Cleanup DirectDraw interfaces */ 9435c4bbdfSmrg if (lpdd4 != NULL) 9535c4bbdfSmrg IDirectDraw_Release(lpdd4); 9635c4bbdfSmrg if (lpdd != NULL) 9735c4bbdfSmrg IDirectDraw_Release(lpdd); 9805b261ecSmrg } 9905b261ecSmrg 10035c4bbdfSmrg winErrorFVerb(2, 10135c4bbdfSmrg "winDetectSupportedEngines - Returning, supported engines %08x\n", 10235c4bbdfSmrg (unsigned int) g_dwEnginesSupported); 10305b261ecSmrg} 10405b261ecSmrg 10505b261ecSmrg/* 10605b261ecSmrg * Set the engine type, depending on the engines 10705b261ecSmrg * supported for this screen, and whether the user 10805b261ecSmrg * suggested an engine type 10905b261ecSmrg */ 11005b261ecSmrg 11105b261ecSmrgBool 11235c4bbdfSmrgwinSetEngine(ScreenPtr pScreen) 11305b261ecSmrg{ 11435c4bbdfSmrg winScreenPriv(pScreen); 11535c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 11635c4bbdfSmrg HDC hdc; 11735c4bbdfSmrg DWORD dwBPP; 11835c4bbdfSmrg 11935c4bbdfSmrg /* Get a DC */ 12035c4bbdfSmrg hdc = GetDC(NULL); 12135c4bbdfSmrg if (hdc == NULL) { 12235c4bbdfSmrg ErrorF("winSetEngine - Couldn't get an HDC\n"); 12335c4bbdfSmrg return FALSE; 12405b261ecSmrg } 12505b261ecSmrg 12635c4bbdfSmrg /* 12735c4bbdfSmrg * pScreenInfo->dwBPP may be 0 to indicate that the current screen 12835c4bbdfSmrg * depth is to be used. Thus, we must query for the current display 12935c4bbdfSmrg * depth here. 13035c4bbdfSmrg */ 13135c4bbdfSmrg dwBPP = GetDeviceCaps(hdc, BITSPIXEL); 13235c4bbdfSmrg 13335c4bbdfSmrg /* Release the DC */ 13435c4bbdfSmrg ReleaseDC(NULL, hdc); 13535c4bbdfSmrg hdc = NULL; 13635c4bbdfSmrg 13735c4bbdfSmrg /* ShadowGDI is the only engine that supports windowed PseudoColor */ 13835c4bbdfSmrg if (dwBPP == 8 && !pScreenInfo->fFullScreen) { 13935c4bbdfSmrg winErrorFVerb(2, 14035c4bbdfSmrg "winSetEngine - Windowed && PseudoColor => ShadowGDI\n"); 14135c4bbdfSmrg pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; 14235c4bbdfSmrg 14335c4bbdfSmrg /* Set engine function pointers */ 14435c4bbdfSmrg winSetEngineFunctionsShadowGDI(pScreen); 14535c4bbdfSmrg return TRUE; 14605b261ecSmrg } 14705b261ecSmrg 14835c4bbdfSmrg /* ShadowGDI is the only engine that supports Multi Window Mode */ 14935c4bbdfSmrg if (FALSE 15005b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM 15135c4bbdfSmrg || pScreenInfo->fMWExtWM 15205b261ecSmrg#endif 15335c4bbdfSmrg || pScreenInfo->fMultiWindow 15435c4bbdfSmrg ) { 15535c4bbdfSmrg winErrorFVerb(2, 15635c4bbdfSmrg "winSetEngine - Multi Window or Rootless => ShadowGDI\n"); 15735c4bbdfSmrg pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; 15835c4bbdfSmrg 15935c4bbdfSmrg /* Set engine function pointers */ 16035c4bbdfSmrg winSetEngineFunctionsShadowGDI(pScreen); 16135c4bbdfSmrg return TRUE; 16205b261ecSmrg } 16305b261ecSmrg 16435c4bbdfSmrg /* If the user's choice is supported, we'll use that */ 16535c4bbdfSmrg if (g_dwEnginesSupported & pScreenInfo->dwEnginePreferred) { 16635c4bbdfSmrg winErrorFVerb(2, "winSetEngine - Using user's preference: %d\n", 16735c4bbdfSmrg (int) pScreenInfo->dwEnginePreferred); 16835c4bbdfSmrg pScreenInfo->dwEngine = pScreenInfo->dwEnginePreferred; 16935c4bbdfSmrg 17035c4bbdfSmrg /* Setup engine function pointers */ 17135c4bbdfSmrg switch (pScreenInfo->dwEngine) { 17235c4bbdfSmrg case WIN_SERVER_SHADOW_GDI: 17335c4bbdfSmrg winSetEngineFunctionsShadowGDI(pScreen); 17435c4bbdfSmrg break; 17535c4bbdfSmrg case WIN_SERVER_SHADOW_DDNL: 17635c4bbdfSmrg winSetEngineFunctionsShadowDDNL(pScreen); 17735c4bbdfSmrg break; 17835c4bbdfSmrg default: 17935c4bbdfSmrg FatalError("winSetEngine - Invalid engine type\n"); 18035c4bbdfSmrg } 18135c4bbdfSmrg return TRUE; 18205b261ecSmrg } 18305b261ecSmrg 18435c4bbdfSmrg /* ShadowDDNL has good performance, so why not */ 18535c4bbdfSmrg if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DDNL) { 18635c4bbdfSmrg winErrorFVerb(2, "winSetEngine - Using Shadow DirectDraw NonLocking\n"); 18735c4bbdfSmrg pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DDNL; 18805b261ecSmrg 18935c4bbdfSmrg /* Set engine function pointers */ 19035c4bbdfSmrg winSetEngineFunctionsShadowDDNL(pScreen); 19135c4bbdfSmrg return TRUE; 19205b261ecSmrg } 19305b261ecSmrg 19435c4bbdfSmrg /* ShadowGDI is next in line */ 19535c4bbdfSmrg if (g_dwEnginesSupported & WIN_SERVER_SHADOW_GDI) { 19635c4bbdfSmrg winErrorFVerb(2, "winSetEngine - Using Shadow GDI DIB\n"); 19735c4bbdfSmrg pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; 19805b261ecSmrg 19935c4bbdfSmrg /* Set engine function pointers */ 20035c4bbdfSmrg winSetEngineFunctionsShadowGDI(pScreen); 20135c4bbdfSmrg return TRUE; 20205b261ecSmrg } 20305b261ecSmrg 2041b5d61b8Smrg return FALSE; 20505b261ecSmrg} 20605b261ecSmrg 20705b261ecSmrg/* 20805b261ecSmrg * Get procedure addresses for DirectDrawCreate and DirectDrawCreateClipper 20905b261ecSmrg */ 21005b261ecSmrg 21105b261ecSmrgBool 21235c4bbdfSmrgwinGetDDProcAddresses(void) 21305b261ecSmrg{ 21435c4bbdfSmrg Bool fReturn = TRUE; 21535c4bbdfSmrg 21635c4bbdfSmrg /* Load the DirectDraw library */ 21735c4bbdfSmrg g_hmodDirectDraw = LoadLibraryEx("ddraw.dll", NULL, 0); 21835c4bbdfSmrg if (g_hmodDirectDraw == NULL) { 21935c4bbdfSmrg ErrorF("winGetDDProcAddresses - Could not load ddraw.dll\n"); 22035c4bbdfSmrg fReturn = TRUE; 22135c4bbdfSmrg goto winGetDDProcAddresses_Exit; 22205b261ecSmrg } 22305b261ecSmrg 22435c4bbdfSmrg /* Try to get the DirectDrawCreate address */ 22535c4bbdfSmrg g_fpDirectDrawCreate = GetProcAddress(g_hmodDirectDraw, "DirectDrawCreate"); 22635c4bbdfSmrg if (g_fpDirectDrawCreate == NULL) { 22735c4bbdfSmrg ErrorF("winGetDDProcAddresses - Could not get DirectDrawCreate " 22835c4bbdfSmrg "address\n"); 22935c4bbdfSmrg fReturn = TRUE; 23035c4bbdfSmrg goto winGetDDProcAddresses_Exit; 23105b261ecSmrg } 23205b261ecSmrg 23335c4bbdfSmrg /* Try to get the DirectDrawCreateClipper address */ 23435c4bbdfSmrg g_fpDirectDrawCreateClipper = GetProcAddress(g_hmodDirectDraw, 23535c4bbdfSmrg "DirectDrawCreateClipper"); 23635c4bbdfSmrg if (g_fpDirectDrawCreateClipper == NULL) { 23735c4bbdfSmrg ErrorF("winGetDDProcAddresses - Could not get " 23835c4bbdfSmrg "DirectDrawCreateClipper address\n"); 23935c4bbdfSmrg fReturn = FALSE; 24035c4bbdfSmrg goto winGetDDProcAddresses_Exit; 24105b261ecSmrg } 24205b261ecSmrg 24335c4bbdfSmrg /* 24435c4bbdfSmrg * Note: Do not unload ddraw.dll here. Do it in GiveUp 24535c4bbdfSmrg */ 24605b261ecSmrg 24705b261ecSmrg winGetDDProcAddresses_Exit: 24835c4bbdfSmrg /* Unload the DirectDraw library if we failed to initialize */ 24935c4bbdfSmrg if (!fReturn && g_hmodDirectDraw != NULL) { 25035c4bbdfSmrg FreeLibrary(g_hmodDirectDraw); 25135c4bbdfSmrg g_hmodDirectDraw = NULL; 25205b261ecSmrg } 25335c4bbdfSmrg 25435c4bbdfSmrg return fReturn; 25505b261ecSmrg} 2569ace9065Smrg 2579ace9065Smrgvoid 2589ace9065SmrgwinReleaseDDProcAddresses(void) 2599ace9065Smrg{ 26035c4bbdfSmrg if (g_hmodDirectDraw != NULL) { 26135c4bbdfSmrg FreeLibrary(g_hmodDirectDraw); 26235c4bbdfSmrg g_hmodDirectDraw = NULL; 26335c4bbdfSmrg g_fpDirectDrawCreate = NULL; 26435c4bbdfSmrg g_fpDirectDrawCreateClipper = NULL; 2659ace9065Smrg } 2669ace9065Smrg} 267