wincreatewnd.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 "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;
7535c4bbdfSmrg    wc.hIcon =
7635c4bbdfSmrg        (HICON) LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
7735c4bbdfSmrg                          GetSystemMetrics(SM_CXICON),
7835c4bbdfSmrg                          GetSystemMetrics(SM_CYICON), 0);
7935c4bbdfSmrg    wc.hCursor = 0;
8035c4bbdfSmrg    wc.hbrBackground = 0;
8135c4bbdfSmrg    wc.lpszMenuName = NULL;
8235c4bbdfSmrg    wc.lpszClassName = WINDOW_CLASS;
8335c4bbdfSmrg    wc.hIconSm =
8435c4bbdfSmrg        (HICON) LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
8535c4bbdfSmrg                          GetSystemMetrics(SM_CXSMICON),
8635c4bbdfSmrg                          GetSystemMetrics(SM_CYSMICON), LR_DEFAULTSIZE);
8735c4bbdfSmrg    RegisterClassEx(&wc);
8835c4bbdfSmrg
8935c4bbdfSmrg    /* Set display and screen-specific tooltip text */
9035c4bbdfSmrg    if (g_pszQueryHost != NULL)
9135c4bbdfSmrg        snprintf(szTitle,
9235c4bbdfSmrg                 sizeof(szTitle),
9335c4bbdfSmrg                 WINDOW_TITLE_XDMCP,
9435c4bbdfSmrg                 g_pszQueryHost, display, (int) pScreenInfo->dwScreen);
9535c4bbdfSmrg    else
9635c4bbdfSmrg        snprintf(szTitle,
9735c4bbdfSmrg                 sizeof(szTitle),
9835c4bbdfSmrg                 WINDOW_TITLE, display, (int) pScreenInfo->dwScreen);
9935c4bbdfSmrg
10035c4bbdfSmrg    /* Create the window */
10135c4bbdfSmrg    *phwnd = CreateWindowExA(0, /* Extended styles */
10235c4bbdfSmrg                             WINDOW_CLASS,      /* Class name */
10335c4bbdfSmrg                             szTitle,   /* Window name */
10435c4bbdfSmrg                             WS_POPUP, iX,      /* Horizontal position */
10535c4bbdfSmrg                             iY,        /* Vertical position */
10635c4bbdfSmrg                             iWidth,    /* Right edge */
10735c4bbdfSmrg                             iHeight,   /* Bottom edge */
10835c4bbdfSmrg                             (HWND) NULL,       /* No parent or owner window */
10935c4bbdfSmrg                             (HMENU) NULL,      /* No menu */
11035c4bbdfSmrg                             GetModuleHandle(NULL),     /* Instance handle */
11135c4bbdfSmrg                             pScreenPriv);      /* ScreenPrivates */
11235c4bbdfSmrg
11335c4bbdfSmrg    /* Hide the window */
11435c4bbdfSmrg    ShowWindow(*phwnd, SW_SHOWNORMAL);
11535c4bbdfSmrg
11635c4bbdfSmrg    /* Send first paint message */
11735c4bbdfSmrg    UpdateWindow(*phwnd);
11835c4bbdfSmrg
11935c4bbdfSmrg    /* Attempt to bring our window to the top of the display */
12035c4bbdfSmrg    BringWindowToTop(*phwnd);
12105b261ecSmrg
12235c4bbdfSmrg    return TRUE;
12305b261ecSmrg}
12405b261ecSmrg
12505b261ecSmrg/*
12605b261ecSmrg * Create our primary Windows display window
12705b261ecSmrg */
12805b261ecSmrg
12905b261ecSmrgBool
13035c4bbdfSmrgwinCreateBoundingWindowWindowed(ScreenPtr pScreen)
13105b261ecSmrg{
13235c4bbdfSmrg    winScreenPriv(pScreen);
13335c4bbdfSmrg    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
13435c4bbdfSmrg    int iWidth = pScreenInfo->dwUserWidth;
13535c4bbdfSmrg    int iHeight = pScreenInfo->dwUserHeight;
13635c4bbdfSmrg    int iPosX;
13735c4bbdfSmrg    int iPosY;
13835c4bbdfSmrg    HWND *phwnd = &pScreenPriv->hwndScreen;
13935c4bbdfSmrg    WNDCLASSEX wc;
14035c4bbdfSmrg    RECT rcClient, rcWorkArea;
14135c4bbdfSmrg    DWORD dwWindowStyle;
14235c4bbdfSmrg    BOOL fForceShowWindow = FALSE;
14335c4bbdfSmrg    char szTitle[256];
14435c4bbdfSmrg
14535c4bbdfSmrg    winDebug("winCreateBoundingWindowWindowed - User w: %d h: %d\n",
14635c4bbdfSmrg             (int) pScreenInfo->dwUserWidth, (int) pScreenInfo->dwUserHeight);
14735c4bbdfSmrg    winDebug("winCreateBoundingWindowWindowed - Current w: %d h: %d\n",
14835c4bbdfSmrg             (int) pScreenInfo->dwWidth, (int) pScreenInfo->dwHeight);
14935c4bbdfSmrg
15035c4bbdfSmrg    /* Set the common window style flags */
15135c4bbdfSmrg    dwWindowStyle = WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX;
15235c4bbdfSmrg
15335c4bbdfSmrg    /* Decorated or undecorated window */
15435c4bbdfSmrg    if (pScreenInfo->fDecoration
15505b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
15635c4bbdfSmrg        && !pScreenInfo->fMWExtWM
15705b261ecSmrg#endif
15835c4bbdfSmrg        && !pScreenInfo->fRootless
15935c4bbdfSmrg        && !pScreenInfo->fMultiWindow
16035c4bbdfSmrg        ) {
16135c4bbdfSmrg        /* Try to handle startup via run.exe. run.exe instructs Windows to
16235c4bbdfSmrg         * hide all created windows. Detect this case and make sure the
16305b261ecSmrg         * window is shown nevertheless */
16435c4bbdfSmrg        STARTUPINFO startupInfo;
16535c4bbdfSmrg
16605b261ecSmrg        GetStartupInfo(&startupInfo);
16735c4bbdfSmrg        if (startupInfo.dwFlags & STARTF_USESHOWWINDOW &&
16835c4bbdfSmrg            startupInfo.wShowWindow == SW_HIDE) {
16935c4bbdfSmrg            fForceShowWindow = TRUE;
17035c4bbdfSmrg        }
17105b261ecSmrg        dwWindowStyle |= WS_CAPTION;
1721b5d61b8Smrg        if (pScreenInfo->iResizeMode != resizeNotAllowed)
17305b261ecSmrg            dwWindowStyle |= WS_THICKFRAME | WS_MAXIMIZEBOX;
17405b261ecSmrg    }
17535c4bbdfSmrg    else
17635c4bbdfSmrg        dwWindowStyle |= WS_POPUP;
17735c4bbdfSmrg
17835c4bbdfSmrg    /* Setup our window class */
17935c4bbdfSmrg    wc.cbSize = sizeof(WNDCLASSEX);
18035c4bbdfSmrg    wc.style = CS_HREDRAW | CS_VREDRAW;
18135c4bbdfSmrg    wc.lpfnWndProc = winWindowProc;
18235c4bbdfSmrg    wc.cbClsExtra = 0;
18335c4bbdfSmrg    wc.cbWndExtra = 0;
18435c4bbdfSmrg    wc.hInstance = g_hInstance;
18535c4bbdfSmrg    wc.hIcon =
18635c4bbdfSmrg        (HICON) LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
18735c4bbdfSmrg                          GetSystemMetrics(SM_CXICON),
18835c4bbdfSmrg                          GetSystemMetrics(SM_CYICON), 0);
18935c4bbdfSmrg    wc.hCursor = 0;
19035c4bbdfSmrg    wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
19135c4bbdfSmrg    wc.lpszMenuName = NULL;
19235c4bbdfSmrg    wc.lpszClassName = WINDOW_CLASS;
19335c4bbdfSmrg    wc.hIconSm =
19435c4bbdfSmrg        (HICON) LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
19535c4bbdfSmrg                          GetSystemMetrics(SM_CXSMICON),
19635c4bbdfSmrg                          GetSystemMetrics(SM_CYSMICON), LR_DEFAULTSIZE);
19735c4bbdfSmrg    RegisterClassEx(&wc);
19835c4bbdfSmrg
19935c4bbdfSmrg    /* Get size of work area */
20035c4bbdfSmrg    winGetWorkArea(&rcWorkArea, pScreenInfo);
20135c4bbdfSmrg
20235c4bbdfSmrg    /* Adjust for auto-hide taskbars */
20335c4bbdfSmrg    winAdjustForAutoHide(&rcWorkArea, pScreenInfo);
20435c4bbdfSmrg
20535c4bbdfSmrg    /* Did the user specify a position? */
20635c4bbdfSmrg    if (pScreenInfo->fUserGavePosition) {
20735c4bbdfSmrg        iPosX = pScreenInfo->dwInitialX;
20835c4bbdfSmrg        iPosY = pScreenInfo->dwInitialY;
20905b261ecSmrg    }
21035c4bbdfSmrg    else {
21135c4bbdfSmrg        iPosX = rcWorkArea.left;
21235c4bbdfSmrg        iPosY = rcWorkArea.top;
21305b261ecSmrg    }
21405b261ecSmrg
21535c4bbdfSmrg    /* Clean up the scrollbars flag, if necessary */
21635c4bbdfSmrg    if ((!pScreenInfo->fDecoration
2179ace9065Smrg#ifdef XWIN_MULTIWINDOWEXTWM
21835c4bbdfSmrg         || pScreenInfo->fMWExtWM
2199ace9065Smrg#endif
22035c4bbdfSmrg         || pScreenInfo->fRootless
22135c4bbdfSmrg         || pScreenInfo->fMultiWindow
22235c4bbdfSmrg        )
22335c4bbdfSmrg        && (pScreenInfo->iResizeMode == resizeWithScrollbars)) {
22435c4bbdfSmrg        /* We cannot have scrollbars if we do not have a window border */
2251b5d61b8Smrg        pScreenInfo->iResizeMode = resizeNotAllowed;
2269ace9065Smrg    }
2279ace9065Smrg
22835c4bbdfSmrg    /* Did the user specify a height and width? */
22935c4bbdfSmrg    if (pScreenInfo->fUserGaveHeightAndWidth) {
23035c4bbdfSmrg        /* User gave a desired height and width, try to accomodate */
23105b261ecSmrg#if CYGDEBUG
23235c4bbdfSmrg        winDebug("winCreateBoundingWindowWindowed - User gave height "
23335c4bbdfSmrg                 "and width\n");
23405b261ecSmrg#endif
23535c4bbdfSmrg
23635c4bbdfSmrg        /* Adjust the window width and height for borders and title bar */
23735c4bbdfSmrg        if (pScreenInfo->fDecoration
23805b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
23935c4bbdfSmrg            && !pScreenInfo->fMWExtWM
24005b261ecSmrg#endif
24135c4bbdfSmrg            && !pScreenInfo->fRootless
24235c4bbdfSmrg            && !pScreenInfo->fMultiWindow
24335c4bbdfSmrg            ) {
24405b261ecSmrg#if CYGDEBUG
24535c4bbdfSmrg            winDebug
24635c4bbdfSmrg                ("winCreateBoundingWindowWindowed - Window has decoration\n");
24705b261ecSmrg#endif
2489ace9065Smrg
24935c4bbdfSmrg            /* Are we resizable */
2501b5d61b8Smrg            if (pScreenInfo->iResizeMode != resizeNotAllowed) {
25105b261ecSmrg#if CYGDEBUG
25235c4bbdfSmrg                winDebug
25335c4bbdfSmrg                    ("winCreateBoundingWindowWindowed - Window is resizable\n");
25405b261ecSmrg#endif
25505b261ecSmrg
25635c4bbdfSmrg                iWidth += 2 * GetSystemMetrics(SM_CXSIZEFRAME);
25735c4bbdfSmrg                iHeight += 2 * GetSystemMetrics(SM_CYSIZEFRAME)
25835c4bbdfSmrg                    + GetSystemMetrics(SM_CYCAPTION);
25935c4bbdfSmrg            }
26035c4bbdfSmrg            else {
26105b261ecSmrg#if CYGDEBUG
26235c4bbdfSmrg                winDebug
26335c4bbdfSmrg                    ("winCreateBoundingWindowWindowed - Window is not resizable\n");
26405b261ecSmrg#endif
26505b261ecSmrg
26635c4bbdfSmrg                iWidth += 2 * GetSystemMetrics(SM_CXFIXEDFRAME);
26735c4bbdfSmrg                iHeight += 2 * GetSystemMetrics(SM_CYFIXEDFRAME)
26835c4bbdfSmrg                    + GetSystemMetrics(SM_CYCAPTION);
26935c4bbdfSmrg            }
27035c4bbdfSmrg        }
27105b261ecSmrg    }
27235c4bbdfSmrg    else {
27335c4bbdfSmrg        /* By default, we are creating a window that is as large as possible */
27405b261ecSmrg#if CYGDEBUG
27535c4bbdfSmrg        winDebug("winCreateBoundingWindowWindowed - User did not give "
27635c4bbdfSmrg                 "height and width\n");
27705b261ecSmrg#endif
27835c4bbdfSmrg        /* Defaults are wrong if we have multiple monitors */
27935c4bbdfSmrg        if (pScreenInfo->fMultipleMonitors) {
28035c4bbdfSmrg            iWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
28135c4bbdfSmrg            iHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
28235c4bbdfSmrg        }
28305b261ecSmrg    }
28405b261ecSmrg
28535c4bbdfSmrg    /* Make sure window is no bigger than work area */
28635c4bbdfSmrg    if (TRUE
28705b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
28835c4bbdfSmrg        && !pScreenInfo->fMWExtWM
28905b261ecSmrg#endif
29035c4bbdfSmrg        && !pScreenInfo->fMultiWindow
29135c4bbdfSmrg        ) {
29235c4bbdfSmrg        /* Trim window width to fit work area */
29335c4bbdfSmrg        if (iWidth > (rcWorkArea.right - rcWorkArea.left))
29435c4bbdfSmrg            iWidth = rcWorkArea.right - rcWorkArea.left;
29535c4bbdfSmrg
29635c4bbdfSmrg        /* Trim window height to fit work area */
29735c4bbdfSmrg        if (iHeight >= (rcWorkArea.bottom - rcWorkArea.top))
29835c4bbdfSmrg            iHeight = rcWorkArea.bottom - rcWorkArea.top;
29935c4bbdfSmrg
30005b261ecSmrg#if CYGDEBUG
30135c4bbdfSmrg        winDebug("winCreateBoundingWindowWindowed - Adjusted width: %d "
30235c4bbdfSmrg                 "height: %d\n", iWidth, iHeight);
30305b261ecSmrg#endif
30405b261ecSmrg    }
30505b261ecSmrg
30635c4bbdfSmrg    /* Set display and screen-specific tooltip text */
30735c4bbdfSmrg    if (g_pszQueryHost != NULL)
30835c4bbdfSmrg        snprintf(szTitle,
30935c4bbdfSmrg                 sizeof(szTitle),
31035c4bbdfSmrg                 WINDOW_TITLE_XDMCP,
31135c4bbdfSmrg                 g_pszQueryHost, display, (int) pScreenInfo->dwScreen);
31235c4bbdfSmrg    else
31335c4bbdfSmrg        snprintf(szTitle,
31435c4bbdfSmrg                 sizeof(szTitle),
31535c4bbdfSmrg                 WINDOW_TITLE, display, (int) pScreenInfo->dwScreen);
31635c4bbdfSmrg
31735c4bbdfSmrg    /* Create the window */
31835c4bbdfSmrg    *phwnd = CreateWindowExA(0, /* Extended styles */
31935c4bbdfSmrg                             WINDOW_CLASS,      /* Class name */
32035c4bbdfSmrg                             szTitle,   /* Window name */
32135c4bbdfSmrg                             dwWindowStyle, iPosX,      /* Horizontal position */
32235c4bbdfSmrg                             iPosY,     /* Vertical position */
32335c4bbdfSmrg                             iWidth,    /* Right edge */
32435c4bbdfSmrg                             iHeight,   /* Bottom edge */
32535c4bbdfSmrg                             (HWND) NULL,       /* No parent or owner window */
32635c4bbdfSmrg                             (HMENU) NULL,      /* No menu */
32735c4bbdfSmrg                             GetModuleHandle(NULL),     /* Instance handle */
32835c4bbdfSmrg                             pScreenPriv);      /* ScreenPrivates */
32935c4bbdfSmrg    if (*phwnd == NULL) {
33035c4bbdfSmrg        ErrorF("winCreateBoundingWindowWindowed - CreateWindowEx () failed\n");
33135c4bbdfSmrg        return FALSE;
33205b261ecSmrg    }
33305b261ecSmrg
33405b261ecSmrg#if CYGDEBUG
33535c4bbdfSmrg    winDebug("winCreateBoundingWindowWindowed - CreateWindowEx () returned\n");
33605b261ecSmrg#endif
33705b261ecSmrg
33835c4bbdfSmrg    if (fForceShowWindow) {
33935c4bbdfSmrg        ErrorF
34035c4bbdfSmrg            ("winCreateBoundingWindowWindowed - Setting normal windowstyle\n");
34135c4bbdfSmrg        ShowWindow(*phwnd, SW_SHOW);
34235c4bbdfSmrg    }
34335c4bbdfSmrg
34435c4bbdfSmrg    /* Get the client area coordinates */
34535c4bbdfSmrg    if (!GetClientRect(*phwnd, &rcClient)) {
34635c4bbdfSmrg        ErrorF("winCreateBoundingWindowWindowed - GetClientRect () "
34735c4bbdfSmrg               "failed\n");
34835c4bbdfSmrg        return FALSE;
34905b261ecSmrg    }
35005b261ecSmrg
35135c4bbdfSmrg    winDebug("winCreateBoundingWindowWindowed - WindowClient "
35235c4bbdfSmrg             "w %d  h %d r %d l %d b %d t %d\n",
35335c4bbdfSmrg             (int)(rcClient.right - rcClient.left),
35435c4bbdfSmrg             (int)(rcClient.bottom - rcClient.top),
35535c4bbdfSmrg             (int)rcClient.right, (int)rcClient.left,
35635c4bbdfSmrg             (int)rcClient.bottom, (int)rcClient.top);
35735c4bbdfSmrg
35835c4bbdfSmrg    /* We adjust the visual size if the user did not specify it */
35935c4bbdfSmrg    if (!
36035c4bbdfSmrg        ((pScreenInfo->iResizeMode == resizeWithScrollbars) &&
36135c4bbdfSmrg         pScreenInfo->fUserGaveHeightAndWidth)) {
36235c4bbdfSmrg        /*
36335c4bbdfSmrg         * User did not give a height and width with scrollbars enabled,
36435c4bbdfSmrg         * so we will resize the underlying visual to be as large as
36535c4bbdfSmrg         * the initial view port (page size).  This way scrollbars will
36635c4bbdfSmrg         * not appear until the user shrinks the window, if they ever do.
36735c4bbdfSmrg         *
36835c4bbdfSmrg         * NOTE: We have to store the viewport size here because
36935c4bbdfSmrg         * the user may have an autohide taskbar, which would
37035c4bbdfSmrg         * cause the viewport size to be one less in one dimension
37135c4bbdfSmrg         * than the viewport size that we calculated by subtracting
37235c4bbdfSmrg         * the size of the borders and caption.
37335c4bbdfSmrg         */
37435c4bbdfSmrg        pScreenInfo->dwWidth = rcClient.right - rcClient.left;
37535c4bbdfSmrg        pScreenInfo->dwHeight = rcClient.bottom - rcClient.top;
37605b261ecSmrg    }
37705b261ecSmrg
37805b261ecSmrg#if 0
37935c4bbdfSmrg    /*
38035c4bbdfSmrg     * NOTE: For the uninitiated, the page size is the number of pixels
38135c4bbdfSmrg     * that we can display in the x or y direction at a time and the
38235c4bbdfSmrg     * range is the total number of pixels in the x or y direction that we
38335c4bbdfSmrg     * have available to display.  In other words, the page size is the
38435c4bbdfSmrg     * size of the window area minus the space the caption, borders, and
38535c4bbdfSmrg     * scrollbars (if any) occupy, and the range is the size of the
38635c4bbdfSmrg     * underlying X visual.  Notice that, contrary to what some of the
38735c4bbdfSmrg     * MSDN Library arcticles lead you to believe, the windows
38835c4bbdfSmrg     * ``client area'' size does not include the scrollbars.  In other words,
38935c4bbdfSmrg     * the whole client area size that is reported to you is drawable by
39035c4bbdfSmrg     * you; you do not have to subtract the size of the scrollbars from
39135c4bbdfSmrg     * the client area size, and if you did it would result in the size
39235c4bbdfSmrg     * of the scrollbars being double counted.
39335c4bbdfSmrg     */
39435c4bbdfSmrg
39535c4bbdfSmrg    /* Setup scrollbar page and range, if scrollbars are enabled */
39635c4bbdfSmrg    if (pScreenInfo->fScrollbars) {
39735c4bbdfSmrg        SCROLLINFO si;
39835c4bbdfSmrg
39935c4bbdfSmrg        /* Initialize the scrollbar info structure */
40035c4bbdfSmrg        si.cbSize = sizeof(si);
40135c4bbdfSmrg        si.fMask = SIF_RANGE | SIF_PAGE;
40235c4bbdfSmrg        si.nMin = 0;
40335c4bbdfSmrg
40435c4bbdfSmrg        /* Setup the width range and page size */
40535c4bbdfSmrg        si.nMax = pScreenInfo->dwWidth - 1;
40635c4bbdfSmrg        si.nPage = rcClient.right - rcClient.left;
40735c4bbdfSmrg        winDebug("winCreateBoundingWindowWindowed - HORZ nMax: %d nPage :%d\n",
40835c4bbdfSmrg                 si.nMax, si.nPage);
40935c4bbdfSmrg        SetScrollInfo(*phwnd, SB_HORZ, &si, TRUE);
41035c4bbdfSmrg
41135c4bbdfSmrg        /* Setup the height range and page size */
41235c4bbdfSmrg        si.nMax = pScreenInfo->dwHeight - 1;
41335c4bbdfSmrg        si.nPage = rcClient.bottom - rcClient.top;
41435c4bbdfSmrg        winDebug("winCreateBoundingWindowWindowed - VERT nMax: %d nPage :%d\n",
41535c4bbdfSmrg                 si.nMax, si.nPage);
41635c4bbdfSmrg        SetScrollInfo(*phwnd, SB_VERT, &si, TRUE);
41705b261ecSmrg    }
41805b261ecSmrg#endif
41905b261ecSmrg
42035c4bbdfSmrg    /* Show the window */
42135c4bbdfSmrg    if (FALSE
42205b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
42335c4bbdfSmrg        || pScreenInfo->fMWExtWM
42405b261ecSmrg#endif
42535c4bbdfSmrg        || pScreenInfo->fMultiWindow
42635c4bbdfSmrg        ) {
42735c4bbdfSmrg        pScreenPriv->fRootWindowShown = FALSE;
42835c4bbdfSmrg        ShowWindow(*phwnd, SW_HIDE);
42905b261ecSmrg    }
43035c4bbdfSmrg    else
43135c4bbdfSmrg        ShowWindow(*phwnd, SW_SHOWNORMAL);
43235c4bbdfSmrg    if (!UpdateWindow(*phwnd)) {
43335c4bbdfSmrg        ErrorF("winCreateBoundingWindowWindowed - UpdateWindow () failed\n");
43435c4bbdfSmrg        return FALSE;
43505b261ecSmrg    }
43635c4bbdfSmrg
43735c4bbdfSmrg    /* Attempt to bring our window to the top of the display */
43835c4bbdfSmrg    if (TRUE
43905b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
44035c4bbdfSmrg        && !pScreenInfo->fMWExtWM
44105b261ecSmrg#endif
44235c4bbdfSmrg        && !pScreenInfo->fRootless
44335c4bbdfSmrg        && !pScreenInfo->fMultiWindow
44435c4bbdfSmrg        ) {
44535c4bbdfSmrg        if (!BringWindowToTop(*phwnd)) {
44635c4bbdfSmrg            ErrorF("winCreateBoundingWindowWindowed - BringWindowToTop () "
44735c4bbdfSmrg                   "failed\n");
44835c4bbdfSmrg            return FALSE;
44935c4bbdfSmrg        }
45005b261ecSmrg    }
45105b261ecSmrg
45235c4bbdfSmrg    winDebug("winCreateBoundingWindowWindowed -  Returning\n");
45305b261ecSmrg
45435c4bbdfSmrg    return TRUE;
45505b261ecSmrg}
45605b261ecSmrg
45705b261ecSmrg/*
45805b261ecSmrg * Find the work area of all attached monitors
45905b261ecSmrg */
46005b261ecSmrg
46105b261ecSmrgstatic Bool
46235c4bbdfSmrgwinGetWorkArea(RECT * prcWorkArea, winScreenInfo * pScreenInfo)
46305b261ecSmrg{
46435c4bbdfSmrg    int iPrimaryWidth, iPrimaryHeight;
46535c4bbdfSmrg    int iWidth, iHeight;
46635c4bbdfSmrg    int iLeft, iTop;
46735c4bbdfSmrg    int iPrimaryNonWorkAreaWidth, iPrimaryNonWorkAreaHeight;
46835c4bbdfSmrg
46935c4bbdfSmrg    /* Use GetMonitorInfo to get work area for monitor */
47035c4bbdfSmrg    if (!pScreenInfo->fMultipleMonitors) {
47135c4bbdfSmrg        MONITORINFO mi;
47235c4bbdfSmrg
47335c4bbdfSmrg        mi.cbSize = sizeof(MONITORINFO);
47435c4bbdfSmrg        if (GetMonitorInfo(pScreenInfo->hMonitor, &mi)) {
47535c4bbdfSmrg            *prcWorkArea = mi.rcWork;
47635c4bbdfSmrg
47735c4bbdfSmrg            winDebug("winGetWorkArea - Monitor %d WorkArea: %d %d %d %d\n",
47835c4bbdfSmrg                     pScreenInfo->iMonitor,
47935c4bbdfSmrg                     (int) prcWorkArea->top, (int) prcWorkArea->left,
48035c4bbdfSmrg                     (int) prcWorkArea->bottom, (int) prcWorkArea->right);
48135c4bbdfSmrg        }
48235c4bbdfSmrg        else {
48335c4bbdfSmrg            ErrorF("winGetWorkArea - GetMonitorInfo() failed for monitor %d\n",
48435c4bbdfSmrg                   pScreenInfo->iMonitor);
48535c4bbdfSmrg        }
48635c4bbdfSmrg
48735c4bbdfSmrg        /* Bail out here if we aren't using multiple monitors */
48835c4bbdfSmrg        return TRUE;
48935c4bbdfSmrg    }
49005b261ecSmrg
49135c4bbdfSmrg    /* SPI_GETWORKAREA only gets the work area of the primary screen. */
49235c4bbdfSmrg    SystemParametersInfo(SPI_GETWORKAREA, 0, prcWorkArea, 0);
49305b261ecSmrg
49435c4bbdfSmrg    winDebug("winGetWorkArea - Primary Monitor WorkArea: %d %d %d %d\n",
49535c4bbdfSmrg             (int) prcWorkArea->top, (int) prcWorkArea->left,
49635c4bbdfSmrg             (int) prcWorkArea->bottom, (int) prcWorkArea->right);
49735c4bbdfSmrg
49835c4bbdfSmrg    /* Get size of full virtual screen */
49935c4bbdfSmrg    iWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
50035c4bbdfSmrg    iHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
50135c4bbdfSmrg
50235c4bbdfSmrg    winDebug("winGetWorkArea - Virtual screen is %d x %d\n", iWidth, iHeight);
50335c4bbdfSmrg
50435c4bbdfSmrg    /* Get origin of full virtual screen */
50535c4bbdfSmrg    iLeft = GetSystemMetrics(SM_XVIRTUALSCREEN);
50635c4bbdfSmrg    iTop = GetSystemMetrics(SM_YVIRTUALSCREEN);
50735c4bbdfSmrg
50835c4bbdfSmrg    winDebug("winGetWorkArea - Virtual screen origin is %d, %d\n", iLeft, iTop);
50935c4bbdfSmrg
51035c4bbdfSmrg    /* Get size of primary screen */
51135c4bbdfSmrg    iPrimaryWidth = GetSystemMetrics(SM_CXSCREEN);
51235c4bbdfSmrg    iPrimaryHeight = GetSystemMetrics(SM_CYSCREEN);
51335c4bbdfSmrg
51435c4bbdfSmrg    winDebug("winGetWorkArea - Primary screen is %d x %d\n",
51535c4bbdfSmrg             iPrimaryWidth, iPrimaryHeight);
51635c4bbdfSmrg
51735c4bbdfSmrg    /* Work out how much of the primary screen we aren't using */
51835c4bbdfSmrg    iPrimaryNonWorkAreaWidth = iPrimaryWidth - (prcWorkArea->right -
51935c4bbdfSmrg                                                prcWorkArea->left);
52035c4bbdfSmrg    iPrimaryNonWorkAreaHeight = iPrimaryHeight - (prcWorkArea->bottom
52135c4bbdfSmrg                                                  - prcWorkArea->top);
52235c4bbdfSmrg
52335c4bbdfSmrg    /* Update the rectangle to include all monitors */
52435c4bbdfSmrg    if (iLeft < 0) {
52535c4bbdfSmrg        prcWorkArea->left = iLeft;
52605b261ecSmrg    }
52735c4bbdfSmrg    if (iTop < 0) {
52835c4bbdfSmrg        prcWorkArea->top = iTop;
52905b261ecSmrg    }
53035c4bbdfSmrg    prcWorkArea->right = prcWorkArea->left + iWidth - iPrimaryNonWorkAreaWidth;
53135c4bbdfSmrg    prcWorkArea->bottom = prcWorkArea->top + iHeight -
53235c4bbdfSmrg        iPrimaryNonWorkAreaHeight;
53335c4bbdfSmrg
53435c4bbdfSmrg    winDebug("winGetWorkArea - Adjusted WorkArea for multiple "
53535c4bbdfSmrg             "monitors: %d %d %d %d\n",
53635c4bbdfSmrg             (int) prcWorkArea->top, (int) prcWorkArea->left,
53735c4bbdfSmrg             (int) prcWorkArea->bottom, (int) prcWorkArea->right);
53835c4bbdfSmrg
53935c4bbdfSmrg    return TRUE;
54005b261ecSmrg}
54105b261ecSmrg
54235c4bbdfSmrgstatic Bool
54335c4bbdfSmrgwinTaskbarOnScreenEdge(unsigned int uEdge, winScreenInfo * pScreenInfo)
54435c4bbdfSmrg{
54535c4bbdfSmrg    APPBARDATA abd;
54635c4bbdfSmrg    HWND hwndAutoHide;
54735c4bbdfSmrg
54835c4bbdfSmrg    ZeroMemory(&abd, sizeof(abd));
54935c4bbdfSmrg    abd.cbSize = sizeof(abd);
55035c4bbdfSmrg    abd.uEdge = uEdge;
55135c4bbdfSmrg
55235c4bbdfSmrg    hwndAutoHide = (HWND) SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd);
55335c4bbdfSmrg    if (hwndAutoHide != NULL) {
55435c4bbdfSmrg        /*
55535c4bbdfSmrg           Found an autohide taskbar on that edge, but is it on the
55635c4bbdfSmrg           same monitor as the screen window?
55735c4bbdfSmrg         */
55835c4bbdfSmrg        if (pScreenInfo->fMultipleMonitors ||
55935c4bbdfSmrg            (MonitorFromWindow(hwndAutoHide, MONITOR_DEFAULTTONULL) ==
56035c4bbdfSmrg             pScreenInfo->hMonitor))
56135c4bbdfSmrg            return TRUE;
56235c4bbdfSmrg    }
56335c4bbdfSmrg    return FALSE;
56435c4bbdfSmrg}
56505b261ecSmrg
56605b261ecSmrg/*
56705b261ecSmrg * Adjust the client area so that any auto-hide toolbars
56805b261ecSmrg * will work correctly.
56905b261ecSmrg */
57005b261ecSmrg
57105b261ecSmrgstatic Bool
57235c4bbdfSmrgwinAdjustForAutoHide(RECT * prcWorkArea, winScreenInfo * pScreenInfo)
57305b261ecSmrg{
57435c4bbdfSmrg    APPBARDATA abd;
57535c4bbdfSmrg
57635c4bbdfSmrg    winDebug("winAdjustForAutoHide - Original WorkArea: %d %d %d %d\n",
57735c4bbdfSmrg             (int) prcWorkArea->top, (int) prcWorkArea->left,
57835c4bbdfSmrg             (int) prcWorkArea->bottom, (int) prcWorkArea->right);
57935c4bbdfSmrg
58035c4bbdfSmrg    /* Find out if the Windows taskbar is set to auto-hide */
58135c4bbdfSmrg    ZeroMemory(&abd, sizeof(abd));
58235c4bbdfSmrg    abd.cbSize = sizeof(abd);
58335c4bbdfSmrg    if (SHAppBarMessage(ABM_GETSTATE, &abd) & ABS_AUTOHIDE)
58435c4bbdfSmrg        winDebug("winAdjustForAutoHide - Taskbar is auto hide\n");
58535c4bbdfSmrg
58635c4bbdfSmrg    /*
58735c4bbdfSmrg       Despite the forgoing, we are checking for any AppBar
58835c4bbdfSmrg       hiding along a monitor edge, not just the Windows TaskBar.
58935c4bbdfSmrg     */
59035c4bbdfSmrg
59135c4bbdfSmrg    /* Look for a TOP auto-hide taskbar */
59235c4bbdfSmrg    if (winTaskbarOnScreenEdge(ABE_TOP, pScreenInfo)) {
59335c4bbdfSmrg        winDebug("winAdjustForAutoHide - Found TOP auto-hide taskbar\n");
59435c4bbdfSmrg        prcWorkArea->top += 1;
59505b261ecSmrg    }
59605b261ecSmrg
59735c4bbdfSmrg    /* Look for a LEFT auto-hide taskbar */
59835c4bbdfSmrg    if (winTaskbarOnScreenEdge(ABE_LEFT, pScreenInfo)) {
59935c4bbdfSmrg        winDebug("winAdjustForAutoHide - Found LEFT auto-hide taskbar\n");
60035c4bbdfSmrg        prcWorkArea->left += 1;
60105b261ecSmrg    }
60205b261ecSmrg
60335c4bbdfSmrg    /* Look for a BOTTOM auto-hide taskbar */
60435c4bbdfSmrg    if (winTaskbarOnScreenEdge(ABE_BOTTOM, pScreenInfo)) {
60535c4bbdfSmrg        winDebug("winAdjustForAutoHide - Found BOTTOM auto-hide taskbar\n");
60635c4bbdfSmrg        prcWorkArea->bottom -= 1;
60705b261ecSmrg    }
60805b261ecSmrg
60935c4bbdfSmrg    /* Look for a RIGHT auto-hide taskbar */
61035c4bbdfSmrg    if (winTaskbarOnScreenEdge(ABE_RIGHT, pScreenInfo)) {
61135c4bbdfSmrg        winDebug("winAdjustForAutoHide - Found RIGHT auto-hide taskbar\n");
61235c4bbdfSmrg        prcWorkArea->right -= 1;
61305b261ecSmrg    }
61405b261ecSmrg
61535c4bbdfSmrg    winDebug("winAdjustForAutoHide - Adjusted WorkArea: %d %d %d %d\n",
61635c4bbdfSmrg             (int) prcWorkArea->top, (int) prcWorkArea->left,
61735c4bbdfSmrg             (int) prcWorkArea->bottom, (int) prcWorkArea->right);
61805b261ecSmrg
61935c4bbdfSmrg    return TRUE;
62005b261ecSmrg}
621