winengine.c revision 35c4bbdf
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
15305b261ecSmrg#ifdef XWIN_MULTIWINDOW
15435c4bbdfSmrg        || pScreenInfo->fMultiWindow
15505b261ecSmrg#endif
15635c4bbdfSmrg        ) {
15735c4bbdfSmrg        winErrorFVerb(2,
15835c4bbdfSmrg                      "winSetEngine - Multi Window or Rootless => ShadowGDI\n");
15935c4bbdfSmrg        pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI;
16035c4bbdfSmrg
16135c4bbdfSmrg        /* Set engine function pointers */
16235c4bbdfSmrg        winSetEngineFunctionsShadowGDI(pScreen);
16335c4bbdfSmrg        return TRUE;
16405b261ecSmrg    }
16505b261ecSmrg
16635c4bbdfSmrg    /* If the user's choice is supported, we'll use that */
16735c4bbdfSmrg    if (g_dwEnginesSupported & pScreenInfo->dwEnginePreferred) {
16835c4bbdfSmrg        winErrorFVerb(2, "winSetEngine - Using user's preference: %d\n",
16935c4bbdfSmrg                      (int) pScreenInfo->dwEnginePreferred);
17035c4bbdfSmrg        pScreenInfo->dwEngine = pScreenInfo->dwEnginePreferred;
17135c4bbdfSmrg
17235c4bbdfSmrg        /* Setup engine function pointers */
17335c4bbdfSmrg        switch (pScreenInfo->dwEngine) {
17435c4bbdfSmrg        case WIN_SERVER_SHADOW_GDI:
17535c4bbdfSmrg            winSetEngineFunctionsShadowGDI(pScreen);
17635c4bbdfSmrg            break;
17735c4bbdfSmrg        case WIN_SERVER_SHADOW_DDNL:
17835c4bbdfSmrg            winSetEngineFunctionsShadowDDNL(pScreen);
17935c4bbdfSmrg            break;
18035c4bbdfSmrg        default:
18135c4bbdfSmrg            FatalError("winSetEngine - Invalid engine type\n");
18235c4bbdfSmrg        }
18335c4bbdfSmrg        return TRUE;
18405b261ecSmrg    }
18505b261ecSmrg
18635c4bbdfSmrg    /* ShadowDDNL has good performance, so why not */
18735c4bbdfSmrg    if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DDNL) {
18835c4bbdfSmrg        winErrorFVerb(2, "winSetEngine - Using Shadow DirectDraw NonLocking\n");
18935c4bbdfSmrg        pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DDNL;
19005b261ecSmrg
19135c4bbdfSmrg        /* Set engine function pointers */
19235c4bbdfSmrg        winSetEngineFunctionsShadowDDNL(pScreen);
19335c4bbdfSmrg        return TRUE;
19405b261ecSmrg    }
19505b261ecSmrg
19635c4bbdfSmrg    /* ShadowGDI is next in line */
19735c4bbdfSmrg    if (g_dwEnginesSupported & WIN_SERVER_SHADOW_GDI) {
19835c4bbdfSmrg        winErrorFVerb(2, "winSetEngine - Using Shadow GDI DIB\n");
19935c4bbdfSmrg        pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI;
20005b261ecSmrg
20135c4bbdfSmrg        /* Set engine function pointers */
20235c4bbdfSmrg        winSetEngineFunctionsShadowGDI(pScreen);
20335c4bbdfSmrg        return TRUE;
20405b261ecSmrg    }
20505b261ecSmrg
20635c4bbdfSmrg    return TRUE;
20705b261ecSmrg}
20805b261ecSmrg
20905b261ecSmrg/*
21005b261ecSmrg * Get procedure addresses for DirectDrawCreate and DirectDrawCreateClipper
21105b261ecSmrg */
21205b261ecSmrg
21305b261ecSmrgBool
21435c4bbdfSmrgwinGetDDProcAddresses(void)
21505b261ecSmrg{
21635c4bbdfSmrg    Bool fReturn = TRUE;
21735c4bbdfSmrg
21835c4bbdfSmrg    /* Load the DirectDraw library */
21935c4bbdfSmrg    g_hmodDirectDraw = LoadLibraryEx("ddraw.dll", NULL, 0);
22035c4bbdfSmrg    if (g_hmodDirectDraw == NULL) {
22135c4bbdfSmrg        ErrorF("winGetDDProcAddresses - Could not load ddraw.dll\n");
22235c4bbdfSmrg        fReturn = TRUE;
22335c4bbdfSmrg        goto winGetDDProcAddresses_Exit;
22405b261ecSmrg    }
22505b261ecSmrg
22635c4bbdfSmrg    /* Try to get the DirectDrawCreate address */
22735c4bbdfSmrg    g_fpDirectDrawCreate = GetProcAddress(g_hmodDirectDraw, "DirectDrawCreate");
22835c4bbdfSmrg    if (g_fpDirectDrawCreate == NULL) {
22935c4bbdfSmrg        ErrorF("winGetDDProcAddresses - Could not get DirectDrawCreate "
23035c4bbdfSmrg               "address\n");
23135c4bbdfSmrg        fReturn = TRUE;
23235c4bbdfSmrg        goto winGetDDProcAddresses_Exit;
23305b261ecSmrg    }
23405b261ecSmrg
23535c4bbdfSmrg    /* Try to get the DirectDrawCreateClipper address */
23635c4bbdfSmrg    g_fpDirectDrawCreateClipper = GetProcAddress(g_hmodDirectDraw,
23735c4bbdfSmrg                                                 "DirectDrawCreateClipper");
23835c4bbdfSmrg    if (g_fpDirectDrawCreateClipper == NULL) {
23935c4bbdfSmrg        ErrorF("winGetDDProcAddresses - Could not get "
24035c4bbdfSmrg               "DirectDrawCreateClipper address\n");
24135c4bbdfSmrg        fReturn = FALSE;
24235c4bbdfSmrg        goto winGetDDProcAddresses_Exit;
24305b261ecSmrg    }
24405b261ecSmrg
24535c4bbdfSmrg    /*
24635c4bbdfSmrg     * Note: Do not unload ddraw.dll here.  Do it in GiveUp
24735c4bbdfSmrg     */
24805b261ecSmrg
24905b261ecSmrg winGetDDProcAddresses_Exit:
25035c4bbdfSmrg    /* Unload the DirectDraw library if we failed to initialize */
25135c4bbdfSmrg    if (!fReturn && g_hmodDirectDraw != NULL) {
25235c4bbdfSmrg        FreeLibrary(g_hmodDirectDraw);
25335c4bbdfSmrg        g_hmodDirectDraw = NULL;
25405b261ecSmrg    }
25535c4bbdfSmrg
25635c4bbdfSmrg    return fReturn;
25705b261ecSmrg}
2589ace9065Smrg
2599ace9065Smrgvoid
2609ace9065SmrgwinReleaseDDProcAddresses(void)
2619ace9065Smrg{
26235c4bbdfSmrg    if (g_hmodDirectDraw != NULL) {
26335c4bbdfSmrg        FreeLibrary(g_hmodDirectDraw);
26435c4bbdfSmrg        g_hmodDirectDraw = NULL;
26535c4bbdfSmrg        g_fpDirectDrawCreate = NULL;
26635c4bbdfSmrg        g_fpDirectDrawCreateClipper = NULL;
2679ace9065Smrg    }
2689ace9065Smrg}
269