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