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