winmultiwindowwindow.c revision 6747b715
105b261ecSmrg/*
205b261ecSmrg *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
36747b715Smrg *Copyright (C) Colin Harrison 2005-2008
405b261ecSmrg *
505b261ecSmrg *Permission is hereby granted, free of charge, to any person obtaining
605b261ecSmrg * a copy of this software and associated documentation files (the
705b261ecSmrg *"Software"), to deal in the Software without restriction, including
805b261ecSmrg *without limitation the rights to use, copy, modify, merge, publish,
905b261ecSmrg *distribute, sublicense, and/or sell copies of the Software, and to
1005b261ecSmrg *permit persons to whom the Software is furnished to do so, subject to
1105b261ecSmrg *the following conditions:
1205b261ecSmrg *
1305b261ecSmrg *The above copyright notice and this permission notice shall be
1405b261ecSmrg *included in all copies or substantial portions of the Software.
1505b261ecSmrg *
1605b261ecSmrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1705b261ecSmrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1805b261ecSmrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1905b261ecSmrg *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
2005b261ecSmrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
2105b261ecSmrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2205b261ecSmrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2305b261ecSmrg *
2405b261ecSmrg *Except as contained in this notice, the name of the XFree86 Project
2505b261ecSmrg *shall not be used in advertising or otherwise to promote the sale, use
2605b261ecSmrg *or other dealings in this Software without prior written authorization
2705b261ecSmrg *from the XFree86 Project.
2805b261ecSmrg *
2905b261ecSmrg * Authors:	Kensuke Matsuzaki
3005b261ecSmrg *		Earle F. Philhower, III
3105b261ecSmrg *		Harold L Hunt II
326747b715Smrg *              Colin Harrison
3305b261ecSmrg */
3405b261ecSmrg
3505b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H
3605b261ecSmrg#include <xwin-config.h>
3705b261ecSmrg#endif
3805b261ecSmrg#include "win.h"
3905b261ecSmrg#include "dixevents.h"
4005b261ecSmrg#include "winmultiwindowclass.h"
4105b261ecSmrg#include "winprefs.h"
4205b261ecSmrg
4305b261ecSmrg/*
4405b261ecSmrg * External global variables
4505b261ecSmrg */
4605b261ecSmrg
476747b715Smrgextern HICON		g_hIconX;
486747b715Smrgextern HICON		g_hSmallIconX;
496747b715Smrgextern HWND		g_hDlgDepthChange;
506747b715Smrgextern Bool             g_fNativeGl;
5105b261ecSmrg
5205b261ecSmrg/*
5305b261ecSmrg * Prototypes for local functions
5405b261ecSmrg */
5505b261ecSmrg
5605b261ecSmrgvoid
5705b261ecSmrgwinCreateWindowsWindow (WindowPtr pWin);
5805b261ecSmrg
5905b261ecSmrgstatic void
6005b261ecSmrgwinDestroyWindowsWindow (WindowPtr pWin);
6105b261ecSmrg
6205b261ecSmrgstatic void
6305b261ecSmrgwinUpdateWindowsWindow (WindowPtr pWin);
6405b261ecSmrg
6505b261ecSmrgstatic void
6605b261ecSmrgwinFindWindow (pointer value, XID id, pointer cdata);
6705b261ecSmrg
686747b715Smrgstatic
696747b715Smrgvoid winInitMultiWindowClass(void)
706747b715Smrg{
716747b715Smrg  static wATOM atomXWinClass=0;
726747b715Smrg  WNDCLASSEX wcx;
736747b715Smrg
746747b715Smrg  if (atomXWinClass==0)
756747b715Smrg  {
766747b715Smrg    /* Setup our window class */
776747b715Smrg    wcx.cbSize=sizeof(WNDCLASSEX);
786747b715Smrg    wcx.style = CS_HREDRAW | CS_VREDRAW | (g_fNativeGl ? CS_OWNDC : 0);
796747b715Smrg    wcx.lpfnWndProc = winTopLevelWindowProc;
806747b715Smrg    wcx.cbClsExtra = 0;
816747b715Smrg    wcx.cbWndExtra = 0;
826747b715Smrg    wcx.hInstance = g_hInstance;
836747b715Smrg    wcx.hIcon = g_hIconX;
846747b715Smrg    wcx.hCursor = 0;
856747b715Smrg    wcx.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
866747b715Smrg    wcx.lpszMenuName = NULL;
876747b715Smrg    wcx.lpszClassName = WINDOW_CLASS_X;
886747b715Smrg    wcx.hIconSm = g_hSmallIconX;
8905b261ecSmrg
906747b715Smrg#if CYGMULTIWINDOW_DEBUG
916747b715Smrg    ErrorF ("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X);
926747b715Smrg#endif
9305b261ecSmrg
946747b715Smrg    atomXWinClass = RegisterClassEx (&wcx);
956747b715Smrg  }
966747b715Smrg}
9705b261ecSmrg
9805b261ecSmrg/*
9905b261ecSmrg * CreateWindow - See Porting Layer Definition - p. 37
10005b261ecSmrg */
10105b261ecSmrg
10205b261ecSmrgBool
10305b261ecSmrgwinCreateWindowMultiWindow (WindowPtr pWin)
10405b261ecSmrg{
10505b261ecSmrg  Bool			fResult = TRUE;
10605b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
10705b261ecSmrg  winWindowPriv(pWin);
10805b261ecSmrg  winScreenPriv(pScreen);
10905b261ecSmrg
11005b261ecSmrg#if CYGMULTIWINDOW_DEBUG
11105b261ecSmrg  winTrace ("winCreateWindowMultiWindow - pWin: %p\n", pWin);
11205b261ecSmrg#endif
11305b261ecSmrg
11405b261ecSmrg  WIN_UNWRAP(CreateWindow);
11505b261ecSmrg  fResult = (*pScreen->CreateWindow) (pWin);
11605b261ecSmrg  WIN_WRAP(CreateWindow, winCreateWindowMultiWindow);
11705b261ecSmrg
11805b261ecSmrg  /* Initialize some privates values */
11905b261ecSmrg  pWinPriv->hRgn = NULL;
12005b261ecSmrg  pWinPriv->hWnd = NULL;
12105b261ecSmrg  pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen);
12205b261ecSmrg  pWinPriv->fXKilled = FALSE;
12305b261ecSmrg
12405b261ecSmrg  return fResult;
12505b261ecSmrg}
12605b261ecSmrg
12705b261ecSmrg
12805b261ecSmrg/*
12905b261ecSmrg * DestroyWindow - See Porting Layer Definition - p. 37
13005b261ecSmrg */
13105b261ecSmrg
13205b261ecSmrgBool
13305b261ecSmrgwinDestroyWindowMultiWindow (WindowPtr pWin)
13405b261ecSmrg{
13505b261ecSmrg  Bool			fResult = TRUE;
13605b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
13705b261ecSmrg  winWindowPriv(pWin);
13805b261ecSmrg  winScreenPriv(pScreen);
13905b261ecSmrg
14005b261ecSmrg#if CYGMULTIWINDOW_DEBUG
14105b261ecSmrg  ErrorF ("winDestroyWindowMultiWindow - pWin: %p\n", pWin);
14205b261ecSmrg#endif
14305b261ecSmrg
14405b261ecSmrg  WIN_UNWRAP(DestroyWindow);
14505b261ecSmrg  fResult = (*pScreen->DestroyWindow)(pWin);
14605b261ecSmrg  WIN_WRAP(DestroyWindow, winDestroyWindowMultiWindow);
14705b261ecSmrg
14805b261ecSmrg  /* Flag that the window has been destroyed */
14905b261ecSmrg  pWinPriv->fXKilled = TRUE;
15005b261ecSmrg
15105b261ecSmrg  /* Kill the MS Windows window associated with this window */
15205b261ecSmrg  winDestroyWindowsWindow (pWin);
15305b261ecSmrg
15405b261ecSmrg  return fResult;
15505b261ecSmrg}
15605b261ecSmrg
15705b261ecSmrg
15805b261ecSmrg/*
15905b261ecSmrg * PositionWindow - See Porting Layer Definition - p. 37
16005b261ecSmrg *
16105b261ecSmrg * This function adjusts the position and size of Windows window
16205b261ecSmrg * with respect to the underlying X window.  This is the inverse
16305b261ecSmrg * of winAdjustXWindow, which adjusts X window to Windows window.
16405b261ecSmrg */
16505b261ecSmrg
16605b261ecSmrgBool
16705b261ecSmrgwinPositionWindowMultiWindow (WindowPtr pWin, int x, int y)
16805b261ecSmrg{
16905b261ecSmrg  Bool			fResult = TRUE;
17005b261ecSmrg  int		        iX, iY, iWidth, iHeight;
17105b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
17205b261ecSmrg  winWindowPriv(pWin);
17305b261ecSmrg  winScreenPriv(pScreen);
17405b261ecSmrg
17505b261ecSmrg  HWND hWnd = pWinPriv->hWnd;
17605b261ecSmrg  RECT rcNew;
17705b261ecSmrg  RECT rcOld;
17805b261ecSmrg#if CYGMULTIWINDOW_DEBUG
17905b261ecSmrg  RECT rcClient;
18005b261ecSmrg  RECT *lpRc;
18105b261ecSmrg#endif
18205b261ecSmrg  DWORD dwExStyle;
18305b261ecSmrg  DWORD dwStyle;
18405b261ecSmrg
18505b261ecSmrg#if CYGMULTIWINDOW_DEBUG
18605b261ecSmrg  winTrace ("winPositionWindowMultiWindow - pWin: %p\n", pWin);
18705b261ecSmrg#endif
18805b261ecSmrg
18905b261ecSmrg  WIN_UNWRAP(PositionWindow);
19005b261ecSmrg  fResult = (*pScreen->PositionWindow)(pWin, x, y);
19105b261ecSmrg  WIN_WRAP(PositionWindow, winPositionWindowMultiWindow);
19205b261ecSmrg
19305b261ecSmrg#if CYGWINDOWING_DEBUG
19405b261ecSmrg  ErrorF ("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n",
19505b261ecSmrg	  x, y);
19605b261ecSmrg#endif
19705b261ecSmrg
19805b261ecSmrg  /* Bail out if the Windows window handle is bad */
19905b261ecSmrg  if (!hWnd)
20005b261ecSmrg    {
20105b261ecSmrg#if CYGWINDOWING_DEBUG
20205b261ecSmrg      ErrorF ("\timmediately return since hWnd is NULL\n");
20305b261ecSmrg#endif
20405b261ecSmrg      return fResult;
20505b261ecSmrg    }
20605b261ecSmrg
20705b261ecSmrg  /* Get the Windows window style and extended style */
20805b261ecSmrg  dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE);
20905b261ecSmrg  dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE);
21005b261ecSmrg
21105b261ecSmrg  /* Get the X and Y location of the X window */
21205b261ecSmrg  iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
21305b261ecSmrg  iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
21405b261ecSmrg
21505b261ecSmrg  /* Get the height and width of the X window */
21605b261ecSmrg  iWidth = pWin->drawable.width;
21705b261ecSmrg  iHeight = pWin->drawable.height;
21805b261ecSmrg
21905b261ecSmrg  /* Store the origin, height, and width in a rectangle structure */
22005b261ecSmrg  SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight);
22105b261ecSmrg
22205b261ecSmrg#if CYGMULTIWINDOW_DEBUG
22305b261ecSmrg  lpRc = &rcNew;
22405b261ecSmrg  ErrorF ("winPositionWindowMultiWindow - (%d ms)drawable (%d, %d)-(%d, %d)\n",
22505b261ecSmrg	  GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
22605b261ecSmrg#endif
22705b261ecSmrg
22805b261ecSmrg  /*
22905b261ecSmrg   * Calculate the required size of the Windows window rectangle,
23005b261ecSmrg   * given the size of the Windows window client area.
23105b261ecSmrg   */
23205b261ecSmrg  AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle);
23305b261ecSmrg
23405b261ecSmrg  /* Get a rectangle describing the old Windows window */
23505b261ecSmrg  GetWindowRect (hWnd, &rcOld);
23605b261ecSmrg
23705b261ecSmrg#if CYGMULTIWINDOW_DEBUG
23805b261ecSmrg  /* Get a rectangle describing the Windows window client area */
23905b261ecSmrg  GetClientRect (hWnd, &rcClient);
24005b261ecSmrg
24105b261ecSmrg  lpRc = &rcNew;
24205b261ecSmrg  ErrorF ("winPositionWindowMultiWindow - (%d ms)rcNew (%d, %d)-(%d, %d)\n",
24305b261ecSmrg	  GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
24405b261ecSmrg
24505b261ecSmrg  lpRc = &rcOld;
24605b261ecSmrg  ErrorF ("winPositionWindowMultiWindow - (%d ms)rcOld (%d, %d)-(%d, %d)\n",
24705b261ecSmrg	  GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
24805b261ecSmrg
24905b261ecSmrg  lpRc = &rcClient;
25005b261ecSmrg  ErrorF ("(%d ms)rcClient (%d, %d)-(%d, %d)\n",
25105b261ecSmrg	  GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
25205b261ecSmrg#endif
25305b261ecSmrg
25405b261ecSmrg  /* Check if the old rectangle and new rectangle are the same */
25505b261ecSmrg  if (!EqualRect (&rcNew, &rcOld))
25605b261ecSmrg    {
25705b261ecSmrg#if CYGMULTIWINDOW_DEBUG
25805b261ecSmrg      ErrorF ("winPositionWindowMultiWindow - Need to move\n");
25905b261ecSmrg#endif
26005b261ecSmrg
26105b261ecSmrg#if CYGWINDOWING_DEBUG
26205b261ecSmrg      ErrorF ("\tMoveWindow to (%ld, %ld) - %ldx%ld\n", rcNew.left, rcNew.top,
26305b261ecSmrg	      rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
26405b261ecSmrg#endif
26505b261ecSmrg      /* Change the position and dimensions of the Windows window */
26605b261ecSmrg      MoveWindow (hWnd,
26705b261ecSmrg		  rcNew.left, rcNew.top,
26805b261ecSmrg		  rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
26905b261ecSmrg		  TRUE);
27005b261ecSmrg    }
27105b261ecSmrg  else
27205b261ecSmrg    {
27305b261ecSmrg#if CYGMULTIWINDOW_DEBUG
27405b261ecSmrg      ErrorF ("winPositionWindowMultiWindow - Not need to move\n");
27505b261ecSmrg#endif
27605b261ecSmrg    }
27705b261ecSmrg
27805b261ecSmrg  return fResult;
27905b261ecSmrg}
28005b261ecSmrg
28105b261ecSmrg
28205b261ecSmrg/*
28305b261ecSmrg * ChangeWindowAttributes - See Porting Layer Definition - p. 37
28405b261ecSmrg */
28505b261ecSmrg
28605b261ecSmrgBool
28705b261ecSmrgwinChangeWindowAttributesMultiWindow (WindowPtr pWin, unsigned long mask)
28805b261ecSmrg{
28905b261ecSmrg  Bool			fResult = TRUE;
29005b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
29105b261ecSmrg  winScreenPriv(pScreen);
29205b261ecSmrg
29305b261ecSmrg#if CYGMULTIWINDOW_DEBUG
29405b261ecSmrg  ErrorF ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin);
29505b261ecSmrg#endif
29605b261ecSmrg
29705b261ecSmrg  WIN_UNWRAP(ChangeWindowAttributes);
29805b261ecSmrg  fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask);
29905b261ecSmrg  WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesMultiWindow);
30005b261ecSmrg
30105b261ecSmrg  /*
30205b261ecSmrg   * NOTE: We do not currently need to do anything here.
30305b261ecSmrg   */
30405b261ecSmrg
30505b261ecSmrg  return fResult;
30605b261ecSmrg}
30705b261ecSmrg
30805b261ecSmrg
30905b261ecSmrg/*
31005b261ecSmrg * UnmapWindow - See Porting Layer Definition - p. 37
31105b261ecSmrg * Also referred to as UnrealizeWindow
31205b261ecSmrg */
31305b261ecSmrg
31405b261ecSmrgBool
31505b261ecSmrgwinUnmapWindowMultiWindow (WindowPtr pWin)
31605b261ecSmrg{
31705b261ecSmrg  Bool			fResult = TRUE;
31805b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
31905b261ecSmrg  winWindowPriv(pWin);
32005b261ecSmrg  winScreenPriv(pScreen);
32105b261ecSmrg
32205b261ecSmrg#if CYGMULTIWINDOW_DEBUG
32305b261ecSmrg  ErrorF ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin);
32405b261ecSmrg#endif
32505b261ecSmrg
32605b261ecSmrg  WIN_UNWRAP(UnrealizeWindow);
32705b261ecSmrg  fResult = (*pScreen->UnrealizeWindow)(pWin);
32805b261ecSmrg  WIN_WRAP(UnrealizeWindow, winUnmapWindowMultiWindow);
32905b261ecSmrg
33005b261ecSmrg  /* Flag that the window has been killed */
33105b261ecSmrg  pWinPriv->fXKilled = TRUE;
33205b261ecSmrg
33305b261ecSmrg  /* Destroy the Windows window associated with this X window */
33405b261ecSmrg  winDestroyWindowsWindow (pWin);
33505b261ecSmrg
33605b261ecSmrg  return fResult;
33705b261ecSmrg}
33805b261ecSmrg
33905b261ecSmrg
34005b261ecSmrg/*
34105b261ecSmrg * MapWindow - See Porting Layer Definition - p. 37
34205b261ecSmrg * Also referred to as RealizeWindow
34305b261ecSmrg */
34405b261ecSmrg
34505b261ecSmrgBool
34605b261ecSmrgwinMapWindowMultiWindow (WindowPtr pWin)
34705b261ecSmrg{
34805b261ecSmrg  Bool			fResult = TRUE;
34905b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
35005b261ecSmrg  winWindowPriv(pWin);
35105b261ecSmrg  winScreenPriv(pScreen);
35205b261ecSmrg
35305b261ecSmrg#if CYGMULTIWINDOW_DEBUG
35405b261ecSmrg  ErrorF ("winMapWindowMultiWindow - pWin: %08x\n", pWin);
35505b261ecSmrg#endif
35605b261ecSmrg
35705b261ecSmrg  WIN_UNWRAP(RealizeWindow);
35805b261ecSmrg  fResult = (*pScreen->RealizeWindow)(pWin);
35905b261ecSmrg  WIN_WRAP(RealizeWindow, winMapWindowMultiWindow);
36005b261ecSmrg
36105b261ecSmrg  /* Flag that this window has not been destroyed */
36205b261ecSmrg  pWinPriv->fXKilled = FALSE;
36305b261ecSmrg
36405b261ecSmrg  /* Refresh/redisplay the Windows window associated with this X window */
36505b261ecSmrg  winUpdateWindowsWindow (pWin);
36605b261ecSmrg
36705b261ecSmrg  /* Update the Windows window's shape */
36805b261ecSmrg  winReshapeMultiWindow (pWin);
36905b261ecSmrg  winUpdateRgnMultiWindow (pWin);
37005b261ecSmrg
37105b261ecSmrg  return fResult;
37205b261ecSmrg}
37305b261ecSmrg
37405b261ecSmrg
37505b261ecSmrg/*
37605b261ecSmrg * ReparentWindow - See Porting Layer Definition - p. 42
37705b261ecSmrg */
37805b261ecSmrg
37905b261ecSmrgvoid
38005b261ecSmrgwinReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent)
38105b261ecSmrg{
38205b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
38305b261ecSmrg  winScreenPriv(pScreen);
38405b261ecSmrg
38505b261ecSmrg#if CYGMULTIWINDOW_DEBUG
38605b261ecSmrg  ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin);
38705b261ecSmrg#endif
38805b261ecSmrg
38905b261ecSmrg  WIN_UNWRAP(ReparentWindow);
39005b261ecSmrg  if (pScreen->ReparentWindow)
39105b261ecSmrg    (*pScreen->ReparentWindow)(pWin, pPriorParent);
39205b261ecSmrg  WIN_WRAP(ReparentWindow, winReparentWindowMultiWindow);
39305b261ecSmrg
39405b261ecSmrg  /* Update the Windows window associated with this X window */
39505b261ecSmrg  winUpdateWindowsWindow (pWin);
39605b261ecSmrg}
39705b261ecSmrg
39805b261ecSmrg
39905b261ecSmrg/*
40005b261ecSmrg * RestackWindow - Shuffle the z-order of a window
40105b261ecSmrg */
40205b261ecSmrg
40305b261ecSmrgvoid
40405b261ecSmrgwinRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib)
40505b261ecSmrg{
4066747b715Smrg#if 0
40705b261ecSmrg  WindowPtr		pPrevWin;
40805b261ecSmrg  UINT			uFlags;
40905b261ecSmrg  HWND			hInsertAfter;
41005b261ecSmrg  HWND                  hWnd = NULL;
4116747b715Smrg#endif
41205b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
41305b261ecSmrg  winScreenPriv(pScreen);
41405b261ecSmrg
41505b261ecSmrg#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
41605b261ecSmrg  winTrace ("winRestackMultiWindow - %08x\n", pWin);
41705b261ecSmrg#endif
41805b261ecSmrg
41905b261ecSmrg   WIN_UNWRAP(RestackWindow);
42005b261ecSmrg   if (pScreen->RestackWindow)
42105b261ecSmrg     (*pScreen->RestackWindow)(pWin, pOldNextSib);
42205b261ecSmrg   WIN_WRAP(RestackWindow, winRestackWindowMultiWindow);
42305b261ecSmrg
42405b261ecSmrg#if 1
42505b261ecSmrg  /*
42605b261ecSmrg   * Calling winReorderWindowsMultiWindow here means our window manager
42705b261ecSmrg   * (i.e. Windows Explorer) has initiative to determine Z order.
42805b261ecSmrg   */
42905b261ecSmrg  if (pWin->nextSib != pOldNextSib)
43005b261ecSmrg    winReorderWindowsMultiWindow ();
43105b261ecSmrg#else
43205b261ecSmrg  /* Bail out if no window privates or window handle is invalid */
43305b261ecSmrg  if (!pWinPriv || !pWinPriv->hWnd)
43405b261ecSmrg    return;
43505b261ecSmrg
43605b261ecSmrg  /* Get a pointer to our previous sibling window */
43705b261ecSmrg  pPrevWin = pWin->prevSib;
43805b261ecSmrg
43905b261ecSmrg  /*
44005b261ecSmrg   * Look for a sibling window with
44105b261ecSmrg   * valid privates and window handle
44205b261ecSmrg   */
44305b261ecSmrg  while (pPrevWin
44405b261ecSmrg	 && !winGetWindowPriv(pPrevWin)
44505b261ecSmrg	 && !winGetWindowPriv(pPrevWin)->hWnd)
44605b261ecSmrg    pPrevWin = pPrevWin->prevSib;
44705b261ecSmrg
44805b261ecSmrg  /* Check if we found a valid sibling */
44905b261ecSmrg  if (pPrevWin)
45005b261ecSmrg    {
45105b261ecSmrg      /* Valid sibling - get handle to insert window after */
45205b261ecSmrg      hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd;
45305b261ecSmrg      uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
45405b261ecSmrg
45505b261ecSmrg      hWnd = GetNextWindow (pWinPriv->hWnd, GW_HWNDPREV);
45605b261ecSmrg
45705b261ecSmrg      do
45805b261ecSmrg	{
45905b261ecSmrg	  if (GetProp (hWnd, WIN_WINDOW_PROP))
46005b261ecSmrg	    {
46105b261ecSmrg	      if (hWnd == winGetWindowPriv(pPrevWin)->hWnd)
46205b261ecSmrg		{
46305b261ecSmrg		  uFlags |= SWP_NOZORDER;
46405b261ecSmrg		}
46505b261ecSmrg	      break;
46605b261ecSmrg	    }
46705b261ecSmrg	  hWnd = GetNextWindow (hWnd, GW_HWNDPREV);
46805b261ecSmrg	}
46905b261ecSmrg      while (hWnd);
47005b261ecSmrg    }
47105b261ecSmrg  else
47205b261ecSmrg    {
47305b261ecSmrg      /* No valid sibling - make this window the top window */
47405b261ecSmrg      hInsertAfter = HWND_TOP;
47505b261ecSmrg      uFlags = SWP_NOMOVE | SWP_NOSIZE;
47605b261ecSmrg    }
47705b261ecSmrg
47805b261ecSmrg  /* Perform the restacking operation in Windows */
47905b261ecSmrg  SetWindowPos (pWinPriv->hWnd,
48005b261ecSmrg		hInsertAfter,
48105b261ecSmrg		0, 0,
48205b261ecSmrg		0, 0,
48305b261ecSmrg		uFlags);
48405b261ecSmrg#endif
48505b261ecSmrg}
48605b261ecSmrg
48705b261ecSmrg
48805b261ecSmrg/*
48905b261ecSmrg * winCreateWindowsWindow - Create a Windows window associated with an X window
49005b261ecSmrg */
49105b261ecSmrg
49205b261ecSmrgvoid
49305b261ecSmrgwinCreateWindowsWindow (WindowPtr pWin)
49405b261ecSmrg{
49505b261ecSmrg  int                   iX, iY;
49605b261ecSmrg  int			iWidth;
49705b261ecSmrg  int			iHeight;
49805b261ecSmrg  HWND			hWnd;
4996747b715Smrg  HWND			hFore = NULL;
50005b261ecSmrg  winWindowPriv(pWin);
50105b261ecSmrg  HICON			hIcon;
50205b261ecSmrg  HICON			hIconSmall;
50305b261ecSmrg  winPrivScreenPtr	pScreenPriv = pWinPriv->pScreenPriv;
50405b261ecSmrg  WinXSizeHints         hints;
5056747b715Smrg  WindowPtr		pDaddy;
5066747b715Smrg
5076747b715Smrg  winInitMultiWindowClass();
50805b261ecSmrg
50905b261ecSmrg#if CYGMULTIWINDOW_DEBUG
51005b261ecSmrg  ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin);
51105b261ecSmrg#endif
51205b261ecSmrg
51305b261ecSmrg  iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
51405b261ecSmrg  iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
51505b261ecSmrg
51605b261ecSmrg  iWidth = pWin->drawable.width;
51705b261ecSmrg  iHeight = pWin->drawable.height;
51805b261ecSmrg
5196747b715Smrg  /* ensure window actually ends up somewhere visible */
5206747b715Smrg  if (iX > GetSystemMetrics (SM_CXVIRTUALSCREEN))
5216747b715Smrg    iX = CW_USEDEFAULT;
52205b261ecSmrg
5236747b715Smrg  if (iY > GetSystemMetrics (SM_CYVIRTUALSCREEN))
5246747b715Smrg    iY = CW_USEDEFAULT;
52505b261ecSmrg
5266747b715Smrg  if (winMultiWindowGetTransientFor (pWin, &pDaddy))
52705b261ecSmrg    {
5286747b715Smrg      if (pDaddy)
5296747b715Smrg      {
5306747b715Smrg        hFore = GetForegroundWindow();
5316747b715Smrg        if (hFore && (pDaddy != (WindowPtr)GetProp(hFore, WIN_WID_PROP))) hFore = NULL;
5326747b715Smrg      }
5336747b715Smrg    }
5346747b715Smrg  else
5356747b715Smrg    {
5366747b715Smrg      /* Default positions if none specified */
5376747b715Smrg      if (!winMultiWindowGetWMNormalHints(pWin, &hints))
5386747b715Smrg        hints.flags = 0;
5396747b715Smrg      if (!(hints.flags & (USPosition|PPosition)) &&
5406747b715Smrg          !pWin->overrideRedirect)
5416747b715Smrg      {
5426747b715Smrg        iX = CW_USEDEFAULT;
5436747b715Smrg        iY = CW_USEDEFAULT;
5446747b715Smrg      }
54505b261ecSmrg    }
54605b261ecSmrg
54705b261ecSmrg  /* Create the window */
54805b261ecSmrg  /* Make it OVERLAPPED in create call since WS_POPUP doesn't support */
54905b261ecSmrg  /* CW_USEDEFAULT, change back to popup after creation */
55005b261ecSmrg  hWnd = CreateWindowExA (WS_EX_TOOLWINDOW,	/* Extended styles */
5516747b715Smrg			  WINDOW_CLASS_X,	/* Class name */
55205b261ecSmrg			  WINDOW_TITLE_X,	/* Window name */
55305b261ecSmrg			  WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
55405b261ecSmrg			  iX,			/* Horizontal position */
55505b261ecSmrg			  iY,			/* Vertical position */
55605b261ecSmrg			  iWidth,		/* Right edge */
55705b261ecSmrg			  iHeight,		/* Bottom edge */
5586747b715Smrg			  hFore,		/* Null or Parent window if transient*/
55905b261ecSmrg			  (HMENU) NULL,		/* No menu */
56005b261ecSmrg			  GetModuleHandle (NULL), /* Instance handle */
56105b261ecSmrg			  pWin);		/* ScreenPrivates */
56205b261ecSmrg  if (hWnd == NULL)
56305b261ecSmrg    {
56405b261ecSmrg      ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
56505b261ecSmrg	      (int) GetLastError ());
56605b261ecSmrg    }
5676747b715Smrg  pWinPriv->hWnd = hWnd;
5686747b715Smrg
5696747b715Smrg  /* Set application or .XWinrc defined Icons */
5706747b715Smrg  winSelectIcons(pWin, &hIcon, &hIconSmall);
5716747b715Smrg  if (hIcon) SendMessage (hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
5726747b715Smrg  if (hIconSmall) SendMessage (hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall);
57305b261ecSmrg
57405b261ecSmrg  /* Change style back to popup, already placed... */
5756747b715Smrg  SetWindowLongPtr(hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
57605b261ecSmrg  SetWindowPos (hWnd, 0, 0, 0, 0, 0,
57705b261ecSmrg		SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
57805b261ecSmrg  /* Make sure it gets the proper system menu for a WS_POPUP, too */
57905b261ecSmrg  GetSystemMenu (hWnd, TRUE);
58005b261ecSmrg
58105b261ecSmrg  /* Cause any .XWinrc menus to be added in main WNDPROC */
58205b261ecSmrg  PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0);
58305b261ecSmrg
5846747b715Smrg  SetProp (hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin));
58505b261ecSmrg
58605b261ecSmrg  /* Flag that this Windows window handles its own activation */
5876747b715Smrg  SetProp (hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0);
58805b261ecSmrg
58905b261ecSmrg  /* Call engine-specific create window procedure */
59005b261ecSmrg  (*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin);
59105b261ecSmrg}
59205b261ecSmrg
59305b261ecSmrg
59405b261ecSmrgBool winInDestroyWindowsWindow = FALSE;
59505b261ecSmrg/*
59605b261ecSmrg * winDestroyWindowsWindow - Destroy a Windows window associated
59705b261ecSmrg * with an X window
59805b261ecSmrg */
59905b261ecSmrgstatic void
60005b261ecSmrgwinDestroyWindowsWindow (WindowPtr pWin)
60105b261ecSmrg{
60205b261ecSmrg  MSG			msg;
60305b261ecSmrg  winWindowPriv(pWin);
60405b261ecSmrg  BOOL			oldstate = winInDestroyWindowsWindow;
60505b261ecSmrg
60605b261ecSmrg#if CYGMULTIWINDOW_DEBUG
60705b261ecSmrg  ErrorF ("winDestroyWindowsWindow\n");
60805b261ecSmrg#endif
60905b261ecSmrg
61005b261ecSmrg  /* Bail out if the Windows window handle is invalid */
61105b261ecSmrg  if (pWinPriv->hWnd == NULL)
61205b261ecSmrg    return;
61305b261ecSmrg
61405b261ecSmrg  winInDestroyWindowsWindow = TRUE;
61505b261ecSmrg
61605b261ecSmrg  SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, NULL);
61705b261ecSmrg  /* Destroy the Windows window */
61805b261ecSmrg  DestroyWindow (pWinPriv->hWnd);
61905b261ecSmrg
62005b261ecSmrg  /* Null our handle to the Window so referencing it will cause an error */
62105b261ecSmrg  pWinPriv->hWnd = NULL;
62205b261ecSmrg
62305b261ecSmrg  /* Process all messages on our queue */
62405b261ecSmrg  while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
62505b261ecSmrg    {
62605b261ecSmrg      if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg))
62705b261ecSmrg	{
62805b261ecSmrg	  DispatchMessage (&msg);
62905b261ecSmrg	}
63005b261ecSmrg    }
63105b261ecSmrg
63205b261ecSmrg  winInDestroyWindowsWindow = oldstate;
63305b261ecSmrg
63405b261ecSmrg#if CYGMULTIWINDOW_DEBUG
63505b261ecSmrg  ErrorF ("-winDestroyWindowsWindow\n");
63605b261ecSmrg#endif
63705b261ecSmrg}
63805b261ecSmrg
63905b261ecSmrg
64005b261ecSmrg/*
64105b261ecSmrg * winUpdateWindowsWindow - Redisplay/redraw a Windows window
64205b261ecSmrg * associated with an X window
64305b261ecSmrg */
64405b261ecSmrg
64505b261ecSmrgstatic void
64605b261ecSmrgwinUpdateWindowsWindow (WindowPtr pWin)
64705b261ecSmrg{
64805b261ecSmrg  winWindowPriv(pWin);
64905b261ecSmrg  HWND			hWnd = pWinPriv->hWnd;
65005b261ecSmrg
65105b261ecSmrg#if CYGMULTIWINDOW_DEBUG
65205b261ecSmrg  ErrorF ("winUpdateWindowsWindow\n");
65305b261ecSmrg#endif
65405b261ecSmrg
65505b261ecSmrg  /* Check if the Windows window's parents have been destroyed */
65605b261ecSmrg  if (pWin->parent != NULL
65705b261ecSmrg      && pWin->parent->parent == NULL
65805b261ecSmrg      && pWin->mapped)
65905b261ecSmrg    {
66005b261ecSmrg      /* Create the Windows window if it has been destroyed */
66105b261ecSmrg      if (hWnd == NULL)
66205b261ecSmrg	{
66305b261ecSmrg	  winCreateWindowsWindow (pWin);
66405b261ecSmrg	  assert (pWinPriv->hWnd != NULL);
66505b261ecSmrg	}
66605b261ecSmrg
66705b261ecSmrg      /* Display the window without activating it */
66805b261ecSmrg      ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE);
66905b261ecSmrg
67005b261ecSmrg      /* Send first paint message */
67105b261ecSmrg      UpdateWindow (pWinPriv->hWnd);
67205b261ecSmrg    }
67305b261ecSmrg  else if (hWnd != NULL)
67405b261ecSmrg    {
67505b261ecSmrg      /* Destroy the Windows window if its parents are destroyed */
67605b261ecSmrg      winDestroyWindowsWindow (pWin);
67705b261ecSmrg      assert (pWinPriv->hWnd == NULL);
67805b261ecSmrg    }
67905b261ecSmrg
68005b261ecSmrg#if CYGMULTIWINDOW_DEBUG
68105b261ecSmrg  ErrorF ("-winUpdateWindowsWindow\n");
68205b261ecSmrg#endif
68305b261ecSmrg}
68405b261ecSmrg
68505b261ecSmrg
68605b261ecSmrg/*
68705b261ecSmrg * winGetWindowID -
68805b261ecSmrg */
68905b261ecSmrg
69005b261ecSmrgXID
69105b261ecSmrgwinGetWindowID (WindowPtr pWin)
69205b261ecSmrg{
69305b261ecSmrg  WindowIDPairRec	wi = {pWin, 0};
69405b261ecSmrg  ClientPtr		c = wClient(pWin);
69505b261ecSmrg
69605b261ecSmrg  /* */
69705b261ecSmrg  FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi);
69805b261ecSmrg
69905b261ecSmrg#if CYGMULTIWINDOW_DEBUG
70005b261ecSmrg  ErrorF ("winGetWindowID - Window ID: %d\n", wi.id);
70105b261ecSmrg#endif
70205b261ecSmrg
70305b261ecSmrg  return wi.id;
70405b261ecSmrg}
70505b261ecSmrg
70605b261ecSmrg
70705b261ecSmrg/*
70805b261ecSmrg * winFindWindow -
70905b261ecSmrg */
71005b261ecSmrg
71105b261ecSmrgstatic void
71205b261ecSmrgwinFindWindow (pointer value, XID id, pointer cdata)
71305b261ecSmrg{
71405b261ecSmrg  WindowIDPairPtr	wi = (WindowIDPairPtr)cdata;
71505b261ecSmrg
71605b261ecSmrg  if (value == wi->value)
71705b261ecSmrg    {
71805b261ecSmrg      wi->id = id;
71905b261ecSmrg    }
72005b261ecSmrg}
72105b261ecSmrg
72205b261ecSmrg
72305b261ecSmrg/*
72405b261ecSmrg * winReorderWindowsMultiWindow -
72505b261ecSmrg */
72605b261ecSmrg
72705b261ecSmrgvoid
72805b261ecSmrgwinReorderWindowsMultiWindow (void)
72905b261ecSmrg{
73005b261ecSmrg  HWND hwnd = NULL;
73105b261ecSmrg  WindowPtr pWin = NULL;
73205b261ecSmrg  WindowPtr pWinSib = NULL;
73305b261ecSmrg  XID vlist[2];
73405b261ecSmrg  static Bool fRestacking = FALSE; /* Avoid recusive calls to this function */
73505b261ecSmrg  DWORD dwCurrentProcessID = GetCurrentProcessId ();
73605b261ecSmrg  DWORD dwWindowProcessID = 0;
73705b261ecSmrg
73805b261ecSmrg#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
73905b261ecSmrg  winTrace ("winReorderWindowsMultiWindow\n");
74005b261ecSmrg#endif
74105b261ecSmrg
74205b261ecSmrg  if (fRestacking)
74305b261ecSmrg    {
74405b261ecSmrg      /* It is a recusive call so immediately exit */
74505b261ecSmrg#if CYGWINDOWING_DEBUG
74605b261ecSmrg      ErrorF ("winReorderWindowsMultiWindow - "
74705b261ecSmrg	      "exit because fRestacking == TRUE\n");
74805b261ecSmrg#endif
74905b261ecSmrg      return;
75005b261ecSmrg    }
75105b261ecSmrg  fRestacking = TRUE;
75205b261ecSmrg
75305b261ecSmrg  /* Loop through top level Window windows, descending in Z order */
75405b261ecSmrg  for ( hwnd = GetTopWindow (NULL);
75505b261ecSmrg	hwnd;
75605b261ecSmrg	hwnd = GetNextWindow (hwnd, GW_HWNDNEXT) )
75705b261ecSmrg    {
75805b261ecSmrg      /* Don't take care of other Cygwin/X process's windows */
75905b261ecSmrg      GetWindowThreadProcessId (hwnd, &dwWindowProcessID);
76005b261ecSmrg
76105b261ecSmrg      if ( GetProp (hwnd, WIN_WINDOW_PROP)
76205b261ecSmrg	   && (dwWindowProcessID == dwCurrentProcessID)
76305b261ecSmrg	   && !IsIconic (hwnd) ) /* ignore minimized windows */
76405b261ecSmrg	{
76505b261ecSmrg	  pWinSib = pWin;
76605b261ecSmrg	  pWin = GetProp (hwnd, WIN_WINDOW_PROP);
76705b261ecSmrg
76805b261ecSmrg	  if (!pWinSib)
76905b261ecSmrg	    { /* 1st window - raise to the top */
77005b261ecSmrg	      vlist[0] = Above;
77105b261ecSmrg
77205b261ecSmrg	      ConfigureWindow (pWin, CWStackMode, vlist, wClient(pWin));
77305b261ecSmrg	    }
77405b261ecSmrg	  else
77505b261ecSmrg	    { /* 2nd or deeper windows - just below the previous one */
77605b261ecSmrg	      vlist[0] = winGetWindowID (pWinSib);
77705b261ecSmrg	      vlist[1] = Below;
77805b261ecSmrg
77905b261ecSmrg	      ConfigureWindow (pWin, CWSibling | CWStackMode,
78005b261ecSmrg			       vlist, wClient(pWin));
78105b261ecSmrg	    }
78205b261ecSmrg	}
78305b261ecSmrg    }
78405b261ecSmrg
78505b261ecSmrg  fRestacking = FALSE;
78605b261ecSmrg}
78705b261ecSmrg
78805b261ecSmrg
78905b261ecSmrg/*
79005b261ecSmrg * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE
79105b261ecSmrg */
79205b261ecSmrg
79305b261ecSmrgvoid
79405b261ecSmrgwinMinimizeWindow (Window id)
79505b261ecSmrg{
79605b261ecSmrg  WindowPtr		pWin;
79705b261ecSmrg  winPrivWinPtr	pWinPriv;
79805b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
79905b261ecSmrg  win32RootlessWindowPtr pRLWinPriv;
80005b261ecSmrg#endif
80105b261ecSmrg  HWND hWnd;
80205b261ecSmrg  ScreenPtr pScreen = NULL;
80305b261ecSmrg  winPrivScreenPtr pScreenPriv = NULL;
80405b261ecSmrg  winScreenInfo *pScreenInfo = NULL;
80505b261ecSmrg
80605b261ecSmrg#if CYGWINDOWING_DEBUG
80705b261ecSmrg  ErrorF ("winMinimizeWindow\n");
80805b261ecSmrg#endif
80905b261ecSmrg
8106747b715Smrg  dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess);
81105b261ecSmrg  if (!pWin)
81205b261ecSmrg  {
81305b261ecSmrg      ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__);
81405b261ecSmrg      return;
81505b261ecSmrg  }
81605b261ecSmrg
81705b261ecSmrg  pScreen = pWin->drawable.pScreen;
81805b261ecSmrg  if (pScreen) pScreenPriv = winGetScreenPriv(pScreen);
81905b261ecSmrg  if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
82005b261ecSmrg
82105b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
82205b261ecSmrg  if (pScreenPriv && pScreenInfo->fInternalWM)
82305b261ecSmrg    {
82405b261ecSmrg      pRLWinPriv  = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
82505b261ecSmrg      hWnd = pRLWinPriv->hWnd;
82605b261ecSmrg    }
82705b261ecSmrg  else
82805b261ecSmrg#else
82905b261ecSmrg  if (pScreenPriv)
83005b261ecSmrg#endif
83105b261ecSmrg    {
83205b261ecSmrg      pWinPriv = winGetWindowPriv (pWin);
83305b261ecSmrg      hWnd = pWinPriv->hWnd;
83405b261ecSmrg    }
83505b261ecSmrg
83605b261ecSmrg  ShowWindow (hWnd, SW_MINIMIZE);
83705b261ecSmrg}
83805b261ecSmrg
83905b261ecSmrg
84005b261ecSmrg/*
84105b261ecSmrg * CopyWindow - See Porting Layer Definition - p. 39
84205b261ecSmrg */
84305b261ecSmrgvoid
84405b261ecSmrgwinCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt,
84505b261ecSmrg			  RegionPtr oldRegion)
84605b261ecSmrg{
84705b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
84805b261ecSmrg  winScreenPriv(pScreen);
84905b261ecSmrg
85005b261ecSmrg#if CYGWINDOWING_DEBUG
85105b261ecSmrg  ErrorF ("CopyWindowMultiWindow\n");
85205b261ecSmrg#endif
85305b261ecSmrg  WIN_UNWRAP(CopyWindow);
85405b261ecSmrg  (*pScreen->CopyWindow)(pWin, oldpt, oldRegion);
85505b261ecSmrg  WIN_WRAP(CopyWindow, winCopyWindowMultiWindow);
85605b261ecSmrg}
85705b261ecSmrg
85805b261ecSmrg
85905b261ecSmrg/*
86005b261ecSmrg * MoveWindow - See Porting Layer Definition - p. 42
86105b261ecSmrg */
86205b261ecSmrgvoid
86305b261ecSmrgwinMoveWindowMultiWindow (WindowPtr pWin, int x, int y,
86405b261ecSmrg			  WindowPtr pSib, VTKind kind)
86505b261ecSmrg{
86605b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
86705b261ecSmrg  winScreenPriv(pScreen);
86805b261ecSmrg
86905b261ecSmrg#if CYGWINDOWING_DEBUG
87005b261ecSmrg  ErrorF ("MoveWindowMultiWindow to (%d, %d)\n", x, y);
87105b261ecSmrg#endif
87205b261ecSmrg
87305b261ecSmrg  WIN_UNWRAP(MoveWindow);
87405b261ecSmrg  (*pScreen->MoveWindow)(pWin, x, y, pSib, kind);
87505b261ecSmrg  WIN_WRAP(MoveWindow, winMoveWindowMultiWindow);
87605b261ecSmrg}
87705b261ecSmrg
87805b261ecSmrg
87905b261ecSmrg/*
88005b261ecSmrg * ResizeWindow - See Porting Layer Definition - p. 42
88105b261ecSmrg */
88205b261ecSmrgvoid
88305b261ecSmrgwinResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w,
88405b261ecSmrg			    unsigned int h, WindowPtr pSib)
88505b261ecSmrg{
88605b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
88705b261ecSmrg  winScreenPriv(pScreen);
88805b261ecSmrg
88905b261ecSmrg#if CYGWINDOWING_DEBUG
89005b261ecSmrg  ErrorF ("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x, y, w, h);
89105b261ecSmrg#endif
89205b261ecSmrg  WIN_UNWRAP(ResizeWindow);
89305b261ecSmrg  (*pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
89405b261ecSmrg  WIN_WRAP(ResizeWindow, winResizeWindowMultiWindow);
89505b261ecSmrg}
89605b261ecSmrg
89705b261ecSmrg
89805b261ecSmrg/*
89905b261ecSmrg * winAdjustXWindow
90005b261ecSmrg *
90105b261ecSmrg * Move and resize X window with respect to corresponding Windows window.
90205b261ecSmrg * This is called from WM_MOVE/WM_SIZE handlers when the user performs
90305b261ecSmrg * any windowing operation (move, resize, minimize, maximize, restore).
90405b261ecSmrg *
90505b261ecSmrg * The functionality is the inverse of winPositionWindowMultiWindow, which
90605b261ecSmrg * adjusts Windows window with respect to X window.
90705b261ecSmrg */
90805b261ecSmrgint
90905b261ecSmrgwinAdjustXWindow (WindowPtr pWin, HWND hwnd)
91005b261ecSmrg{
91105b261ecSmrg  RECT rcDraw; /* Rect made from pWin->drawable to be adjusted */
91205b261ecSmrg  RECT rcWin;  /* The source: WindowRect from hwnd */
91305b261ecSmrg  DrawablePtr pDraw;
91405b261ecSmrg  XID vlist[4];
91505b261ecSmrg  LONG dX, dY, dW, dH, x, y;
91605b261ecSmrg  DWORD dwStyle, dwExStyle;
91705b261ecSmrg
91805b261ecSmrg#define WIDTH(rc) (rc.right - rc.left)
91905b261ecSmrg#define HEIGHT(rc) (rc.bottom - rc.top)
92005b261ecSmrg
92105b261ecSmrg#if CYGWINDOWING_DEBUG
92205b261ecSmrg  ErrorF ("winAdjustXWindow\n");
92305b261ecSmrg#endif
92405b261ecSmrg
92505b261ecSmrg  if (IsIconic (hwnd))
92605b261ecSmrg    {
92705b261ecSmrg#if CYGWINDOWING_DEBUG
92805b261ecSmrg      ErrorF ("\timmediately return because the window is iconized\n");
92905b261ecSmrg#endif
93005b261ecSmrg      /*
93105b261ecSmrg       * If the Windows window is minimized, its WindowRect has
93205b261ecSmrg       * meaningless values so we don't adjust X window to it.
93305b261ecSmrg       */
93405b261ecSmrg      vlist[0] = 0;
93505b261ecSmrg      vlist[1] = 0;
93605b261ecSmrg      return ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin));
93705b261ecSmrg    }
93805b261ecSmrg
93905b261ecSmrg  pDraw = &pWin->drawable;
94005b261ecSmrg
94105b261ecSmrg  /* Calculate the window rect from the drawable */
94205b261ecSmrg  x = pDraw->x + GetSystemMetrics (SM_XVIRTUALSCREEN);
94305b261ecSmrg  y = pDraw->y + GetSystemMetrics (SM_YVIRTUALSCREEN);
94405b261ecSmrg  SetRect (&rcDraw, x, y, x + pDraw->width, y + pDraw->height);
94505b261ecSmrg#ifdef CYGMULTIWINDOW_DEBUG
94605b261ecSmrg          winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n",
94705b261ecSmrg              rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom,
94805b261ecSmrg              rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top);
94905b261ecSmrg#endif
95005b261ecSmrg  dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE);
95105b261ecSmrg  dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE);
95205b261ecSmrg#ifdef CYGMULTIWINDOW_DEBUG
95305b261ecSmrg          winDebug("\tWindowStyle: %08x %08x\n", dwStyle, dwExStyle);
95405b261ecSmrg#endif
95505b261ecSmrg  AdjustWindowRectEx (&rcDraw, dwStyle, FALSE, dwExStyle);
95605b261ecSmrg
95705b261ecSmrg  /* The source of adjust */
95805b261ecSmrg  GetWindowRect (hwnd, &rcWin);
95905b261ecSmrg#ifdef CYGMULTIWINDOW_DEBUG
96005b261ecSmrg          winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
96105b261ecSmrg              rcWin.left, rcWin.top, rcWin.right, rcWin.bottom,
96205b261ecSmrg              rcWin.right - rcWin.left, rcWin.bottom - rcWin.top);
96305b261ecSmrg          winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n",
96405b261ecSmrg              rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom,
96505b261ecSmrg              rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top);
96605b261ecSmrg#endif
96705b261ecSmrg
96805b261ecSmrg  if (EqualRect (&rcDraw, &rcWin)) {
96905b261ecSmrg    /* Bail if no adjust is needed */
97005b261ecSmrg#if CYGWINDOWING_DEBUG
97105b261ecSmrg    ErrorF ("\treturn because already adjusted\n");
97205b261ecSmrg#endif
97305b261ecSmrg    return 0;
97405b261ecSmrg  }
97505b261ecSmrg
97605b261ecSmrg  /* Calculate delta values */
97705b261ecSmrg  dX = rcWin.left - rcDraw.left;
97805b261ecSmrg  dY = rcWin.top - rcDraw.top;
97905b261ecSmrg  dW = WIDTH(rcWin) - WIDTH(rcDraw);
98005b261ecSmrg  dH = HEIGHT(rcWin) - HEIGHT(rcDraw);
98105b261ecSmrg
98205b261ecSmrg  /*
98305b261ecSmrg   * Adjust.
98405b261ecSmrg   * We may only need to move (vlist[0] and [1]), or only resize
98505b261ecSmrg   * ([2] and [3]) but currently we set all the parameters and leave
98605b261ecSmrg   * the decision to ConfigureWindow.  The reason is code simplicity.
98705b261ecSmrg  */
98805b261ecSmrg  vlist[0] = pDraw->x + dX - wBorderWidth(pWin);
98905b261ecSmrg  vlist[1] = pDraw->y + dY - wBorderWidth(pWin);
99005b261ecSmrg  vlist[2] = pDraw->width + dW;
99105b261ecSmrg  vlist[3] = pDraw->height + dH;
99205b261ecSmrg#if CYGWINDOWING_DEBUG
99305b261ecSmrg  ErrorF ("\tConfigureWindow to (%ld, %ld) - %ldx%ld\n", vlist[0], vlist[1],
99405b261ecSmrg	  vlist[2], vlist[3]);
99505b261ecSmrg#endif
99605b261ecSmrg  return ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight,
99705b261ecSmrg			  vlist, wClient(pWin));
99805b261ecSmrg
99905b261ecSmrg#undef WIDTH
100005b261ecSmrg#undef HEIGHT
100105b261ecSmrg}
100205b261ecSmrg
1003