105b261ecSmrg/*
205b261ecSmrg *Copyright (C) 1994-2000 The XFree86 Project, Inc. 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 THE XFREE86 PROJECT 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 the XFree86 Project
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 the XFree86 Project.
2705b261ecSmrg *
2805b261ecSmrg * Authors:	Dakshinamurthy Karra
2905b261ecSmrg *		Suhaib M Siddiqi
3005b261ecSmrg *		Peter Busch
3105b261ecSmrg *		Harold L Hunt II
3205b261ecSmrg *		Kensuke Matsuzaki
3305b261ecSmrg */
3405b261ecSmrg
3505b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H
3605b261ecSmrg#include <xwin-config.h>
3705b261ecSmrg#endif
3805b261ecSmrg#include "win.h"
3905b261ecSmrg#include "winmsg.h"
4005b261ecSmrg
4105b261ecSmrg/*
4205b261ecSmrg * Determine what type of screen we are initializing
43ed6184dfSmrg * and call the appropriate procedure to initialize
4405b261ecSmrg * that type of screen.
4505b261ecSmrg */
4605b261ecSmrg
4705b261ecSmrgBool
4835c4bbdfSmrgwinScreenInit(ScreenPtr pScreen, int argc, char **argv)
4905b261ecSmrg{
5035c4bbdfSmrg    winScreenInfoPtr pScreenInfo = &g_ScreenInfo[pScreen->myNum];
5135c4bbdfSmrg    winPrivScreenPtr pScreenPriv;
5235c4bbdfSmrg    HDC hdc;
5335c4bbdfSmrg    DWORD dwInitialBPP;
5405b261ecSmrg
5505b261ecSmrg#if CYGDEBUG || YES
5635c4bbdfSmrg    winDebug("winScreenInit - dwWidth: %u dwHeight: %u\n",
5735c4bbdfSmrg             (unsigned int)pScreenInfo->dwWidth, (unsigned int)pScreenInfo->dwHeight);
5805b261ecSmrg#endif
5905b261ecSmrg
6035c4bbdfSmrg    /* Allocate privates for this screen */
6135c4bbdfSmrg    if (!winAllocatePrivates(pScreen)) {
6235c4bbdfSmrg        ErrorF("winScreenInit - Couldn't allocate screen privates\n");
6335c4bbdfSmrg        return FALSE;
6405b261ecSmrg    }
6505b261ecSmrg
6635c4bbdfSmrg    /* Get a pointer to the privates structure that was allocated */
6735c4bbdfSmrg    pScreenPriv = winGetScreenPriv(pScreen);
6835c4bbdfSmrg
6935c4bbdfSmrg    /* Save a pointer to this screen in the screen info structure */
7035c4bbdfSmrg    pScreenInfo->pScreen = pScreen;
7135c4bbdfSmrg
7235c4bbdfSmrg    /* Save a pointer to the screen info in the screen privates structure */
7335c4bbdfSmrg    /* This allows us to get back to the screen info from a screen pointer */
7435c4bbdfSmrg    pScreenPriv->pScreenInfo = pScreenInfo;
7535c4bbdfSmrg
7635c4bbdfSmrg    /*
7735c4bbdfSmrg     * Determine which engine to use.
7835c4bbdfSmrg     *
7935c4bbdfSmrg     * NOTE: This is done once per screen because each screen possibly has
8035c4bbdfSmrg     * a preferred engine specified on the command line.
8135c4bbdfSmrg     */
8235c4bbdfSmrg    if (!winSetEngine(pScreen)) {
8335c4bbdfSmrg        ErrorF("winScreenInit - winSetEngine () failed\n");
8435c4bbdfSmrg        return FALSE;
8505b261ecSmrg    }
8605b261ecSmrg
8735c4bbdfSmrg    /* Horribly misnamed function: Allow engine to adjust BPP for screen */
8835c4bbdfSmrg    dwInitialBPP = pScreenInfo->dwBPP;
899ace9065Smrg
9035c4bbdfSmrg    if (!(*pScreenPriv->pwinAdjustVideoMode) (pScreen)) {
9135c4bbdfSmrg        ErrorF("winScreenInit - winAdjustVideoMode () failed\n");
9235c4bbdfSmrg        return FALSE;
9305b261ecSmrg    }
9405b261ecSmrg
9535c4bbdfSmrg    if (dwInitialBPP == WIN_DEFAULT_BPP) {
9635c4bbdfSmrg        /* No -depth parameter was passed, let the user know the depth being used */
9735c4bbdfSmrg        ErrorF
9835c4bbdfSmrg            ("winScreenInit - Using Windows display depth of %d bits per pixel\n",
9935c4bbdfSmrg             (int) pScreenInfo->dwBPP);
1009ace9065Smrg    }
10135c4bbdfSmrg    else if (dwInitialBPP != pScreenInfo->dwBPP) {
10235c4bbdfSmrg        /* Warn user if engine forced a depth different to -depth parameter */
10335c4bbdfSmrg        ErrorF
104ed6184dfSmrg            ("winScreenInit - Command line depth of %d bpp overridden by engine, using %d bpp\n",
10535c4bbdfSmrg             (int) dwInitialBPP, (int) pScreenInfo->dwBPP);
1069ace9065Smrg    }
10735c4bbdfSmrg    else {
10835c4bbdfSmrg        ErrorF("winScreenInit - Using command line depth of %d bpp\n",
10935c4bbdfSmrg               (int) pScreenInfo->dwBPP);
1109ace9065Smrg    }
1119ace9065Smrg
11235c4bbdfSmrg    /* Check for supported display depth */
11335c4bbdfSmrg    if (!(WIN_SUPPORTED_BPPS & (1 << (pScreenInfo->dwBPP - 1)))) {
11435c4bbdfSmrg        ErrorF("winScreenInit - Unsupported display depth: %d\n"
11535c4bbdfSmrg               "Change your Windows display depth to 15, 16, 24, or 32 bits "
11635c4bbdfSmrg               "per pixel.\n", (int) pScreenInfo->dwBPP);
11735c4bbdfSmrg        ErrorF("winScreenInit - Supported depths: %08x\n", WIN_SUPPORTED_BPPS);
11805b261ecSmrg#if WIN_CHECK_DEPTH
11935c4bbdfSmrg        return FALSE;
12005b261ecSmrg#endif
12105b261ecSmrg    }
12205b261ecSmrg
12335c4bbdfSmrg    /*
12435c4bbdfSmrg     * Check that all monitors have the same display depth if we are using
12535c4bbdfSmrg     * multiple monitors
12635c4bbdfSmrg     */
12735c4bbdfSmrg    if (pScreenInfo->fMultipleMonitors
12835c4bbdfSmrg        && !GetSystemMetrics(SM_SAMEDISPLAYFORMAT)) {
12935c4bbdfSmrg        ErrorF("winScreenInit - Monitors do not all have same pixel format / "
13035c4bbdfSmrg               "display depth.\n");
13135c4bbdfSmrg        if (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI) {
13235c4bbdfSmrg            ErrorF
13335c4bbdfSmrg                ("winScreenInit - Performance may suffer off primary display.\n");
1349ace9065Smrg        }
13535c4bbdfSmrg        else {
13635c4bbdfSmrg            ErrorF("winScreenInit - Using primary display only.\n");
13735c4bbdfSmrg            pScreenInfo->fMultipleMonitors = FALSE;
1389ace9065Smrg        }
13905b261ecSmrg    }
14005b261ecSmrg
14135c4bbdfSmrg    /* Create display window */
14235c4bbdfSmrg    if (!(*pScreenPriv->pwinCreateBoundingWindow) (pScreen)) {
14335c4bbdfSmrg        ErrorF("winScreenInit - pwinCreateBoundingWindow () " "failed\n");
14435c4bbdfSmrg        return FALSE;
14505b261ecSmrg    }
14605b261ecSmrg
14735c4bbdfSmrg    /* Get a device context */
14835c4bbdfSmrg    hdc = GetDC(pScreenPriv->hwndScreen);
14935c4bbdfSmrg
15035c4bbdfSmrg    /* Are we using multiple monitors? */
15135c4bbdfSmrg    if (pScreenInfo->fMultipleMonitors) {
15235c4bbdfSmrg        /*
15335c4bbdfSmrg         * In this case, some of the defaults set in
15435c4bbdfSmrg         * winInitializeScreenDefaults() are not correct ...
15535c4bbdfSmrg         */
15635c4bbdfSmrg        if (!pScreenInfo->fUserGaveHeightAndWidth) {
15735c4bbdfSmrg            pScreenInfo->dwWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
15835c4bbdfSmrg            pScreenInfo->dwHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
15935c4bbdfSmrg        }
16005b261ecSmrg    }
16105b261ecSmrg
16235c4bbdfSmrg    /* Release the device context */
16335c4bbdfSmrg    ReleaseDC(pScreenPriv->hwndScreen, hdc);
16435c4bbdfSmrg
16535c4bbdfSmrg    /* Clear the visuals list */
16635c4bbdfSmrg    miClearVisualTypes();
16735c4bbdfSmrg
16835c4bbdfSmrg    /* Call the engine dependent screen initialization procedure */
16935c4bbdfSmrg    if (!((*pScreenPriv->pwinFinishScreenInit) (pScreen->myNum, pScreen, argc, argv))) {
17035c4bbdfSmrg        ErrorF("winScreenInit - winFinishScreenInit () failed\n");
17135c4bbdfSmrg
17235c4bbdfSmrg        /* call the engine dependent screen close procedure to clean up from a failure */
17335c4bbdfSmrg        pScreenPriv->pwinCloseScreen(pScreen);
17435c4bbdfSmrg
17535c4bbdfSmrg        return FALSE;
17605b261ecSmrg    }
17705b261ecSmrg
17835c4bbdfSmrg    if (!g_fSoftwareCursor)
17935c4bbdfSmrg        winInitCursor(pScreen);
18035c4bbdfSmrg    else
18135c4bbdfSmrg        winErrorFVerb(2, "winScreenInit - Using software cursor\n");
18205b261ecSmrg
18335c4bbdfSmrg    if (!noPanoramiXExtension) {
18435c4bbdfSmrg        /*
18535c4bbdfSmrg           Note the screen origin in a normalized coordinate space where (0,0) is at the top left
18635c4bbdfSmrg           of the native virtual desktop area
18735c4bbdfSmrg         */
18835c4bbdfSmrg        pScreen->x =
18935c4bbdfSmrg            pScreenInfo->dwInitialX - GetSystemMetrics(SM_XVIRTUALSCREEN);
19035c4bbdfSmrg        pScreen->y =
19135c4bbdfSmrg            pScreenInfo->dwInitialY - GetSystemMetrics(SM_YVIRTUALSCREEN);
1926747b715Smrg
19335c4bbdfSmrg        ErrorF("Screen %d added at virtual desktop coordinate (%d,%d).\n",
19435c4bbdfSmrg               pScreen->myNum, pScreen->x, pScreen->y);
19535c4bbdfSmrg    }
1966747b715Smrg
19705b261ecSmrg#if CYGDEBUG || YES
19835c4bbdfSmrg    winDebug("winScreenInit - returning\n");
19905b261ecSmrg#endif
20005b261ecSmrg
20135c4bbdfSmrg    return TRUE;
20205b261ecSmrg}
20305b261ecSmrg
2046747b715Smrgstatic Bool
2056747b715SmrgwinCreateScreenResources(ScreenPtr pScreen)
2066747b715Smrg{
20735c4bbdfSmrg    winScreenPriv(pScreen);
20835c4bbdfSmrg    Bool result;
20935c4bbdfSmrg
21035c4bbdfSmrg    result = pScreenPriv->pwinCreateScreenResources(pScreen);
21135c4bbdfSmrg
21235c4bbdfSmrg    /* Now the screen bitmap has been wrapped in a pixmap,
21335c4bbdfSmrg       add that to the Shadow framebuffer */
21435c4bbdfSmrg    if (!shadowAdd(pScreen, pScreen->devPrivate,
21535c4bbdfSmrg                   pScreenPriv->pwinShadowUpdate, NULL, 0, 0)) {
21635c4bbdfSmrg        ErrorF("winCreateScreenResources - shadowAdd () failed\n");
21735c4bbdfSmrg        return FALSE;
2186747b715Smrg    }
2196747b715Smrg
22035c4bbdfSmrg    return result;
2216747b715Smrg}
22205b261ecSmrg
22305b261ecSmrg/* See Porting Layer Definition - p. 20 */
22405b261ecSmrgBool
22535c4bbdfSmrgwinFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv)
22605b261ecSmrg{
22735c4bbdfSmrg    winScreenPriv(pScreen);
22835c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
22935c4bbdfSmrg    VisualPtr pVisual = NULL;
23035c4bbdfSmrg
23135c4bbdfSmrg    int iReturn;
23205b261ecSmrg
23335c4bbdfSmrg    /* Create framebuffer */
23435c4bbdfSmrg    if (!(*pScreenPriv->pwinInitScreen) (pScreen)) {
23535c4bbdfSmrg        ErrorF("winFinishScreenInitFB - Could not allocate framebuffer\n");
23635c4bbdfSmrg        return FALSE;
23735c4bbdfSmrg    }
23835c4bbdfSmrg
23935c4bbdfSmrg    /*
24035c4bbdfSmrg     * Calculate the number of bits that are used to represent color in each pixel,
24135c4bbdfSmrg     * the color depth for the screen
24235c4bbdfSmrg     */
24335c4bbdfSmrg    if (pScreenInfo->dwBPP == 8)
24435c4bbdfSmrg        pScreenInfo->dwDepth = 8;
24535c4bbdfSmrg    else
24635c4bbdfSmrg        pScreenInfo->dwDepth = winCountBits(pScreenPriv->dwRedMask)
24735c4bbdfSmrg            + winCountBits(pScreenPriv->dwGreenMask)
24835c4bbdfSmrg            + winCountBits(pScreenPriv->dwBlueMask);
24935c4bbdfSmrg
25035c4bbdfSmrg    winErrorFVerb(2, "winFinishScreenInitFB - Masks: %08x %08x %08x\n",
25135c4bbdfSmrg                  (unsigned int) pScreenPriv->dwRedMask,
25235c4bbdfSmrg                  (unsigned int) pScreenPriv->dwGreenMask,
25335c4bbdfSmrg                  (unsigned int) pScreenPriv->dwBlueMask);
25435c4bbdfSmrg
25535c4bbdfSmrg    /* Init visuals */
25635c4bbdfSmrg    if (!(*pScreenPriv->pwinInitVisuals) (pScreen)) {
25735c4bbdfSmrg        ErrorF("winFinishScreenInitFB - winInitVisuals failed\n");
25835c4bbdfSmrg        return FALSE;
25935c4bbdfSmrg    }
26035c4bbdfSmrg
261ed6184dfSmrg    if ((pScreenInfo->dwBPP == 8) && (pScreenInfo->fCompositeWM)) {
262ed6184dfSmrg        ErrorF("-compositewm disabled due to 8bpp depth\n");
263ed6184dfSmrg        pScreenInfo->fCompositeWM = FALSE;
264ed6184dfSmrg    }
265ed6184dfSmrg
26635c4bbdfSmrg    /* Apparently we need this for the render extension */
26735c4bbdfSmrg    miSetPixmapDepths();
26835c4bbdfSmrg
26935c4bbdfSmrg    /* Start fb initialization */
27035c4bbdfSmrg    if (!fbSetupScreen(pScreen,
27135c4bbdfSmrg                       pScreenInfo->pfb,
27235c4bbdfSmrg                       pScreenInfo->dwWidth, pScreenInfo->dwHeight,
27335c4bbdfSmrg                       monitorResolution, monitorResolution,
27435c4bbdfSmrg                       pScreenInfo->dwStride, pScreenInfo->dwBPP)) {
27535c4bbdfSmrg        ErrorF("winFinishScreenInitFB - fbSetupScreen failed\n");
27635c4bbdfSmrg        return FALSE;
27735c4bbdfSmrg    }
27835c4bbdfSmrg
27935c4bbdfSmrg    /* Override default colormap routines if visual class is dynamic */
28035c4bbdfSmrg    if (pScreenInfo->dwDepth == 8
28135c4bbdfSmrg        && (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI
28235c4bbdfSmrg            || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
28335c4bbdfSmrg                && pScreenInfo->fFullScreen))) {
28435c4bbdfSmrg        winSetColormapFunctions(pScreen);
28535c4bbdfSmrg
28635c4bbdfSmrg        /*
28735c4bbdfSmrg         * NOTE: Setting whitePixel to 255 causes Magic 7.1 to allocate its
28835c4bbdfSmrg         * own colormap, as it cannot allocate 7 planes in the default
28935c4bbdfSmrg         * colormap.  Setting whitePixel to 1 allows Magic to get 7
29035c4bbdfSmrg         * planes in the default colormap, so it doesn't create its
291ed6184dfSmrg         * own colormap.  This latter situation is highly desirable,
29235c4bbdfSmrg         * as it keeps the Magic window viewable when switching to
29335c4bbdfSmrg         * other X clients that use the default colormap.
29435c4bbdfSmrg         */
29535c4bbdfSmrg        pScreen->blackPixel = 0;
29635c4bbdfSmrg        pScreen->whitePixel = 1;
29735c4bbdfSmrg    }
29835c4bbdfSmrg
29935c4bbdfSmrg    /* Finish fb initialization */
30035c4bbdfSmrg    if (!fbFinishScreenInit(pScreen,
30135c4bbdfSmrg                            pScreenInfo->pfb,
30235c4bbdfSmrg                            pScreenInfo->dwWidth, pScreenInfo->dwHeight,
30335c4bbdfSmrg                            monitorResolution, monitorResolution,
30435c4bbdfSmrg                            pScreenInfo->dwStride, pScreenInfo->dwBPP)) {
30535c4bbdfSmrg        ErrorF("winFinishScreenInitFB - fbFinishScreenInit failed\n");
30635c4bbdfSmrg        return FALSE;
30735c4bbdfSmrg    }
30835c4bbdfSmrg
30935c4bbdfSmrg    /* Save a pointer to the root visual */
31035c4bbdfSmrg    for (pVisual = pScreen->visuals;
31135c4bbdfSmrg         pVisual->vid != pScreen->rootVisual; pVisual++);
31235c4bbdfSmrg    pScreenPriv->pRootVisual = pVisual;
31335c4bbdfSmrg
31435c4bbdfSmrg    /*
31535c4bbdfSmrg     * Setup points to the block and wakeup handlers.  Pass a pointer
31635c4bbdfSmrg     * to the current screen as pWakeupdata.
31735c4bbdfSmrg     */
31835c4bbdfSmrg    pScreen->BlockHandler = winBlockHandler;
31935c4bbdfSmrg    pScreen->WakeupHandler = winWakeupHandler;
32035c4bbdfSmrg
32135c4bbdfSmrg    /* Render extension initialization, calls miPictureInit */
32235c4bbdfSmrg    if (!fbPictureInit(pScreen, NULL, 0)) {
32335c4bbdfSmrg        ErrorF("winFinishScreenInitFB - fbPictureInit () failed\n");
32435c4bbdfSmrg        return FALSE;
32505b261ecSmrg    }
32605b261ecSmrg
32705b261ecSmrg#ifdef RANDR
32835c4bbdfSmrg    /* Initialize resize and rotate support */
32935c4bbdfSmrg    if (!winRandRInit(pScreen)) {
33035c4bbdfSmrg        ErrorF("winFinishScreenInitFB - winRandRInit () failed\n");
33135c4bbdfSmrg        return FALSE;
33205b261ecSmrg    }
33305b261ecSmrg#endif
33405b261ecSmrg
33535c4bbdfSmrg    /* Setup the cursor routines */
33605b261ecSmrg#if CYGDEBUG
33735c4bbdfSmrg    winDebug("winFinishScreenInitFB - Calling miDCInitialize ()\n");
33805b261ecSmrg#endif
33935c4bbdfSmrg    miDCInitialize(pScreen, &g_winPointerCursorFuncs);
34005b261ecSmrg
34135c4bbdfSmrg    /* KDrive does winCreateDefColormap right after miDCInitialize */
34235c4bbdfSmrg    /* Create a default colormap */
34305b261ecSmrg#if CYGDEBUG
34435c4bbdfSmrg    winDebug("winFinishScreenInitFB - Calling winCreateDefColormap ()\n");
34505b261ecSmrg#endif
34635c4bbdfSmrg    if (!winCreateDefColormap(pScreen)) {
34735c4bbdfSmrg        ErrorF("winFinishScreenInitFB - Could not create colormap\n");
34835c4bbdfSmrg        return FALSE;
34905b261ecSmrg    }
35005b261ecSmrg
35135c4bbdfSmrg    /* Initialize the shadow framebuffer layer */
35235c4bbdfSmrg    if ((pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI
353ed6184dfSmrg         || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)) {
35405b261ecSmrg#if CYGDEBUG
35535c4bbdfSmrg        winDebug("winFinishScreenInitFB - Calling shadowSetup ()\n");
35605b261ecSmrg#endif
35735c4bbdfSmrg        if (!shadowSetup(pScreen)) {
35835c4bbdfSmrg            ErrorF("winFinishScreenInitFB - shadowSetup () failed\n");
35935c4bbdfSmrg            return FALSE;
36035c4bbdfSmrg        }
36135c4bbdfSmrg
36235c4bbdfSmrg        /* Wrap CreateScreenResources so we can add the screen pixmap
36335c4bbdfSmrg           to the Shadow framebuffer after it's been created */
36435c4bbdfSmrg        pScreenPriv->pwinCreateScreenResources = pScreen->CreateScreenResources;
36535c4bbdfSmrg        pScreen->CreateScreenResources = winCreateScreenResources;
36605b261ecSmrg    }
36705b261ecSmrg
36835c4bbdfSmrg    /* Handle rootless mode */
36935c4bbdfSmrg    if (pScreenInfo->fRootless) {
37035c4bbdfSmrg        /* Define the WRAP macro temporarily for local use */
37105b261ecSmrg#define WRAP(a) \
37205b261ecSmrg    if (pScreen->a) { \
37305b261ecSmrg        pScreenPriv->a = pScreen->a; \
37405b261ecSmrg    } else { \
37535c4bbdfSmrg        winDebug("winScreenInit - null screen fn " #a "\n"); \
37605b261ecSmrg        pScreenPriv->a = NULL; \
37705b261ecSmrg    }
37805b261ecSmrg
37935c4bbdfSmrg        /* Save a pointer to each lower-level window procedure */
38035c4bbdfSmrg        WRAP(CreateWindow);
38135c4bbdfSmrg        WRAP(DestroyWindow);
38235c4bbdfSmrg        WRAP(RealizeWindow);
38335c4bbdfSmrg        WRAP(UnrealizeWindow);
38435c4bbdfSmrg        WRAP(PositionWindow);
38535c4bbdfSmrg        WRAP(ChangeWindowAttributes);
38635c4bbdfSmrg        WRAP(SetShape);
38735c4bbdfSmrg
38835c4bbdfSmrg        /* Assign rootless window procedures to be top level procedures */
38935c4bbdfSmrg        pScreen->CreateWindow = winCreateWindowRootless;
39035c4bbdfSmrg        pScreen->DestroyWindow = winDestroyWindowRootless;
39135c4bbdfSmrg        pScreen->PositionWindow = winPositionWindowRootless;
39235c4bbdfSmrg        /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesRootless; */
39335c4bbdfSmrg        pScreen->RealizeWindow = winMapWindowRootless;
39435c4bbdfSmrg        pScreen->UnrealizeWindow = winUnmapWindowRootless;
39535c4bbdfSmrg        pScreen->SetShape = winSetShapeRootless;
39635c4bbdfSmrg
39735c4bbdfSmrg        /* Undefine the WRAP macro, as it is not needed elsewhere */
39805b261ecSmrg#undef WRAP
39905b261ecSmrg    }
40005b261ecSmrg
40135c4bbdfSmrg    /* Handle multi window mode */
40235c4bbdfSmrg    else if (pScreenInfo->fMultiWindow) {
40335c4bbdfSmrg        /* Define the WRAP macro temporarily for local use */
40405b261ecSmrg#define WRAP(a) \
40505b261ecSmrg    if (pScreen->a) { \
40605b261ecSmrg        pScreenPriv->a = pScreen->a; \
40705b261ecSmrg    } else { \
40835c4bbdfSmrg        winDebug("null screen fn " #a "\n"); \
40905b261ecSmrg        pScreenPriv->a = NULL; \
41005b261ecSmrg    }
41105b261ecSmrg
41235c4bbdfSmrg        /* Save a pointer to each lower-level window procedure */
41335c4bbdfSmrg        WRAP(CreateWindow);
41435c4bbdfSmrg        WRAP(DestroyWindow);
41535c4bbdfSmrg        WRAP(RealizeWindow);
41635c4bbdfSmrg        WRAP(UnrealizeWindow);
41735c4bbdfSmrg        WRAP(PositionWindow);
41835c4bbdfSmrg        WRAP(ChangeWindowAttributes);
41935c4bbdfSmrg        WRAP(ReparentWindow);
42035c4bbdfSmrg        WRAP(RestackWindow);
42135c4bbdfSmrg        WRAP(ResizeWindow);
42235c4bbdfSmrg        WRAP(MoveWindow);
42335c4bbdfSmrg        WRAP(CopyWindow);
42435c4bbdfSmrg        WRAP(SetShape);
425ed6184dfSmrg        WRAP(ModifyPixmapHeader);
42635c4bbdfSmrg
42735c4bbdfSmrg        /* Assign multi-window window procedures to be top level procedures */
42835c4bbdfSmrg        pScreen->CreateWindow = winCreateWindowMultiWindow;
42935c4bbdfSmrg        pScreen->DestroyWindow = winDestroyWindowMultiWindow;
43035c4bbdfSmrg        pScreen->PositionWindow = winPositionWindowMultiWindow;
43135c4bbdfSmrg        /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesMultiWindow; */
43235c4bbdfSmrg        pScreen->RealizeWindow = winMapWindowMultiWindow;
43335c4bbdfSmrg        pScreen->UnrealizeWindow = winUnmapWindowMultiWindow;
43435c4bbdfSmrg        pScreen->ReparentWindow = winReparentWindowMultiWindow;
43535c4bbdfSmrg        pScreen->RestackWindow = winRestackWindowMultiWindow;
43635c4bbdfSmrg        pScreen->ResizeWindow = winResizeWindowMultiWindow;
43735c4bbdfSmrg        pScreen->MoveWindow = winMoveWindowMultiWindow;
43835c4bbdfSmrg        pScreen->CopyWindow = winCopyWindowMultiWindow;
43935c4bbdfSmrg        pScreen->SetShape = winSetShapeMultiWindow;
44035c4bbdfSmrg
441ed6184dfSmrg        if (pScreenInfo->fCompositeWM) {
442ed6184dfSmrg            pScreen->CreatePixmap = winCreatePixmapMultiwindow;
443ed6184dfSmrg            pScreen->DestroyPixmap = winDestroyPixmapMultiwindow;
444ed6184dfSmrg            pScreen->ModifyPixmapHeader = winModifyPixmapHeaderMultiwindow;
445ed6184dfSmrg        }
446ed6184dfSmrg
44735c4bbdfSmrg        /* Undefine the WRAP macro, as it is not needed elsewhere */
44805b261ecSmrg#undef WRAP
44905b261ecSmrg    }
45005b261ecSmrg
45135c4bbdfSmrg    /* Wrap either fb's or shadow's CloseScreen with our CloseScreen */
45235c4bbdfSmrg    pScreenPriv->CloseScreen = pScreen->CloseScreen;
45335c4bbdfSmrg    pScreen->CloseScreen = pScreenPriv->pwinCloseScreen;
45405b261ecSmrg
45535c4bbdfSmrg    /* Create a mutex for modules in separate threads to wait for */
45635c4bbdfSmrg    iReturn = pthread_mutex_init(&pScreenPriv->pmServerStarted, NULL);
45735c4bbdfSmrg    if (iReturn != 0) {
45835c4bbdfSmrg        ErrorF("winFinishScreenInitFB - pthread_mutex_init () failed: %d\n",
45935c4bbdfSmrg               iReturn);
46035c4bbdfSmrg        return FALSE;
46105b261ecSmrg    }
46205b261ecSmrg
46335c4bbdfSmrg    /* Own the mutex for modules in separate threads */
46435c4bbdfSmrg    iReturn = pthread_mutex_lock(&pScreenPriv->pmServerStarted);
46535c4bbdfSmrg    if (iReturn != 0) {
46635c4bbdfSmrg        ErrorF("winFinishScreenInitFB - pthread_mutex_lock () failed: %d\n",
46735c4bbdfSmrg               iReturn);
46835c4bbdfSmrg        return FALSE;
46905b261ecSmrg    }
47005b261ecSmrg
47135c4bbdfSmrg    /* Set the ServerStarted flag to false */
47235c4bbdfSmrg    pScreenPriv->fServerStarted = FALSE;
47305b261ecSmrg
47405b261ecSmrg
4751b5d61b8Smrg    if (pScreenInfo->fMultiWindow) {
47605b261ecSmrg#if CYGDEBUG || YES
47735c4bbdfSmrg        winDebug("winFinishScreenInitFB - Calling winInitWM.\n");
47805b261ecSmrg#endif
47905b261ecSmrg
48035c4bbdfSmrg        /* Initialize multi window mode */
48135c4bbdfSmrg        if (!winInitWM(&pScreenPriv->pWMInfo,
48235c4bbdfSmrg                       &pScreenPriv->ptWMProc,
48335c4bbdfSmrg                       &pScreenPriv->ptXMsgProc,
48435c4bbdfSmrg                       &pScreenPriv->pmServerStarted,
4851b5d61b8Smrg                       pScreenInfo->dwScreen,
486ed6184dfSmrg                       (HWND) &pScreenPriv->hwndScreen,
487ed6184dfSmrg                       pScreenInfo->fCompositeWM)) {
48835c4bbdfSmrg            ErrorF("winFinishScreenInitFB - winInitWM () failed.\n");
48935c4bbdfSmrg            return FALSE;
49005b261ecSmrg        }
49135c4bbdfSmrg    }
49205b261ecSmrg
49335c4bbdfSmrg    /* Tell the server that we are enabled */
49435c4bbdfSmrg    pScreenPriv->fEnabled = TRUE;
49505b261ecSmrg
49635c4bbdfSmrg    /* Tell the server that we have a valid depth */
49735c4bbdfSmrg    pScreenPriv->fBadDepth = FALSE;
49805b261ecSmrg
49905b261ecSmrg#if CYGDEBUG || YES
50035c4bbdfSmrg    winDebug("winFinishScreenInitFB - returning\n");
50105b261ecSmrg#endif
50205b261ecSmrg
50335c4bbdfSmrg    return TRUE;
50405b261ecSmrg}
505