wincreatewnd.c revision 9ace9065
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#ifndef ABS_AUTOHIDE
3805b261ecSmrg#define ABS_AUTOHIDE 1
3905b261ecSmrg#endif
4005b261ecSmrg
4105b261ecSmrg/*
4205b261ecSmrg * Local function prototypes
4305b261ecSmrg */
4405b261ecSmrg
4505b261ecSmrgstatic Bool
4605b261ecSmrgwinGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo);
4705b261ecSmrg
4805b261ecSmrgstatic Bool
4905b261ecSmrgwinAdjustForAutoHide (RECT *prcWorkArea);
5005b261ecSmrg
5105b261ecSmrg
5205b261ecSmrg/*
5305b261ecSmrg * Create a full screen window
5405b261ecSmrg */
5505b261ecSmrg
5605b261ecSmrgBool
5705b261ecSmrgwinCreateBoundingWindowFullScreen (ScreenPtr pScreen)
5805b261ecSmrg{
5905b261ecSmrg  winScreenPriv(pScreen);
6005b261ecSmrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
6105b261ecSmrg  int			iX = pScreenInfo->dwInitialX;
6205b261ecSmrg  int			iY = pScreenInfo->dwInitialY;
6305b261ecSmrg  int			iWidth = pScreenInfo->dwWidth;
6405b261ecSmrg  int			iHeight = pScreenInfo->dwHeight;
6505b261ecSmrg  HWND			*phwnd = &pScreenPriv->hwndScreen;
666747b715Smrg  WNDCLASSEX		wc;
6705b261ecSmrg  char			szTitle[256];
6805b261ecSmrg
6905b261ecSmrg#if CYGDEBUG
7005b261ecSmrg  winDebug ("winCreateBoundingWindowFullScreen\n");
7105b261ecSmrg#endif
7205b261ecSmrg
7305b261ecSmrg  /* Setup our window class */
746747b715Smrg  wc.cbSize=sizeof(WNDCLASSEX);
7505b261ecSmrg  wc.style = CS_HREDRAW | CS_VREDRAW;
7605b261ecSmrg  wc.lpfnWndProc = winWindowProc;
7705b261ecSmrg  wc.cbClsExtra = 0;
7805b261ecSmrg  wc.cbWndExtra = 0;
7905b261ecSmrg  wc.hInstance = g_hInstance;
806747b715Smrg  wc.hIcon = (HICON)LoadImage (g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
816747b715Smrg		GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0);
8205b261ecSmrg  wc.hCursor = 0;
8305b261ecSmrg  wc.hbrBackground = 0;
8405b261ecSmrg  wc.lpszMenuName = NULL;
8505b261ecSmrg  wc.lpszClassName = WINDOW_CLASS;
866747b715Smrg  wc.hIconSm = (HICON)LoadImage (g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
876747b715Smrg		GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTSIZE);
886747b715Smrg  RegisterClassEx (&wc);
8905b261ecSmrg
9005b261ecSmrg  /* Set display and screen-specific tooltip text */
9105b261ecSmrg  if (g_pszQueryHost != NULL)
9205b261ecSmrg    snprintf (szTitle,
9305b261ecSmrg	    sizeof (szTitle),
9405b261ecSmrg	    WINDOW_TITLE_XDMCP,
956747b715Smrg	    g_pszQueryHost,
966747b715Smrg	    display,
976747b715Smrg	    (int) pScreenInfo->dwScreen);
9805b261ecSmrg  else
9905b261ecSmrg    snprintf (szTitle,
10005b261ecSmrg	    sizeof (szTitle),
10105b261ecSmrg	    WINDOW_TITLE,
10205b261ecSmrg	    display,
10305b261ecSmrg	    (int) pScreenInfo->dwScreen);
10405b261ecSmrg
10505b261ecSmrg  /* Create the window */
10605b261ecSmrg  *phwnd = CreateWindowExA (0,			/* Extended styles */
10705b261ecSmrg			    WINDOW_CLASS,	/* Class name */
10805b261ecSmrg			    szTitle,		/* Window name */
10905b261ecSmrg			    WS_POPUP,
11005b261ecSmrg			    iX,			/* Horizontal position */
11105b261ecSmrg			    iY,			/* Vertical position */
11205b261ecSmrg			    iWidth,		/* Right edge */
11305b261ecSmrg			    iHeight,		/* Bottom edge */
11405b261ecSmrg			    (HWND) NULL,	/* No parent or owner window */
11505b261ecSmrg			    (HMENU) NULL,	/* No menu */
11605b261ecSmrg			    GetModuleHandle (NULL),/* Instance handle */
11705b261ecSmrg			    pScreenPriv);	/* ScreenPrivates */
11805b261ecSmrg
11905b261ecSmrg  /* Branch on the server engine */
12005b261ecSmrg  switch (pScreenInfo->dwEngine)
12105b261ecSmrg    {
12205b261ecSmrg#ifdef XWIN_NATIVEGDI
12305b261ecSmrg    case WIN_SERVER_SHADOW_GDI:
12405b261ecSmrg      /* Show the window */
12505b261ecSmrg      ShowWindow (*phwnd, SW_SHOWMAXIMIZED);
12605b261ecSmrg      break;
12705b261ecSmrg#endif
12805b261ecSmrg
12905b261ecSmrg    default:
13005b261ecSmrg      /* Hide the window */
13105b261ecSmrg      ShowWindow (*phwnd, SW_SHOWNORMAL);
13205b261ecSmrg      break;
13305b261ecSmrg    }
13405b261ecSmrg
13505b261ecSmrg  /* Send first paint message */
13605b261ecSmrg  UpdateWindow (*phwnd);
13705b261ecSmrg
13805b261ecSmrg  /* Attempt to bring our window to the top of the display */
13905b261ecSmrg  BringWindowToTop (*phwnd);
14005b261ecSmrg
14105b261ecSmrg  return TRUE;
14205b261ecSmrg}
14305b261ecSmrg
14405b261ecSmrg
14505b261ecSmrg/*
14605b261ecSmrg * Create our primary Windows display window
14705b261ecSmrg */
14805b261ecSmrg
14905b261ecSmrgBool
15005b261ecSmrgwinCreateBoundingWindowWindowed (ScreenPtr pScreen)
15105b261ecSmrg{
15205b261ecSmrg  winScreenPriv(pScreen);
15305b261ecSmrg  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
15405b261ecSmrg  int			iWidth = pScreenInfo->dwUserWidth;
15505b261ecSmrg  int			iHeight = pScreenInfo->dwUserHeight;
15605b261ecSmrg  int                   iPosX;
15705b261ecSmrg  int                   iPosY;
15805b261ecSmrg  HWND			*phwnd = &pScreenPriv->hwndScreen;
1596747b715Smrg  WNDCLASSEX		wc;
16005b261ecSmrg  RECT			rcClient, rcWorkArea;
16105b261ecSmrg  DWORD			dwWindowStyle;
16205b261ecSmrg  BOOL			fForceShowWindow = FALSE;
16305b261ecSmrg  char			szTitle[256];
16405b261ecSmrg
16505b261ecSmrg  winDebug ("winCreateBoundingWindowWindowed - User w: %d h: %d\n",
16605b261ecSmrg	  (int) pScreenInfo->dwUserWidth, (int) pScreenInfo->dwUserHeight);
16705b261ecSmrg  winDebug ("winCreateBoundingWindowWindowed - Current w: %d h: %d\n",
16805b261ecSmrg	  (int) pScreenInfo->dwWidth, (int) pScreenInfo->dwHeight);
16905b261ecSmrg
17005b261ecSmrg  /* Set the common window style flags */
17105b261ecSmrg  dwWindowStyle = WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX;
17205b261ecSmrg
17305b261ecSmrg  /* Decorated or undecorated window */
17405b261ecSmrg  if (pScreenInfo->fDecoration
17505b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
17605b261ecSmrg      && !pScreenInfo->fMWExtWM
17705b261ecSmrg#endif
17805b261ecSmrg      && !pScreenInfo->fRootless
17905b261ecSmrg#ifdef XWIN_MULTIWINDOW
18005b261ecSmrg      && !pScreenInfo->fMultiWindow
18105b261ecSmrg#endif
18205b261ecSmrg      )
18305b261ecSmrg    {
18405b261ecSmrg        /* Try to handle startup via run.exe. run.exe instructs Windows to
18505b261ecSmrg         * hide all created windows. Detect this case and make sure the
18605b261ecSmrg         * window is shown nevertheless */
18705b261ecSmrg        STARTUPINFO   startupInfo;
18805b261ecSmrg        GetStartupInfo(&startupInfo);
18905b261ecSmrg        if (startupInfo.dwFlags & STARTF_USESHOWWINDOW &&
19005b261ecSmrg                startupInfo.wShowWindow == SW_HIDE)
19105b261ecSmrg        {
19205b261ecSmrg          fForceShowWindow = TRUE;
19305b261ecSmrg        }
19405b261ecSmrg        dwWindowStyle |= WS_CAPTION;
1959ace9065Smrg        if (pScreenInfo->iResizeMode != notAllowed)
19605b261ecSmrg            dwWindowStyle |= WS_THICKFRAME | WS_MAXIMIZEBOX;
19705b261ecSmrg    }
19805b261ecSmrg  else
19905b261ecSmrg    dwWindowStyle |= WS_POPUP;
20005b261ecSmrg
20105b261ecSmrg  /* Setup our window class */
2026747b715Smrg  wc.cbSize=sizeof(WNDCLASSEX);
20305b261ecSmrg  wc.style = CS_HREDRAW | CS_VREDRAW;
20405b261ecSmrg  wc.lpfnWndProc = winWindowProc;
20505b261ecSmrg  wc.cbClsExtra = 0;
20605b261ecSmrg  wc.cbWndExtra = 0;
20705b261ecSmrg  wc.hInstance = g_hInstance;
2086747b715Smrg  wc.hIcon = (HICON)LoadImage (g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
2096747b715Smrg		GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0);
21005b261ecSmrg  wc.hCursor = 0;
21105b261ecSmrg  wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
21205b261ecSmrg  wc.lpszMenuName = NULL;
21305b261ecSmrg  wc.lpszClassName = WINDOW_CLASS;
2146747b715Smrg  wc.hIconSm = (HICON)LoadImage (g_hInstance, MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
2156747b715Smrg		GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTSIZE);
2166747b715Smrg  RegisterClassEx (&wc);
21705b261ecSmrg
21805b261ecSmrg  /* Get size of work area */
21905b261ecSmrg  winGetWorkArea (&rcWorkArea, pScreenInfo);
22005b261ecSmrg
22105b261ecSmrg  /* Adjust for auto-hide taskbars */
22205b261ecSmrg  winAdjustForAutoHide (&rcWorkArea);
22305b261ecSmrg
22405b261ecSmrg  /* Did the user specify a position? */
22505b261ecSmrg  if (pScreenInfo->fUserGavePosition)
22605b261ecSmrg    {
22705b261ecSmrg      iPosX = pScreenInfo->dwInitialX;
22805b261ecSmrg      iPosY = pScreenInfo->dwInitialY;
22905b261ecSmrg    }
23005b261ecSmrg  else
23105b261ecSmrg    {
23205b261ecSmrg      iPosX = rcWorkArea.left;
23305b261ecSmrg      iPosY = rcWorkArea.top;
23405b261ecSmrg    }
23505b261ecSmrg
2369ace9065Smrg  /* Clean up the scrollbars flag, if necessary */
2379ace9065Smrg  if ((!pScreenInfo->fDecoration
2389ace9065Smrg#ifdef XWIN_MULTIWINDOWEXTWM
2399ace9065Smrg       || pScreenInfo->fMWExtWM
2409ace9065Smrg#endif
2419ace9065Smrg       || pScreenInfo->fRootless
2429ace9065Smrg#ifdef XWIN_MULTIWINDOW
2439ace9065Smrg       || pScreenInfo->fMultiWindow
2449ace9065Smrg#endif
2459ace9065Smrg       )
2469ace9065Smrg      && (pScreenInfo->iResizeMode == resizeWithScrollbars))
2479ace9065Smrg    {
2489ace9065Smrg      /* We cannot have scrollbars if we do not have a window border */
2499ace9065Smrg      pScreenInfo->iResizeMode = notAllowed;
2509ace9065Smrg    }
2519ace9065Smrg
25205b261ecSmrg  /* Did the user specify a height and width? */
25305b261ecSmrg  if (pScreenInfo->fUserGaveHeightAndWidth)
25405b261ecSmrg    {
25505b261ecSmrg      /* User gave a desired height and width, try to accomodate */
25605b261ecSmrg#if CYGDEBUG
25705b261ecSmrg      winDebug ("winCreateBoundingWindowWindowed - User gave height "
25805b261ecSmrg	      "and width\n");
25905b261ecSmrg#endif
26005b261ecSmrg
26105b261ecSmrg      /* Adjust the window width and height for borders and title bar */
26205b261ecSmrg      if (pScreenInfo->fDecoration
26305b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
26405b261ecSmrg	  && !pScreenInfo->fMWExtWM
26505b261ecSmrg#endif
26605b261ecSmrg	  && !pScreenInfo->fRootless
26705b261ecSmrg#ifdef XWIN_MULTIWINDOW
26805b261ecSmrg	  && !pScreenInfo->fMultiWindow
26905b261ecSmrg#endif
27005b261ecSmrg	  )
27105b261ecSmrg	{
27205b261ecSmrg#if CYGDEBUG
27305b261ecSmrg	  winDebug ("winCreateBoundingWindowWindowed - Window has decoration\n");
27405b261ecSmrg#endif
2759ace9065Smrg
2769ace9065Smrg          /* Are we resizable */
2779ace9065Smrg          if (pScreenInfo->iResizeMode != notAllowed)
27805b261ecSmrg	    {
27905b261ecSmrg#if CYGDEBUG
2809ace9065Smrg	      winDebug ("winCreateBoundingWindowWindowed - Window is resizable\n");
28105b261ecSmrg#endif
28205b261ecSmrg
28305b261ecSmrg	      iWidth += 2 * GetSystemMetrics (SM_CXSIZEFRAME);
28405b261ecSmrg	      iHeight += 2 * GetSystemMetrics (SM_CYSIZEFRAME)
28505b261ecSmrg		+ GetSystemMetrics (SM_CYCAPTION);
28605b261ecSmrg	    }
28705b261ecSmrg	  else
28805b261ecSmrg	    {
28905b261ecSmrg#if CYGDEBUG
2909ace9065Smrg	      winDebug ("winCreateBoundingWindowWindowed - Window is not resizable\n");
29105b261ecSmrg#endif
29205b261ecSmrg
29305b261ecSmrg	      iWidth += 2 * GetSystemMetrics (SM_CXFIXEDFRAME);
29405b261ecSmrg	      iHeight += 2 * GetSystemMetrics (SM_CYFIXEDFRAME)
29505b261ecSmrg		+ GetSystemMetrics (SM_CYCAPTION);
29605b261ecSmrg	    }
29705b261ecSmrg	}
29805b261ecSmrg    }
29905b261ecSmrg  else
30005b261ecSmrg    {
30105b261ecSmrg      /* By default, we are creating a window that is as large as possible */
30205b261ecSmrg#if CYGDEBUG
30305b261ecSmrg      winDebug ("winCreateBoundingWindowWindowed - User did not give "
30405b261ecSmrg	      "height and width\n");
30505b261ecSmrg#endif
30605b261ecSmrg      /* Defaults are wrong if we have multiple monitors */
30705b261ecSmrg      if (pScreenInfo->fMultipleMonitors)
30805b261ecSmrg	{
30905b261ecSmrg	  iWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
31005b261ecSmrg	  iHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
31105b261ecSmrg	}
31205b261ecSmrg    }
31305b261ecSmrg
3149ace9065Smrg  /* Make sure window is no bigger than work area */
31505b261ecSmrg  if (TRUE
31605b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
31705b261ecSmrg       && !pScreenInfo->fMWExtWM
31805b261ecSmrg#endif
31905b261ecSmrg#ifdef XWIN_MULTIWINDOW
32005b261ecSmrg       && !pScreenInfo->fMultiWindow
32105b261ecSmrg#endif
32205b261ecSmrg     )
32305b261ecSmrg    {
32405b261ecSmrg      /* Trim window width to fit work area */
32505b261ecSmrg      if (iWidth > (rcWorkArea.right - rcWorkArea.left))
32605b261ecSmrg        iWidth = rcWorkArea.right - rcWorkArea.left;
32705b261ecSmrg
32805b261ecSmrg      /* Trim window height to fit work area */
32905b261ecSmrg      if (iHeight >= (rcWorkArea.bottom - rcWorkArea.top))
33005b261ecSmrg        iHeight = rcWorkArea.bottom - rcWorkArea.top;
33105b261ecSmrg
33205b261ecSmrg#if CYGDEBUG
33305b261ecSmrg      winDebug ("winCreateBoundingWindowWindowed - Adjusted width: %d "\
33405b261ecSmrg	      "height: %d\n",
33505b261ecSmrg    	  iWidth, iHeight);
33605b261ecSmrg#endif
33705b261ecSmrg    }
33805b261ecSmrg
33905b261ecSmrg  /* Set display and screen-specific tooltip text */
34005b261ecSmrg  if (g_pszQueryHost != NULL)
34105b261ecSmrg    snprintf (szTitle,
34205b261ecSmrg	    sizeof (szTitle),
34305b261ecSmrg	    WINDOW_TITLE_XDMCP,
3446747b715Smrg	    g_pszQueryHost,
3456747b715Smrg	    display,
3466747b715Smrg	    (int) pScreenInfo->dwScreen);
34705b261ecSmrg  else
34805b261ecSmrg    snprintf (szTitle,
34905b261ecSmrg	    sizeof (szTitle),
35005b261ecSmrg	    WINDOW_TITLE,
35105b261ecSmrg	    display,
35205b261ecSmrg	    (int) pScreenInfo->dwScreen);
35305b261ecSmrg
35405b261ecSmrg  /* Create the window */
35505b261ecSmrg  *phwnd = CreateWindowExA (0,			/* Extended styles */
35605b261ecSmrg			    WINDOW_CLASS,	/* Class name */
35705b261ecSmrg			    szTitle,		/* Window name */
35805b261ecSmrg			    dwWindowStyle,
35905b261ecSmrg			    iPosX,	        /* Horizontal position */
36005b261ecSmrg			    iPosY,	        /* Vertical position */
36105b261ecSmrg			    iWidth,		/* Right edge */
36205b261ecSmrg			    iHeight,		/* Bottom edge */
36305b261ecSmrg			    (HWND) NULL,	/* No parent or owner window */
36405b261ecSmrg			    (HMENU) NULL,	/* No menu */
36505b261ecSmrg			    GetModuleHandle (NULL),/* Instance handle */
36605b261ecSmrg			    pScreenPriv);	/* ScreenPrivates */
36705b261ecSmrg  if (*phwnd == NULL)
36805b261ecSmrg    {
36905b261ecSmrg      ErrorF ("winCreateBoundingWindowWindowed - CreateWindowEx () failed\n");
37005b261ecSmrg      return FALSE;
37105b261ecSmrg    }
37205b261ecSmrg
37305b261ecSmrg#if CYGDEBUG
37405b261ecSmrg  winDebug ("winCreateBoundingWindowWindowed - CreateWindowEx () returned\n");
37505b261ecSmrg#endif
37605b261ecSmrg
37705b261ecSmrg  if (fForceShowWindow)
37805b261ecSmrg  {
37905b261ecSmrg      ErrorF("winCreateBoundingWindowWindowed - Setting normal windowstyle\n");
38005b261ecSmrg      ShowWindow(*phwnd, SW_SHOW);
38105b261ecSmrg  }
38205b261ecSmrg
38305b261ecSmrg  /* Get the client area coordinates */
38405b261ecSmrg  if (!GetClientRect (*phwnd, &rcClient))
38505b261ecSmrg    {
38605b261ecSmrg      ErrorF ("winCreateBoundingWindowWindowed - GetClientRect () "
38705b261ecSmrg	      "failed\n");
38805b261ecSmrg      return FALSE;
38905b261ecSmrg    }
39005b261ecSmrg
39105b261ecSmrg  winDebug ("winCreateBoundingWindowWindowed - WindowClient "
39205b261ecSmrg	  "w %ld h %ld r %ld l %ld b %ld t %ld\n",
39305b261ecSmrg	  rcClient.right - rcClient.left,
39405b261ecSmrg	  rcClient.bottom - rcClient.top,
39505b261ecSmrg	  rcClient.right, rcClient.left,
39605b261ecSmrg	  rcClient.bottom, rcClient.top);
39705b261ecSmrg
39805b261ecSmrg  /* We adjust the visual size if the user did not specify it */
3999ace9065Smrg  if (!((pScreenInfo->iResizeMode == resizeWithScrollbars) && pScreenInfo->fUserGaveHeightAndWidth))
40005b261ecSmrg    {
40105b261ecSmrg      /*
40205b261ecSmrg       * User did not give a height and width with scrollbars enabled,
40305b261ecSmrg       * so we will resize the underlying visual to be as large as
40405b261ecSmrg       * the initial view port (page size).  This way scrollbars will
40505b261ecSmrg       * not appear until the user shrinks the window, if they ever do.
40605b261ecSmrg       *
40705b261ecSmrg       * NOTE: We have to store the viewport size here because
40805b261ecSmrg       * the user may have an autohide taskbar, which would
40905b261ecSmrg       * cause the viewport size to be one less in one dimension
41005b261ecSmrg       * than the viewport size that we calculated by subtracting
41105b261ecSmrg       * the size of the borders and caption.
41205b261ecSmrg       */
41305b261ecSmrg      pScreenInfo->dwWidth = rcClient.right - rcClient.left;
41405b261ecSmrg      pScreenInfo->dwHeight = rcClient.bottom - rcClient.top;
41505b261ecSmrg    }
41605b261ecSmrg
41705b261ecSmrg#if 0
41805b261ecSmrg  /*
41905b261ecSmrg   * NOTE: For the uninitiated, the page size is the number of pixels
42005b261ecSmrg   * that we can display in the x or y direction at a time and the
42105b261ecSmrg   * range is the total number of pixels in the x or y direction that we
42205b261ecSmrg   * have available to display.  In other words, the page size is the
42305b261ecSmrg   * size of the window area minus the space the caption, borders, and
42405b261ecSmrg   * scrollbars (if any) occupy, and the range is the size of the
42505b261ecSmrg   * underlying X visual.  Notice that, contrary to what some of the
42605b261ecSmrg   * MSDN Library arcticles lead you to believe, the windows
42705b261ecSmrg   * ``client area'' size does not include the scrollbars.  In other words,
42805b261ecSmrg   * the whole client area size that is reported to you is drawable by
42905b261ecSmrg   * you; you do not have to subtract the size of the scrollbars from
43005b261ecSmrg   * the client area size, and if you did it would result in the size
43105b261ecSmrg   * of the scrollbars being double counted.
43205b261ecSmrg   */
43305b261ecSmrg
43405b261ecSmrg  /* Setup scrollbar page and range, if scrollbars are enabled */
43505b261ecSmrg  if (pScreenInfo->fScrollbars)
43605b261ecSmrg    {
43705b261ecSmrg      SCROLLINFO		si;
43805b261ecSmrg
43905b261ecSmrg      /* Initialize the scrollbar info structure */
44005b261ecSmrg      si.cbSize = sizeof (si);
44105b261ecSmrg      si.fMask = SIF_RANGE | SIF_PAGE;
44205b261ecSmrg      si.nMin = 0;
44305b261ecSmrg
44405b261ecSmrg      /* Setup the width range and page size */
44505b261ecSmrg      si.nMax = pScreenInfo->dwWidth - 1;
44605b261ecSmrg      si.nPage = rcClient.right - rcClient.left;
44705b261ecSmrg      winDebug ("winCreateBoundingWindowWindowed - HORZ nMax: %d nPage :%d\n",
44805b261ecSmrg	      si.nMax, si.nPage);
44905b261ecSmrg      SetScrollInfo (*phwnd, SB_HORZ, &si, TRUE);
45005b261ecSmrg
45105b261ecSmrg      /* Setup the height range and page size */
45205b261ecSmrg      si.nMax = pScreenInfo->dwHeight - 1;
45305b261ecSmrg      si.nPage = rcClient.bottom - rcClient.top;
45405b261ecSmrg      winDebug ("winCreateBoundingWindowWindowed - VERT nMax: %d nPage :%d\n",
45505b261ecSmrg	      si.nMax, si.nPage);
45605b261ecSmrg      SetScrollInfo (*phwnd, SB_VERT, &si, TRUE);
45705b261ecSmrg    }
45805b261ecSmrg#endif
45905b261ecSmrg
46005b261ecSmrg  /* Show the window */
46105b261ecSmrg  if (FALSE
46205b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
46305b261ecSmrg      || pScreenInfo->fMWExtWM
46405b261ecSmrg#endif
46505b261ecSmrg#ifdef XWIN_MULTIWINDOW
46605b261ecSmrg      || pScreenInfo->fMultiWindow
46705b261ecSmrg#endif
46805b261ecSmrg      )
46905b261ecSmrg    {
47005b261ecSmrg#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
47105b261ecSmrg      pScreenPriv->fRootWindowShown = FALSE;
47205b261ecSmrg#endif
47305b261ecSmrg      ShowWindow (*phwnd, SW_HIDE);
47405b261ecSmrg    }
47505b261ecSmrg  else
47605b261ecSmrg    ShowWindow (*phwnd, SW_SHOWNORMAL);
47705b261ecSmrg  if (!UpdateWindow (*phwnd))
47805b261ecSmrg    {
47905b261ecSmrg      ErrorF ("winCreateBoundingWindowWindowed - UpdateWindow () failed\n");
48005b261ecSmrg      return FALSE;
48105b261ecSmrg    }
48205b261ecSmrg
48305b261ecSmrg  /* Attempt to bring our window to the top of the display */
48405b261ecSmrg  if (TRUE
48505b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
48605b261ecSmrg      && !pScreenInfo->fMWExtWM
48705b261ecSmrg#endif
48805b261ecSmrg      && !pScreenInfo->fRootless
48905b261ecSmrg#ifdef XWIN_MULTIWINDOW
49005b261ecSmrg      && !pScreenInfo->fMultiWindow
49105b261ecSmrg#endif
49205b261ecSmrg      )
49305b261ecSmrg    {
49405b261ecSmrg      if (!BringWindowToTop (*phwnd))
49505b261ecSmrg	{
49605b261ecSmrg	  ErrorF ("winCreateBoundingWindowWindowed - BringWindowToTop () "
49705b261ecSmrg		  "failed\n");
49805b261ecSmrg	  return FALSE;
49905b261ecSmrg	}
50005b261ecSmrg    }
50105b261ecSmrg
50205b261ecSmrg#ifdef XWIN_NATIVEGDI
50305b261ecSmrg  /* Paint window background blue */
50405b261ecSmrg  if (pScreenInfo->dwEngine == WIN_SERVER_NATIVE_GDI)
50505b261ecSmrg    winPaintBackground (*phwnd, RGB (0x00, 0x00, 0xFF));
50605b261ecSmrg#endif
50705b261ecSmrg
50805b261ecSmrg  winDebug ("winCreateBoundingWindowWindowed -  Returning\n");
50905b261ecSmrg
51005b261ecSmrg  return TRUE;
51105b261ecSmrg}
51205b261ecSmrg
51305b261ecSmrg
51405b261ecSmrg/*
51505b261ecSmrg * Find the work area of all attached monitors
51605b261ecSmrg */
51705b261ecSmrg
51805b261ecSmrgstatic Bool
51905b261ecSmrgwinGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo)
52005b261ecSmrg{
52105b261ecSmrg  int			iPrimaryWidth, iPrimaryHeight;
52205b261ecSmrg  int			iWidth, iHeight;
52305b261ecSmrg  int			iLeft, iTop;
52405b261ecSmrg  int			iPrimaryNonWorkAreaWidth, iPrimaryNonWorkAreaHeight;
52505b261ecSmrg
52605b261ecSmrg  /* SPI_GETWORKAREA only gets the work area of the primary screen. */
52705b261ecSmrg  SystemParametersInfo (SPI_GETWORKAREA, 0, prcWorkArea, 0);
52805b261ecSmrg
52905b261ecSmrg  /* Bail out here if we aren't using multiple monitors */
53005b261ecSmrg  if (!pScreenInfo->fMultipleMonitors)
53105b261ecSmrg    return TRUE;
53205b261ecSmrg
53305b261ecSmrg  winDebug ("winGetWorkArea - Original WorkArea: %d %d %d %d\n",
53405b261ecSmrg	  (int) prcWorkArea->top, (int) prcWorkArea->left,
53505b261ecSmrg	  (int) prcWorkArea->bottom, (int) prcWorkArea->right);
53605b261ecSmrg
53705b261ecSmrg  /* Get size of full virtual screen */
53805b261ecSmrg  iWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
53905b261ecSmrg  iHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
54005b261ecSmrg
54105b261ecSmrg  winDebug ("winGetWorkArea - Virtual screen is %d x %d\n", iWidth, iHeight);
54205b261ecSmrg
54305b261ecSmrg  /* Get origin of full virtual screen */
54405b261ecSmrg  iLeft = GetSystemMetrics (SM_XVIRTUALSCREEN);
54505b261ecSmrg  iTop = GetSystemMetrics (SM_YVIRTUALSCREEN);
54605b261ecSmrg
54705b261ecSmrg  winDebug ("winGetWorkArea - Virtual screen origin is %d, %d\n", iLeft, iTop);
54805b261ecSmrg
54905b261ecSmrg  /* Get size of primary screen */
55005b261ecSmrg  iPrimaryWidth = GetSystemMetrics (SM_CXSCREEN);
55105b261ecSmrg  iPrimaryHeight = GetSystemMetrics (SM_CYSCREEN);
55205b261ecSmrg
55305b261ecSmrg  winDebug ("winGetWorkArea - Primary screen is %d x %d\n",
55405b261ecSmrg	 iPrimaryWidth, iPrimaryHeight);
55505b261ecSmrg
55605b261ecSmrg  /* Work out how much of the primary screen we aren't using */
55705b261ecSmrg  iPrimaryNonWorkAreaWidth = iPrimaryWidth - (prcWorkArea->right -
55805b261ecSmrg					      prcWorkArea->left);
55905b261ecSmrg  iPrimaryNonWorkAreaHeight = iPrimaryHeight - (prcWorkArea->bottom
56005b261ecSmrg						- prcWorkArea->top);
56105b261ecSmrg
56205b261ecSmrg  /* Update the rectangle to include all monitors */
56305b261ecSmrg  if (iLeft < 0)
56405b261ecSmrg    {
56505b261ecSmrg      prcWorkArea->left = iLeft;
56605b261ecSmrg    }
56705b261ecSmrg  if (iTop < 0)
56805b261ecSmrg    {
56905b261ecSmrg      prcWorkArea->top = iTop;
57005b261ecSmrg    }
57105b261ecSmrg  prcWorkArea->right = prcWorkArea->left + iWidth -
57205b261ecSmrg    iPrimaryNonWorkAreaWidth;
57305b261ecSmrg  prcWorkArea->bottom = prcWorkArea->top + iHeight -
57405b261ecSmrg    iPrimaryNonWorkAreaHeight;
57505b261ecSmrg
57605b261ecSmrg  winDebug ("winGetWorkArea - Adjusted WorkArea for multiple "
57705b261ecSmrg	  "monitors: %d %d %d %d\n",
57805b261ecSmrg	  (int) prcWorkArea->top, (int) prcWorkArea->left,
57905b261ecSmrg	  (int) prcWorkArea->bottom, (int) prcWorkArea->right);
58005b261ecSmrg
58105b261ecSmrg  return TRUE;
58205b261ecSmrg}
58305b261ecSmrg
58405b261ecSmrg
58505b261ecSmrg/*
58605b261ecSmrg * Adjust the client area so that any auto-hide toolbars
58705b261ecSmrg * will work correctly.
58805b261ecSmrg */
58905b261ecSmrg
59005b261ecSmrgstatic Bool
59105b261ecSmrgwinAdjustForAutoHide (RECT *prcWorkArea)
59205b261ecSmrg{
59305b261ecSmrg  APPBARDATA		abd;
59405b261ecSmrg  HWND			hwndAutoHide;
59505b261ecSmrg
59605b261ecSmrg  winDebug ("winAdjustForAutoHide - Original WorkArea: %d %d %d %d\n",
59705b261ecSmrg	  (int) prcWorkArea->top, (int) prcWorkArea->left,
59805b261ecSmrg	  (int) prcWorkArea->bottom, (int) prcWorkArea->right);
59905b261ecSmrg
60005b261ecSmrg  /* Find out if the Windows taskbar is set to auto-hide */
60105b261ecSmrg  ZeroMemory (&abd, sizeof (abd));
60205b261ecSmrg  abd.cbSize = sizeof (abd);
60305b261ecSmrg  if (SHAppBarMessage (ABM_GETSTATE, &abd) & ABS_AUTOHIDE)
60405b261ecSmrg    winDebug ("winAdjustForAutoHide - Taskbar is auto hide\n");
60505b261ecSmrg
60605b261ecSmrg  /* Look for a TOP auto-hide taskbar */
60705b261ecSmrg  abd.uEdge = ABE_TOP;
60805b261ecSmrg  hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd);
60905b261ecSmrg  if (hwndAutoHide != NULL)
61005b261ecSmrg    {
61105b261ecSmrg      winDebug ("winAdjustForAutoHide - Found TOP auto-hide taskbar\n");
61205b261ecSmrg      prcWorkArea->top += 1;
61305b261ecSmrg    }
61405b261ecSmrg
61505b261ecSmrg  /* Look for a LEFT auto-hide taskbar */
61605b261ecSmrg  abd.uEdge = ABE_LEFT;
61705b261ecSmrg  hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd);
61805b261ecSmrg  if (hwndAutoHide != NULL)
61905b261ecSmrg    {
62005b261ecSmrg      winDebug ("winAdjustForAutoHide - Found LEFT auto-hide taskbar\n");
62105b261ecSmrg      prcWorkArea->left += 1;
62205b261ecSmrg    }
62305b261ecSmrg
62405b261ecSmrg  /* Look for a BOTTOM auto-hide taskbar */
62505b261ecSmrg  abd.uEdge = ABE_BOTTOM;
62605b261ecSmrg  hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd);
62705b261ecSmrg  if (hwndAutoHide != NULL)
62805b261ecSmrg    {
62905b261ecSmrg      winDebug ("winAdjustForAutoHide - Found BOTTOM auto-hide taskbar\n");
63005b261ecSmrg      prcWorkArea->bottom -= 1;
63105b261ecSmrg    }
63205b261ecSmrg
63305b261ecSmrg  /* Look for a RIGHT auto-hide taskbar */
63405b261ecSmrg  abd.uEdge = ABE_RIGHT;
63505b261ecSmrg  hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd);
63605b261ecSmrg  if (hwndAutoHide != NULL)
63705b261ecSmrg    {
63805b261ecSmrg      winDebug ("winAdjustForAutoHide - Found RIGHT auto-hide taskbar\n");
63905b261ecSmrg      prcWorkArea->right -= 1;
64005b261ecSmrg    }
64105b261ecSmrg
64205b261ecSmrg  winDebug ("winAdjustForAutoHide - Adjusted WorkArea: %d %d %d %d\n",
64305b261ecSmrg	  (int) prcWorkArea->top, (int) prcWorkArea->left,
64405b261ecSmrg	  (int) prcWorkArea->bottom, (int) prcWorkArea->right);
64505b261ecSmrg
64605b261ecSmrg#if 0
64705b261ecSmrg  /* Obtain the task bar window dimensions */
64805b261ecSmrg  abd.hWnd = hwndAutoHide;
64905b261ecSmrg  hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETTASKBARPOS, &abd);
65005b261ecSmrg  winDebug ("hwndAutoHide %08x abd.hWnd %08x %d %d %d %d\n",
65105b261ecSmrg	  hwndAutoHide, abd.hWnd,
65205b261ecSmrg	  abd.rc.top, abd.rc.left, abd.rc.bottom, abd.rc.right);
65305b261ecSmrg#endif
65405b261ecSmrg
65505b261ecSmrg  return TRUE;
65605b261ecSmrg}
657