wincreatewnd.c revision ed6184df
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 "shellapi.h"
3605b261ecSmrg
3705b261ecSmrg/*
3805b261ecSmrg * Local function prototypes
3905b261ecSmrg */
4005b261ecSmrg
4105b261ecSmrgstatic Bool
4235c4bbdfSmrg winGetWorkArea(RECT * prcWorkArea, winScreenInfo * pScreenInfo);
4305b261ecSmrg
4405b261ecSmrgstatic Bool
4535c4bbdfSmrg winAdjustForAutoHide(RECT * prcWorkArea, winScreenInfo * pScreenInfo);
4605b261ecSmrg
4705b261ecSmrg/*
4805b261ecSmrg * Create a full screen window
4905b261ecSmrg */
5005b261ecSmrg
5105b261ecSmrgBool
5235c4bbdfSmrgwinCreateBoundingWindowFullScreen(ScreenPtr pScreen)
5305b261ecSmrg{
5435c4bbdfSmrg    winScreenPriv(pScreen);
5535c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
5635c4bbdfSmrg    int iX = pScreenInfo->dwInitialX;
5735c4bbdfSmrg    int iY = pScreenInfo->dwInitialY;
5835c4bbdfSmrg    int iWidth = pScreenInfo->dwWidth;
5935c4bbdfSmrg    int iHeight = pScreenInfo->dwHeight;
6035c4bbdfSmrg    HWND *phwnd = &pScreenPriv->hwndScreen;
6135c4bbdfSmrg    WNDCLASSEX wc;
6235c4bbdfSmrg    char szTitle[256];
6305b261ecSmrg
6405b261ecSmrg#if CYGDEBUG
6535c4bbdfSmrg    winDebug("winCreateBoundingWindowFullScreen\n");
6605b261ecSmrg#endif
6705b261ecSmrg
6835c4bbdfSmrg    /* Setup our window class */
6935c4bbdfSmrg    wc.cbSize = sizeof(WNDCLASSEX);
7035c4bbdfSmrg    wc.style = CS_HREDRAW | CS_VREDRAW;
7135c4bbdfSmrg    wc.lpfnWndProc = winWindowProc;
7235c4bbdfSmrg    wc.cbClsExtra = 0;
7335c4bbdfSmrg    wc.cbWndExtra = 0;
7435c4bbdfSmrg    wc.hInstance = g_hInstance;
75ed6184dfSmrg    wc.hIcon = pScreenInfo->hIcon;
7635c4bbdfSmrg    wc.hCursor = 0;
7735c4bbdfSmrg    wc.hbrBackground = 0;
7835c4bbdfSmrg    wc.lpszMenuName = NULL;
7935c4bbdfSmrg    wc.lpszClassName = WINDOW_CLASS;
80ed6184dfSmrg    wc.hIconSm = pScreenInfo->hIconSm;
8135c4bbdfSmrg    RegisterClassEx(&wc);
8235c4bbdfSmrg
8335c4bbdfSmrg    /* Set display and screen-specific tooltip text */
8435c4bbdfSmrg    if (g_pszQueryHost != NULL)
8535c4bbdfSmrg        snprintf(szTitle,
8635c4bbdfSmrg                 sizeof(szTitle),
8735c4bbdfSmrg                 WINDOW_TITLE_XDMCP,
8835c4bbdfSmrg                 g_pszQueryHost, display, (int) pScreenInfo->dwScreen);
8935c4bbdfSmrg    else
9035c4bbdfSmrg        snprintf(szTitle,
9135c4bbdfSmrg                 sizeof(szTitle),
9235c4bbdfSmrg                 WINDOW_TITLE, display, (int) pScreenInfo->dwScreen);
9335c4bbdfSmrg
9435c4bbdfSmrg    /* Create the window */
9535c4bbdfSmrg    *phwnd = CreateWindowExA(0, /* Extended styles */
9635c4bbdfSmrg                             WINDOW_CLASS,      /* Class name */
9735c4bbdfSmrg                             szTitle,   /* Window name */
9835c4bbdfSmrg                             WS_POPUP, iX,      /* Horizontal position */
9935c4bbdfSmrg                             iY,        /* Vertical position */
10035c4bbdfSmrg                             iWidth,    /* Right edge */
10135c4bbdfSmrg                             iHeight,   /* Bottom edge */
10235c4bbdfSmrg                             (HWND) NULL,       /* No parent or owner window */
10335c4bbdfSmrg                             (HMENU) NULL,      /* No menu */
10435c4bbdfSmrg                             GetModuleHandle(NULL),     /* Instance handle */
10535c4bbdfSmrg                             pScreenPriv);      /* ScreenPrivates */
10635c4bbdfSmrg
10735c4bbdfSmrg    /* Hide the window */
10835c4bbdfSmrg    ShowWindow(*phwnd, SW_SHOWNORMAL);
10935c4bbdfSmrg
11035c4bbdfSmrg    /* Send first paint message */
11135c4bbdfSmrg    UpdateWindow(*phwnd);
11235c4bbdfSmrg
11335c4bbdfSmrg    /* Attempt to bring our window to the top of the display */
11435c4bbdfSmrg    BringWindowToTop(*phwnd);
11505b261ecSmrg
11635c4bbdfSmrg    return TRUE;
11705b261ecSmrg}
11805b261ecSmrg
11905b261ecSmrg/*
12005b261ecSmrg * Create our primary Windows display window
12105b261ecSmrg */
12205b261ecSmrg
12305b261ecSmrgBool
12435c4bbdfSmrgwinCreateBoundingWindowWindowed(ScreenPtr pScreen)
12505b261ecSmrg{
12635c4bbdfSmrg    winScreenPriv(pScreen);
12735c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
12835c4bbdfSmrg    int iWidth = pScreenInfo->dwUserWidth;
12935c4bbdfSmrg    int iHeight = pScreenInfo->dwUserHeight;
13035c4bbdfSmrg    int iPosX;
13135c4bbdfSmrg    int iPosY;
13235c4bbdfSmrg    HWND *phwnd = &pScreenPriv->hwndScreen;
13335c4bbdfSmrg    WNDCLASSEX wc;
13435c4bbdfSmrg    RECT rcClient, rcWorkArea;
13535c4bbdfSmrg    DWORD dwWindowStyle;
13635c4bbdfSmrg    BOOL fForceShowWindow = FALSE;
13735c4bbdfSmrg    char szTitle[256];
13835c4bbdfSmrg
13935c4bbdfSmrg    winDebug("winCreateBoundingWindowWindowed - User w: %d h: %d\n",
14035c4bbdfSmrg             (int) pScreenInfo->dwUserWidth, (int) pScreenInfo->dwUserHeight);
14135c4bbdfSmrg    winDebug("winCreateBoundingWindowWindowed - Current w: %d h: %d\n",
14235c4bbdfSmrg             (int) pScreenInfo->dwWidth, (int) pScreenInfo->dwHeight);
14335c4bbdfSmrg
14435c4bbdfSmrg    /* Set the common window style flags */
14535c4bbdfSmrg    dwWindowStyle = WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX;
14635c4bbdfSmrg
14735c4bbdfSmrg    /* Decorated or undecorated window */
14835c4bbdfSmrg    if (pScreenInfo->fDecoration
14935c4bbdfSmrg        && !pScreenInfo->fRootless
15035c4bbdfSmrg        && !pScreenInfo->fMultiWindow
15135c4bbdfSmrg        ) {
15235c4bbdfSmrg        /* Try to handle startup via run.exe. run.exe instructs Windows to
15335c4bbdfSmrg         * hide all created windows. Detect this case and make sure the
15405b261ecSmrg         * window is shown nevertheless */
15535c4bbdfSmrg        STARTUPINFO startupInfo;
15635c4bbdfSmrg
15705b261ecSmrg        GetStartupInfo(&startupInfo);
15835c4bbdfSmrg        if (startupInfo.dwFlags & STARTF_USESHOWWINDOW &&
15935c4bbdfSmrg            startupInfo.wShowWindow == SW_HIDE) {
16035c4bbdfSmrg            fForceShowWindow = TRUE;
16135c4bbdfSmrg        }
16205b261ecSmrg        dwWindowStyle |= WS_CAPTION;
1631b5d61b8Smrg        if (pScreenInfo->iResizeMode != resizeNotAllowed)
16405b261ecSmrg            dwWindowStyle |= WS_THICKFRAME | WS_MAXIMIZEBOX;
16505b261ecSmrg    }
16635c4bbdfSmrg    else
16735c4bbdfSmrg        dwWindowStyle |= WS_POPUP;
16835c4bbdfSmrg
16935c4bbdfSmrg    /* Setup our window class */
17035c4bbdfSmrg    wc.cbSize = sizeof(WNDCLASSEX);
17135c4bbdfSmrg    wc.style = CS_HREDRAW | CS_VREDRAW;
17235c4bbdfSmrg    wc.lpfnWndProc = winWindowProc;
17335c4bbdfSmrg    wc.cbClsExtra = 0;
17435c4bbdfSmrg    wc.cbWndExtra = 0;
17535c4bbdfSmrg    wc.hInstance = g_hInstance;
176ed6184dfSmrg    wc.hIcon = pScreenInfo->hIcon;
17735c4bbdfSmrg    wc.hCursor = 0;
17835c4bbdfSmrg    wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
17935c4bbdfSmrg    wc.lpszMenuName = NULL;
18035c4bbdfSmrg    wc.lpszClassName = WINDOW_CLASS;
181ed6184dfSmrg    wc.hIconSm = pScreenInfo->hIconSm;
18235c4bbdfSmrg    RegisterClassEx(&wc);
18335c4bbdfSmrg
18435c4bbdfSmrg    /* Get size of work area */
18535c4bbdfSmrg    winGetWorkArea(&rcWorkArea, pScreenInfo);
18635c4bbdfSmrg
18735c4bbdfSmrg    /* Adjust for auto-hide taskbars */
18835c4bbdfSmrg    winAdjustForAutoHide(&rcWorkArea, pScreenInfo);
18935c4bbdfSmrg
19035c4bbdfSmrg    /* Did the user specify a position? */
19135c4bbdfSmrg    if (pScreenInfo->fUserGavePosition) {
19235c4bbdfSmrg        iPosX = pScreenInfo->dwInitialX;
19335c4bbdfSmrg        iPosY = pScreenInfo->dwInitialY;
19405b261ecSmrg    }
19535c4bbdfSmrg    else {
19635c4bbdfSmrg        iPosX = rcWorkArea.left;
19735c4bbdfSmrg        iPosY = rcWorkArea.top;
19805b261ecSmrg    }
19905b261ecSmrg
20035c4bbdfSmrg    /* Clean up the scrollbars flag, if necessary */
20135c4bbdfSmrg    if ((!pScreenInfo->fDecoration
20235c4bbdfSmrg         || pScreenInfo->fRootless
20335c4bbdfSmrg         || pScreenInfo->fMultiWindow
20435c4bbdfSmrg        )
20535c4bbdfSmrg        && (pScreenInfo->iResizeMode == resizeWithScrollbars)) {
20635c4bbdfSmrg        /* We cannot have scrollbars if we do not have a window border */
2071b5d61b8Smrg        pScreenInfo->iResizeMode = resizeNotAllowed;
2089ace9065Smrg    }
2099ace9065Smrg
21035c4bbdfSmrg    /* Did the user specify a height and width? */
21135c4bbdfSmrg    if (pScreenInfo->fUserGaveHeightAndWidth) {
212ed6184dfSmrg        /* User gave a desired height and width, try to accommodate */
21305b261ecSmrg#if CYGDEBUG
21435c4bbdfSmrg        winDebug("winCreateBoundingWindowWindowed - User gave height "
21535c4bbdfSmrg                 "and width\n");
21605b261ecSmrg#endif
21735c4bbdfSmrg
21835c4bbdfSmrg        /* Adjust the window width and height for borders and title bar */
21935c4bbdfSmrg        if (pScreenInfo->fDecoration
22035c4bbdfSmrg            && !pScreenInfo->fRootless
22135c4bbdfSmrg            && !pScreenInfo->fMultiWindow
22235c4bbdfSmrg            ) {
22305b261ecSmrg#if CYGDEBUG
22435c4bbdfSmrg            winDebug
22535c4bbdfSmrg                ("winCreateBoundingWindowWindowed - Window has decoration\n");
22605b261ecSmrg#endif
2279ace9065Smrg
22835c4bbdfSmrg            /* Are we resizable */
2291b5d61b8Smrg            if (pScreenInfo->iResizeMode != resizeNotAllowed) {
23005b261ecSmrg#if CYGDEBUG
23135c4bbdfSmrg                winDebug
23235c4bbdfSmrg                    ("winCreateBoundingWindowWindowed - Window is resizable\n");
23305b261ecSmrg#endif
23405b261ecSmrg
23535c4bbdfSmrg                iWidth += 2 * GetSystemMetrics(SM_CXSIZEFRAME);
23635c4bbdfSmrg                iHeight += 2 * GetSystemMetrics(SM_CYSIZEFRAME)
23735c4bbdfSmrg                    + GetSystemMetrics(SM_CYCAPTION);
23835c4bbdfSmrg            }
23935c4bbdfSmrg            else {
24005b261ecSmrg#if CYGDEBUG
24135c4bbdfSmrg                winDebug
24235c4bbdfSmrg                    ("winCreateBoundingWindowWindowed - Window is not resizable\n");
24305b261ecSmrg#endif
24405b261ecSmrg
24535c4bbdfSmrg                iWidth += 2 * GetSystemMetrics(SM_CXFIXEDFRAME);
24635c4bbdfSmrg                iHeight += 2 * GetSystemMetrics(SM_CYFIXEDFRAME)
24735c4bbdfSmrg                    + GetSystemMetrics(SM_CYCAPTION);
24835c4bbdfSmrg            }
24935c4bbdfSmrg        }
25005b261ecSmrg    }
25135c4bbdfSmrg    else {
25235c4bbdfSmrg        /* By default, we are creating a window that is as large as possible */
25305b261ecSmrg#if CYGDEBUG
25435c4bbdfSmrg        winDebug("winCreateBoundingWindowWindowed - User did not give "
25535c4bbdfSmrg                 "height and width\n");
25605b261ecSmrg#endif
25735c4bbdfSmrg        /* Defaults are wrong if we have multiple monitors */
25835c4bbdfSmrg        if (pScreenInfo->fMultipleMonitors) {
25935c4bbdfSmrg            iWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
26035c4bbdfSmrg            iHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
26135c4bbdfSmrg        }
26205b261ecSmrg    }
26305b261ecSmrg
26435c4bbdfSmrg    /* Make sure window is no bigger than work area */
26535c4bbdfSmrg    if (TRUE
26635c4bbdfSmrg        && !pScreenInfo->fMultiWindow
26735c4bbdfSmrg        ) {
26835c4bbdfSmrg        /* Trim window width to fit work area */
26935c4bbdfSmrg        if (iWidth > (rcWorkArea.right - rcWorkArea.left))
27035c4bbdfSmrg            iWidth = rcWorkArea.right - rcWorkArea.left;
27135c4bbdfSmrg
27235c4bbdfSmrg        /* Trim window height to fit work area */
27335c4bbdfSmrg        if (iHeight >= (rcWorkArea.bottom - rcWorkArea.top))
27435c4bbdfSmrg            iHeight = rcWorkArea.bottom - rcWorkArea.top;
27535c4bbdfSmrg
27605b261ecSmrg#if CYGDEBUG
27735c4bbdfSmrg        winDebug("winCreateBoundingWindowWindowed - Adjusted width: %d "
27835c4bbdfSmrg                 "height: %d\n", iWidth, iHeight);
27905b261ecSmrg#endif
28005b261ecSmrg    }
28105b261ecSmrg
28235c4bbdfSmrg    /* Set display and screen-specific tooltip text */
28335c4bbdfSmrg    if (g_pszQueryHost != NULL)
28435c4bbdfSmrg        snprintf(szTitle,
28535c4bbdfSmrg                 sizeof(szTitle),
28635c4bbdfSmrg                 WINDOW_TITLE_XDMCP,
28735c4bbdfSmrg                 g_pszQueryHost, display, (int) pScreenInfo->dwScreen);
28835c4bbdfSmrg    else
28935c4bbdfSmrg        snprintf(szTitle,
29035c4bbdfSmrg                 sizeof(szTitle),
29135c4bbdfSmrg                 WINDOW_TITLE, display, (int) pScreenInfo->dwScreen);
29235c4bbdfSmrg
29335c4bbdfSmrg    /* Create the window */
29435c4bbdfSmrg    *phwnd = CreateWindowExA(0, /* Extended styles */
29535c4bbdfSmrg                             WINDOW_CLASS,      /* Class name */
29635c4bbdfSmrg                             szTitle,   /* Window name */
29735c4bbdfSmrg                             dwWindowStyle, iPosX,      /* Horizontal position */
29835c4bbdfSmrg                             iPosY,     /* Vertical position */
29935c4bbdfSmrg                             iWidth,    /* Right edge */
30035c4bbdfSmrg                             iHeight,   /* Bottom edge */
30135c4bbdfSmrg                             (HWND) NULL,       /* No parent or owner window */
30235c4bbdfSmrg                             (HMENU) NULL,      /* No menu */
30335c4bbdfSmrg                             GetModuleHandle(NULL),     /* Instance handle */
30435c4bbdfSmrg                             pScreenPriv);      /* ScreenPrivates */
30535c4bbdfSmrg    if (*phwnd == NULL) {
30635c4bbdfSmrg        ErrorF("winCreateBoundingWindowWindowed - CreateWindowEx () failed\n");
30735c4bbdfSmrg        return FALSE;
30805b261ecSmrg    }
30905b261ecSmrg
31005b261ecSmrg#if CYGDEBUG
31135c4bbdfSmrg    winDebug("winCreateBoundingWindowWindowed - CreateWindowEx () returned\n");
31205b261ecSmrg#endif
31305b261ecSmrg
31435c4bbdfSmrg    if (fForceShowWindow) {
31535c4bbdfSmrg        ErrorF
31635c4bbdfSmrg            ("winCreateBoundingWindowWindowed - Setting normal windowstyle\n");
31735c4bbdfSmrg        ShowWindow(*phwnd, SW_SHOW);
31835c4bbdfSmrg    }
31935c4bbdfSmrg
32035c4bbdfSmrg    /* Get the client area coordinates */
32135c4bbdfSmrg    if (!GetClientRect(*phwnd, &rcClient)) {
32235c4bbdfSmrg        ErrorF("winCreateBoundingWindowWindowed - GetClientRect () "
32335c4bbdfSmrg               "failed\n");
32435c4bbdfSmrg        return FALSE;
32505b261ecSmrg    }
32605b261ecSmrg
32735c4bbdfSmrg    winDebug("winCreateBoundingWindowWindowed - WindowClient "
32835c4bbdfSmrg             "w %d  h %d r %d l %d b %d t %d\n",
32935c4bbdfSmrg             (int)(rcClient.right - rcClient.left),
33035c4bbdfSmrg             (int)(rcClient.bottom - rcClient.top),
33135c4bbdfSmrg             (int)rcClient.right, (int)rcClient.left,
33235c4bbdfSmrg             (int)rcClient.bottom, (int)rcClient.top);
33335c4bbdfSmrg
33435c4bbdfSmrg    /* We adjust the visual size if the user did not specify it */
33535c4bbdfSmrg    if (!
33635c4bbdfSmrg        ((pScreenInfo->iResizeMode == resizeWithScrollbars) &&
33735c4bbdfSmrg         pScreenInfo->fUserGaveHeightAndWidth)) {
33835c4bbdfSmrg        /*
33935c4bbdfSmrg         * User did not give a height and width with scrollbars enabled,
34035c4bbdfSmrg         * so we will resize the underlying visual to be as large as
34135c4bbdfSmrg         * the initial view port (page size).  This way scrollbars will
34235c4bbdfSmrg         * not appear until the user shrinks the window, if they ever do.
34335c4bbdfSmrg         *
34435c4bbdfSmrg         * NOTE: We have to store the viewport size here because
34535c4bbdfSmrg         * the user may have an autohide taskbar, which would
34635c4bbdfSmrg         * cause the viewport size to be one less in one dimension
34735c4bbdfSmrg         * than the viewport size that we calculated by subtracting
34835c4bbdfSmrg         * the size of the borders and caption.
34935c4bbdfSmrg         */
35035c4bbdfSmrg        pScreenInfo->dwWidth = rcClient.right - rcClient.left;
35135c4bbdfSmrg        pScreenInfo->dwHeight = rcClient.bottom - rcClient.top;
35205b261ecSmrg    }
35305b261ecSmrg
35405b261ecSmrg#if 0
35535c4bbdfSmrg    /*
35635c4bbdfSmrg     * NOTE: For the uninitiated, the page size is the number of pixels
35735c4bbdfSmrg     * that we can display in the x or y direction at a time and the
35835c4bbdfSmrg     * range is the total number of pixels in the x or y direction that we
35935c4bbdfSmrg     * have available to display.  In other words, the page size is the
36035c4bbdfSmrg     * size of the window area minus the space the caption, borders, and
36135c4bbdfSmrg     * scrollbars (if any) occupy, and the range is the size of the
36235c4bbdfSmrg     * underlying X visual.  Notice that, contrary to what some of the
36335c4bbdfSmrg     * MSDN Library arcticles lead you to believe, the windows
36435c4bbdfSmrg     * ``client area'' size does not include the scrollbars.  In other words,
36535c4bbdfSmrg     * the whole client area size that is reported to you is drawable by
36635c4bbdfSmrg     * you; you do not have to subtract the size of the scrollbars from
36735c4bbdfSmrg     * the client area size, and if you did it would result in the size
36835c4bbdfSmrg     * of the scrollbars being double counted.
36935c4bbdfSmrg     */
37035c4bbdfSmrg
37135c4bbdfSmrg    /* Setup scrollbar page and range, if scrollbars are enabled */
37235c4bbdfSmrg    if (pScreenInfo->fScrollbars) {
37335c4bbdfSmrg        SCROLLINFO si;
37435c4bbdfSmrg
37535c4bbdfSmrg        /* Initialize the scrollbar info structure */
37635c4bbdfSmrg        si.cbSize = sizeof(si);
37735c4bbdfSmrg        si.fMask = SIF_RANGE | SIF_PAGE;
37835c4bbdfSmrg        si.nMin = 0;
37935c4bbdfSmrg
38035c4bbdfSmrg        /* Setup the width range and page size */
38135c4bbdfSmrg        si.nMax = pScreenInfo->dwWidth - 1;
38235c4bbdfSmrg        si.nPage = rcClient.right - rcClient.left;
38335c4bbdfSmrg        winDebug("winCreateBoundingWindowWindowed - HORZ nMax: %d nPage :%d\n",
38435c4bbdfSmrg                 si.nMax, si.nPage);
38535c4bbdfSmrg        SetScrollInfo(*phwnd, SB_HORZ, &si, TRUE);
38635c4bbdfSmrg
38735c4bbdfSmrg        /* Setup the height range and page size */
38835c4bbdfSmrg        si.nMax = pScreenInfo->dwHeight - 1;
38935c4bbdfSmrg        si.nPage = rcClient.bottom - rcClient.top;
39035c4bbdfSmrg        winDebug("winCreateBoundingWindowWindowed - VERT nMax: %d nPage :%d\n",
39135c4bbdfSmrg                 si.nMax, si.nPage);
39235c4bbdfSmrg        SetScrollInfo(*phwnd, SB_VERT, &si, TRUE);
39305b261ecSmrg    }
39405b261ecSmrg#endif
39505b261ecSmrg
39635c4bbdfSmrg    /* Show the window */
39735c4bbdfSmrg    if (FALSE
39835c4bbdfSmrg        || pScreenInfo->fMultiWindow
39935c4bbdfSmrg        ) {
40035c4bbdfSmrg        pScreenPriv->fRootWindowShown = FALSE;
40135c4bbdfSmrg        ShowWindow(*phwnd, SW_HIDE);
40205b261ecSmrg    }
40335c4bbdfSmrg    else
40435c4bbdfSmrg        ShowWindow(*phwnd, SW_SHOWNORMAL);
40535c4bbdfSmrg    if (!UpdateWindow(*phwnd)) {
40635c4bbdfSmrg        ErrorF("winCreateBoundingWindowWindowed - UpdateWindow () failed\n");
40735c4bbdfSmrg        return FALSE;
40805b261ecSmrg    }
40935c4bbdfSmrg
41035c4bbdfSmrg    /* Attempt to bring our window to the top of the display */
41135c4bbdfSmrg    if (TRUE
41235c4bbdfSmrg        && !pScreenInfo->fRootless
41335c4bbdfSmrg        && !pScreenInfo->fMultiWindow
41435c4bbdfSmrg        ) {
41535c4bbdfSmrg        if (!BringWindowToTop(*phwnd)) {
41635c4bbdfSmrg            ErrorF("winCreateBoundingWindowWindowed - BringWindowToTop () "
41735c4bbdfSmrg                   "failed\n");
41835c4bbdfSmrg            return FALSE;
41935c4bbdfSmrg        }
42005b261ecSmrg    }
42105b261ecSmrg
42235c4bbdfSmrg    winDebug("winCreateBoundingWindowWindowed -  Returning\n");
42305b261ecSmrg
42435c4bbdfSmrg    return TRUE;
42505b261ecSmrg}
42605b261ecSmrg
42705b261ecSmrg/*
42805b261ecSmrg * Find the work area of all attached monitors
42905b261ecSmrg */
43005b261ecSmrg
43105b261ecSmrgstatic Bool
43235c4bbdfSmrgwinGetWorkArea(RECT * prcWorkArea, winScreenInfo * pScreenInfo)
43305b261ecSmrg{
43435c4bbdfSmrg    int iPrimaryWidth, iPrimaryHeight;
43535c4bbdfSmrg    int iWidth, iHeight;
43635c4bbdfSmrg    int iLeft, iTop;
43735c4bbdfSmrg    int iPrimaryNonWorkAreaWidth, iPrimaryNonWorkAreaHeight;
43835c4bbdfSmrg
43935c4bbdfSmrg    /* Use GetMonitorInfo to get work area for monitor */
44035c4bbdfSmrg    if (!pScreenInfo->fMultipleMonitors) {
44135c4bbdfSmrg        MONITORINFO mi;
44235c4bbdfSmrg
44335c4bbdfSmrg        mi.cbSize = sizeof(MONITORINFO);
44435c4bbdfSmrg        if (GetMonitorInfo(pScreenInfo->hMonitor, &mi)) {
44535c4bbdfSmrg            *prcWorkArea = mi.rcWork;
44635c4bbdfSmrg
44735c4bbdfSmrg            winDebug("winGetWorkArea - Monitor %d WorkArea: %d %d %d %d\n",
44835c4bbdfSmrg                     pScreenInfo->iMonitor,
44935c4bbdfSmrg                     (int) prcWorkArea->top, (int) prcWorkArea->left,
45035c4bbdfSmrg                     (int) prcWorkArea->bottom, (int) prcWorkArea->right);
45135c4bbdfSmrg        }
45235c4bbdfSmrg        else {
45335c4bbdfSmrg            ErrorF("winGetWorkArea - GetMonitorInfo() failed for monitor %d\n",
45435c4bbdfSmrg                   pScreenInfo->iMonitor);
45535c4bbdfSmrg        }
45635c4bbdfSmrg
45735c4bbdfSmrg        /* Bail out here if we aren't using multiple monitors */
45835c4bbdfSmrg        return TRUE;
45935c4bbdfSmrg    }
46005b261ecSmrg
46135c4bbdfSmrg    /* SPI_GETWORKAREA only gets the work area of the primary screen. */
46235c4bbdfSmrg    SystemParametersInfo(SPI_GETWORKAREA, 0, prcWorkArea, 0);
46305b261ecSmrg
46435c4bbdfSmrg    winDebug("winGetWorkArea - Primary Monitor WorkArea: %d %d %d %d\n",
46535c4bbdfSmrg             (int) prcWorkArea->top, (int) prcWorkArea->left,
46635c4bbdfSmrg             (int) prcWorkArea->bottom, (int) prcWorkArea->right);
46735c4bbdfSmrg
46835c4bbdfSmrg    /* Get size of full virtual screen */
46935c4bbdfSmrg    iWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
47035c4bbdfSmrg    iHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
47135c4bbdfSmrg
47235c4bbdfSmrg    winDebug("winGetWorkArea - Virtual screen is %d x %d\n", iWidth, iHeight);
47335c4bbdfSmrg
47435c4bbdfSmrg    /* Get origin of full virtual screen */
47535c4bbdfSmrg    iLeft = GetSystemMetrics(SM_XVIRTUALSCREEN);
47635c4bbdfSmrg    iTop = GetSystemMetrics(SM_YVIRTUALSCREEN);
47735c4bbdfSmrg
47835c4bbdfSmrg    winDebug("winGetWorkArea - Virtual screen origin is %d, %d\n", iLeft, iTop);
47935c4bbdfSmrg
48035c4bbdfSmrg    /* Get size of primary screen */
48135c4bbdfSmrg    iPrimaryWidth = GetSystemMetrics(SM_CXSCREEN);
48235c4bbdfSmrg    iPrimaryHeight = GetSystemMetrics(SM_CYSCREEN);
48335c4bbdfSmrg
48435c4bbdfSmrg    winDebug("winGetWorkArea - Primary screen is %d x %d\n",
48535c4bbdfSmrg             iPrimaryWidth, iPrimaryHeight);
48635c4bbdfSmrg
48735c4bbdfSmrg    /* Work out how much of the primary screen we aren't using */
48835c4bbdfSmrg    iPrimaryNonWorkAreaWidth = iPrimaryWidth - (prcWorkArea->right -
48935c4bbdfSmrg                                                prcWorkArea->left);
49035c4bbdfSmrg    iPrimaryNonWorkAreaHeight = iPrimaryHeight - (prcWorkArea->bottom
49135c4bbdfSmrg                                                  - prcWorkArea->top);
49235c4bbdfSmrg
49335c4bbdfSmrg    /* Update the rectangle to include all monitors */
49435c4bbdfSmrg    if (iLeft < 0) {
49535c4bbdfSmrg        prcWorkArea->left = iLeft;
49605b261ecSmrg    }
49735c4bbdfSmrg    if (iTop < 0) {
49835c4bbdfSmrg        prcWorkArea->top = iTop;
49905b261ecSmrg    }
50035c4bbdfSmrg    prcWorkArea->right = prcWorkArea->left + iWidth - iPrimaryNonWorkAreaWidth;
50135c4bbdfSmrg    prcWorkArea->bottom = prcWorkArea->top + iHeight -
50235c4bbdfSmrg        iPrimaryNonWorkAreaHeight;
50335c4bbdfSmrg
50435c4bbdfSmrg    winDebug("winGetWorkArea - Adjusted WorkArea for multiple "
50535c4bbdfSmrg             "monitors: %d %d %d %d\n",
50635c4bbdfSmrg             (int) prcWorkArea->top, (int) prcWorkArea->left,
50735c4bbdfSmrg             (int) prcWorkArea->bottom, (int) prcWorkArea->right);
50835c4bbdfSmrg
50935c4bbdfSmrg    return TRUE;
51005b261ecSmrg}
51105b261ecSmrg
51235c4bbdfSmrgstatic Bool
51335c4bbdfSmrgwinTaskbarOnScreenEdge(unsigned int uEdge, winScreenInfo * pScreenInfo)
51435c4bbdfSmrg{
51535c4bbdfSmrg    APPBARDATA abd;
51635c4bbdfSmrg    HWND hwndAutoHide;
51735c4bbdfSmrg
51835c4bbdfSmrg    ZeroMemory(&abd, sizeof(abd));
51935c4bbdfSmrg    abd.cbSize = sizeof(abd);
52035c4bbdfSmrg    abd.uEdge = uEdge;
52135c4bbdfSmrg
52235c4bbdfSmrg    hwndAutoHide = (HWND) SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd);
52335c4bbdfSmrg    if (hwndAutoHide != NULL) {
52435c4bbdfSmrg        /*
52535c4bbdfSmrg           Found an autohide taskbar on that edge, but is it on the
52635c4bbdfSmrg           same monitor as the screen window?
52735c4bbdfSmrg         */
52835c4bbdfSmrg        if (pScreenInfo->fMultipleMonitors ||
52935c4bbdfSmrg            (MonitorFromWindow(hwndAutoHide, MONITOR_DEFAULTTONULL) ==
53035c4bbdfSmrg             pScreenInfo->hMonitor))
53135c4bbdfSmrg            return TRUE;
53235c4bbdfSmrg    }
53335c4bbdfSmrg    return FALSE;
53435c4bbdfSmrg}
53505b261ecSmrg
53605b261ecSmrg/*
53705b261ecSmrg * Adjust the client area so that any auto-hide toolbars
53805b261ecSmrg * will work correctly.
53905b261ecSmrg */
54005b261ecSmrg
54105b261ecSmrgstatic Bool
54235c4bbdfSmrgwinAdjustForAutoHide(RECT * prcWorkArea, winScreenInfo * pScreenInfo)
54305b261ecSmrg{
54435c4bbdfSmrg    APPBARDATA abd;
54535c4bbdfSmrg
54635c4bbdfSmrg    winDebug("winAdjustForAutoHide - Original WorkArea: %d %d %d %d\n",
54735c4bbdfSmrg             (int) prcWorkArea->top, (int) prcWorkArea->left,
54835c4bbdfSmrg             (int) prcWorkArea->bottom, (int) prcWorkArea->right);
54935c4bbdfSmrg
55035c4bbdfSmrg    /* Find out if the Windows taskbar is set to auto-hide */
55135c4bbdfSmrg    ZeroMemory(&abd, sizeof(abd));
55235c4bbdfSmrg    abd.cbSize = sizeof(abd);
55335c4bbdfSmrg    if (SHAppBarMessage(ABM_GETSTATE, &abd) & ABS_AUTOHIDE)
55435c4bbdfSmrg        winDebug("winAdjustForAutoHide - Taskbar is auto hide\n");
55535c4bbdfSmrg
55635c4bbdfSmrg    /*
55735c4bbdfSmrg       Despite the forgoing, we are checking for any AppBar
55835c4bbdfSmrg       hiding along a monitor edge, not just the Windows TaskBar.
55935c4bbdfSmrg     */
56035c4bbdfSmrg
56135c4bbdfSmrg    /* Look for a TOP auto-hide taskbar */
56235c4bbdfSmrg    if (winTaskbarOnScreenEdge(ABE_TOP, pScreenInfo)) {
56335c4bbdfSmrg        winDebug("winAdjustForAutoHide - Found TOP auto-hide taskbar\n");
56435c4bbdfSmrg        prcWorkArea->top += 1;
56505b261ecSmrg    }
56605b261ecSmrg
56735c4bbdfSmrg    /* Look for a LEFT auto-hide taskbar */
56835c4bbdfSmrg    if (winTaskbarOnScreenEdge(ABE_LEFT, pScreenInfo)) {
56935c4bbdfSmrg        winDebug("winAdjustForAutoHide - Found LEFT auto-hide taskbar\n");
57035c4bbdfSmrg        prcWorkArea->left += 1;
57105b261ecSmrg    }
57205b261ecSmrg
57335c4bbdfSmrg    /* Look for a BOTTOM auto-hide taskbar */
57435c4bbdfSmrg    if (winTaskbarOnScreenEdge(ABE_BOTTOM, pScreenInfo)) {
57535c4bbdfSmrg        winDebug("winAdjustForAutoHide - Found BOTTOM auto-hide taskbar\n");
57635c4bbdfSmrg        prcWorkArea->bottom -= 1;
57705b261ecSmrg    }
57805b261ecSmrg
57935c4bbdfSmrg    /* Look for a RIGHT auto-hide taskbar */
58035c4bbdfSmrg    if (winTaskbarOnScreenEdge(ABE_RIGHT, pScreenInfo)) {
58135c4bbdfSmrg        winDebug("winAdjustForAutoHide - Found RIGHT auto-hide taskbar\n");
58235c4bbdfSmrg        prcWorkArea->right -= 1;
58305b261ecSmrg    }
58405b261ecSmrg
58535c4bbdfSmrg    winDebug("winAdjustForAutoHide - Adjusted WorkArea: %d %d %d %d\n",
58635c4bbdfSmrg             (int) prcWorkArea->top, (int) prcWorkArea->left,
58735c4bbdfSmrg             (int) prcWorkArea->bottom, (int) prcWorkArea->right);
58805b261ecSmrg
58935c4bbdfSmrg    return TRUE;
59005b261ecSmrg}
591