winmultiwindowwindow.c revision 05b261ec
105b261ecSmrg/*
205b261ecSmrg *Copyright (C) 1994-2000 The XFree86 Project, Inc. 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 THE XFREE86 PROJECT 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 the XFree86 Project
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 the XFree86 Project.
2705b261ecSmrg *
2805b261ecSmrg * Authors:	Kensuke Matsuzaki
2905b261ecSmrg *		Earle F. Philhower, III
3005b261ecSmrg *		Harold L Hunt II
3105b261ecSmrg */
3205b261ecSmrg
3305b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H
3405b261ecSmrg#include <xwin-config.h>
3505b261ecSmrg#endif
3605b261ecSmrg#include "win.h"
3705b261ecSmrg#include "dixevents.h"
3805b261ecSmrg#include "winmultiwindowclass.h"
3905b261ecSmrg#include "winprefs.h"
4005b261ecSmrg
4105b261ecSmrg/*
4205b261ecSmrg * External global variables
4305b261ecSmrg */
4405b261ecSmrg
4505b261ecSmrgextern HWND			g_hDlgDepthChange;
4605b261ecSmrg
4705b261ecSmrgextern void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon);
4805b261ecSmrg
4905b261ecSmrg/*
5005b261ecSmrg * Prototypes for local functions
5105b261ecSmrg */
5205b261ecSmrg
5305b261ecSmrgvoid
5405b261ecSmrgwinCreateWindowsWindow (WindowPtr pWin);
5505b261ecSmrg
5605b261ecSmrgstatic void
5705b261ecSmrgwinDestroyWindowsWindow (WindowPtr pWin);
5805b261ecSmrg
5905b261ecSmrgstatic void
6005b261ecSmrgwinUpdateWindowsWindow (WindowPtr pWin);
6105b261ecSmrg
6205b261ecSmrgstatic void
6305b261ecSmrgwinFindWindow (pointer value, XID id, pointer cdata);
6405b261ecSmrg
6505b261ecSmrg/*
6605b261ecSmrg * Constant defines
6705b261ecSmrg */
6805b261ecSmrg
6905b261ecSmrg#define MOUSE_POLLING_INTERVAL		500
7005b261ecSmrg
7105b261ecSmrg
7205b261ecSmrg/*
7305b261ecSmrg * Macros
7405b261ecSmrg */
7505b261ecSmrg
7605b261ecSmrg#define SubSend(pWin) \
7705b261ecSmrg    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
7805b261ecSmrg
7905b261ecSmrg#define StrSend(pWin) \
8005b261ecSmrg    ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
8105b261ecSmrg
8205b261ecSmrg#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
8305b261ecSmrg
8405b261ecSmrg
8505b261ecSmrg/*
8605b261ecSmrg * CreateWindow - See Porting Layer Definition - p. 37
8705b261ecSmrg */
8805b261ecSmrg
8905b261ecSmrgBool
9005b261ecSmrgwinCreateWindowMultiWindow (WindowPtr pWin)
9105b261ecSmrg{
9205b261ecSmrg  Bool			fResult = TRUE;
9305b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
9405b261ecSmrg  winWindowPriv(pWin);
9505b261ecSmrg  winScreenPriv(pScreen);
9605b261ecSmrg
9705b261ecSmrg#if CYGMULTIWINDOW_DEBUG
9805b261ecSmrg  winTrace ("winCreateWindowMultiWindow - pWin: %p\n", pWin);
9905b261ecSmrg#endif
10005b261ecSmrg
10105b261ecSmrg  WIN_UNWRAP(CreateWindow);
10205b261ecSmrg  fResult = (*pScreen->CreateWindow) (pWin);
10305b261ecSmrg  WIN_WRAP(CreateWindow, winCreateWindowMultiWindow);
10405b261ecSmrg
10505b261ecSmrg  /* Initialize some privates values */
10605b261ecSmrg  pWinPriv->hRgn = NULL;
10705b261ecSmrg  pWinPriv->hWnd = NULL;
10805b261ecSmrg  pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen);
10905b261ecSmrg  pWinPriv->fXKilled = FALSE;
11005b261ecSmrg
11105b261ecSmrg  return fResult;
11205b261ecSmrg}
11305b261ecSmrg
11405b261ecSmrg
11505b261ecSmrg/*
11605b261ecSmrg * DestroyWindow - See Porting Layer Definition - p. 37
11705b261ecSmrg */
11805b261ecSmrg
11905b261ecSmrgBool
12005b261ecSmrgwinDestroyWindowMultiWindow (WindowPtr pWin)
12105b261ecSmrg{
12205b261ecSmrg  Bool			fResult = TRUE;
12305b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
12405b261ecSmrg  winWindowPriv(pWin);
12505b261ecSmrg  winScreenPriv(pScreen);
12605b261ecSmrg
12705b261ecSmrg#if CYGMULTIWINDOW_DEBUG
12805b261ecSmrg  ErrorF ("winDestroyWindowMultiWindow - pWin: %p\n", pWin);
12905b261ecSmrg#endif
13005b261ecSmrg
13105b261ecSmrg  WIN_UNWRAP(DestroyWindow);
13205b261ecSmrg  fResult = (*pScreen->DestroyWindow)(pWin);
13305b261ecSmrg  WIN_WRAP(DestroyWindow, winDestroyWindowMultiWindow);
13405b261ecSmrg
13505b261ecSmrg  /* Flag that the window has been destroyed */
13605b261ecSmrg  pWinPriv->fXKilled = TRUE;
13705b261ecSmrg
13805b261ecSmrg  /* Kill the MS Windows window associated with this window */
13905b261ecSmrg  winDestroyWindowsWindow (pWin);
14005b261ecSmrg
14105b261ecSmrg  return fResult;
14205b261ecSmrg}
14305b261ecSmrg
14405b261ecSmrg
14505b261ecSmrg/*
14605b261ecSmrg * PositionWindow - See Porting Layer Definition - p. 37
14705b261ecSmrg *
14805b261ecSmrg * This function adjusts the position and size of Windows window
14905b261ecSmrg * with respect to the underlying X window.  This is the inverse
15005b261ecSmrg * of winAdjustXWindow, which adjusts X window to Windows window.
15105b261ecSmrg */
15205b261ecSmrg
15305b261ecSmrgBool
15405b261ecSmrgwinPositionWindowMultiWindow (WindowPtr pWin, int x, int y)
15505b261ecSmrg{
15605b261ecSmrg  Bool			fResult = TRUE;
15705b261ecSmrg  int		        iX, iY, iWidth, iHeight;
15805b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
15905b261ecSmrg  winWindowPriv(pWin);
16005b261ecSmrg  winScreenPriv(pScreen);
16105b261ecSmrg
16205b261ecSmrg  HWND hWnd = pWinPriv->hWnd;
16305b261ecSmrg  RECT rcNew;
16405b261ecSmrg  RECT rcOld;
16505b261ecSmrg#if CYGMULTIWINDOW_DEBUG
16605b261ecSmrg  RECT rcClient;
16705b261ecSmrg  RECT *lpRc;
16805b261ecSmrg#endif
16905b261ecSmrg  DWORD dwExStyle;
17005b261ecSmrg  DWORD dwStyle;
17105b261ecSmrg
17205b261ecSmrg#if CYGMULTIWINDOW_DEBUG
17305b261ecSmrg  winTrace ("winPositionWindowMultiWindow - pWin: %p\n", pWin);
17405b261ecSmrg#endif
17505b261ecSmrg
17605b261ecSmrg  WIN_UNWRAP(PositionWindow);
17705b261ecSmrg  fResult = (*pScreen->PositionWindow)(pWin, x, y);
17805b261ecSmrg  WIN_WRAP(PositionWindow, winPositionWindowMultiWindow);
17905b261ecSmrg
18005b261ecSmrg#if CYGWINDOWING_DEBUG
18105b261ecSmrg  ErrorF ("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n",
18205b261ecSmrg	  x, y);
18305b261ecSmrg#endif
18405b261ecSmrg
18505b261ecSmrg  /* Bail out if the Windows window handle is bad */
18605b261ecSmrg  if (!hWnd)
18705b261ecSmrg    {
18805b261ecSmrg#if CYGWINDOWING_DEBUG
18905b261ecSmrg      ErrorF ("\timmediately return since hWnd is NULL\n");
19005b261ecSmrg#endif
19105b261ecSmrg      return fResult;
19205b261ecSmrg    }
19305b261ecSmrg
19405b261ecSmrg  /* Get the Windows window style and extended style */
19505b261ecSmrg  dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE);
19605b261ecSmrg  dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE);
19705b261ecSmrg
19805b261ecSmrg  /* Get the X and Y location of the X window */
19905b261ecSmrg  iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
20005b261ecSmrg  iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
20105b261ecSmrg
20205b261ecSmrg  /* Get the height and width of the X window */
20305b261ecSmrg  iWidth = pWin->drawable.width;
20405b261ecSmrg  iHeight = pWin->drawable.height;
20505b261ecSmrg
20605b261ecSmrg  /* Store the origin, height, and width in a rectangle structure */
20705b261ecSmrg  SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight);
20805b261ecSmrg
20905b261ecSmrg#if CYGMULTIWINDOW_DEBUG
21005b261ecSmrg  lpRc = &rcNew;
21105b261ecSmrg  ErrorF ("winPositionWindowMultiWindow - (%d ms)drawable (%d, %d)-(%d, %d)\n",
21205b261ecSmrg	  GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
21305b261ecSmrg#endif
21405b261ecSmrg
21505b261ecSmrg  /*
21605b261ecSmrg   * Calculate the required size of the Windows window rectangle,
21705b261ecSmrg   * given the size of the Windows window client area.
21805b261ecSmrg   */
21905b261ecSmrg  AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle);
22005b261ecSmrg
22105b261ecSmrg  /* Get a rectangle describing the old Windows window */
22205b261ecSmrg  GetWindowRect (hWnd, &rcOld);
22305b261ecSmrg
22405b261ecSmrg#if CYGMULTIWINDOW_DEBUG
22505b261ecSmrg  /* Get a rectangle describing the Windows window client area */
22605b261ecSmrg  GetClientRect (hWnd, &rcClient);
22705b261ecSmrg
22805b261ecSmrg  lpRc = &rcNew;
22905b261ecSmrg  ErrorF ("winPositionWindowMultiWindow - (%d ms)rcNew (%d, %d)-(%d, %d)\n",
23005b261ecSmrg	  GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
23105b261ecSmrg
23205b261ecSmrg  lpRc = &rcOld;
23305b261ecSmrg  ErrorF ("winPositionWindowMultiWindow - (%d ms)rcOld (%d, %d)-(%d, %d)\n",
23405b261ecSmrg	  GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
23505b261ecSmrg
23605b261ecSmrg  lpRc = &rcClient;
23705b261ecSmrg  ErrorF ("(%d ms)rcClient (%d, %d)-(%d, %d)\n",
23805b261ecSmrg	  GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
23905b261ecSmrg#endif
24005b261ecSmrg
24105b261ecSmrg  /* Check if the old rectangle and new rectangle are the same */
24205b261ecSmrg  if (!EqualRect (&rcNew, &rcOld))
24305b261ecSmrg    {
24405b261ecSmrg#if CYGMULTIWINDOW_DEBUG
24505b261ecSmrg      ErrorF ("winPositionWindowMultiWindow - Need to move\n");
24605b261ecSmrg#endif
24705b261ecSmrg
24805b261ecSmrg#if CYGWINDOWING_DEBUG
24905b261ecSmrg      ErrorF ("\tMoveWindow to (%ld, %ld) - %ldx%ld\n", rcNew.left, rcNew.top,
25005b261ecSmrg	      rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
25105b261ecSmrg#endif
25205b261ecSmrg      /* Change the position and dimensions of the Windows window */
25305b261ecSmrg      MoveWindow (hWnd,
25405b261ecSmrg		  rcNew.left, rcNew.top,
25505b261ecSmrg		  rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
25605b261ecSmrg		  TRUE);
25705b261ecSmrg    }
25805b261ecSmrg  else
25905b261ecSmrg    {
26005b261ecSmrg#if CYGMULTIWINDOW_DEBUG
26105b261ecSmrg      ErrorF ("winPositionWindowMultiWindow - Not need to move\n");
26205b261ecSmrg#endif
26305b261ecSmrg    }
26405b261ecSmrg
26505b261ecSmrg  return fResult;
26605b261ecSmrg}
26705b261ecSmrg
26805b261ecSmrg
26905b261ecSmrg/*
27005b261ecSmrg * ChangeWindowAttributes - See Porting Layer Definition - p. 37
27105b261ecSmrg */
27205b261ecSmrg
27305b261ecSmrgBool
27405b261ecSmrgwinChangeWindowAttributesMultiWindow (WindowPtr pWin, unsigned long mask)
27505b261ecSmrg{
27605b261ecSmrg  Bool			fResult = TRUE;
27705b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
27805b261ecSmrg  winWindowPriv(pWin);
27905b261ecSmrg  winScreenPriv(pScreen);
28005b261ecSmrg
28105b261ecSmrg#if CYGMULTIWINDOW_DEBUG
28205b261ecSmrg  ErrorF ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin);
28305b261ecSmrg#endif
28405b261ecSmrg
28505b261ecSmrg  WIN_UNWRAP(ChangeWindowAttributes);
28605b261ecSmrg  fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask);
28705b261ecSmrg  WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesMultiWindow);
28805b261ecSmrg
28905b261ecSmrg  /*
29005b261ecSmrg   * NOTE: We do not currently need to do anything here.
29105b261ecSmrg   */
29205b261ecSmrg
29305b261ecSmrg  return fResult;
29405b261ecSmrg}
29505b261ecSmrg
29605b261ecSmrg
29705b261ecSmrg/*
29805b261ecSmrg * UnmapWindow - See Porting Layer Definition - p. 37
29905b261ecSmrg * Also referred to as UnrealizeWindow
30005b261ecSmrg */
30105b261ecSmrg
30205b261ecSmrgBool
30305b261ecSmrgwinUnmapWindowMultiWindow (WindowPtr pWin)
30405b261ecSmrg{
30505b261ecSmrg  Bool			fResult = TRUE;
30605b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
30705b261ecSmrg  winWindowPriv(pWin);
30805b261ecSmrg  winScreenPriv(pScreen);
30905b261ecSmrg
31005b261ecSmrg#if CYGMULTIWINDOW_DEBUG
31105b261ecSmrg  ErrorF ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin);
31205b261ecSmrg#endif
31305b261ecSmrg
31405b261ecSmrg  WIN_UNWRAP(UnrealizeWindow);
31505b261ecSmrg  fResult = (*pScreen->UnrealizeWindow)(pWin);
31605b261ecSmrg  WIN_WRAP(UnrealizeWindow, winUnmapWindowMultiWindow);
31705b261ecSmrg
31805b261ecSmrg  /* Flag that the window has been killed */
31905b261ecSmrg  pWinPriv->fXKilled = TRUE;
32005b261ecSmrg
32105b261ecSmrg  /* Destroy the Windows window associated with this X window */
32205b261ecSmrg  winDestroyWindowsWindow (pWin);
32305b261ecSmrg
32405b261ecSmrg  return fResult;
32505b261ecSmrg}
32605b261ecSmrg
32705b261ecSmrg
32805b261ecSmrg/*
32905b261ecSmrg * MapWindow - See Porting Layer Definition - p. 37
33005b261ecSmrg * Also referred to as RealizeWindow
33105b261ecSmrg */
33205b261ecSmrg
33305b261ecSmrgBool
33405b261ecSmrgwinMapWindowMultiWindow (WindowPtr pWin)
33505b261ecSmrg{
33605b261ecSmrg  Bool			fResult = TRUE;
33705b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
33805b261ecSmrg  winWindowPriv(pWin);
33905b261ecSmrg  winScreenPriv(pScreen);
34005b261ecSmrg
34105b261ecSmrg#if CYGMULTIWINDOW_DEBUG
34205b261ecSmrg  ErrorF ("winMapWindowMultiWindow - pWin: %08x\n", pWin);
34305b261ecSmrg#endif
34405b261ecSmrg
34505b261ecSmrg  WIN_UNWRAP(RealizeWindow);
34605b261ecSmrg  fResult = (*pScreen->RealizeWindow)(pWin);
34705b261ecSmrg  WIN_WRAP(RealizeWindow, winMapWindowMultiWindow);
34805b261ecSmrg
34905b261ecSmrg  /* Flag that this window has not been destroyed */
35005b261ecSmrg  pWinPriv->fXKilled = FALSE;
35105b261ecSmrg
35205b261ecSmrg  /* Refresh/redisplay the Windows window associated with this X window */
35305b261ecSmrg  winUpdateWindowsWindow (pWin);
35405b261ecSmrg
35505b261ecSmrg#ifdef SHAPE
35605b261ecSmrg  /* Update the Windows window's shape */
35705b261ecSmrg  winReshapeMultiWindow (pWin);
35805b261ecSmrg  winUpdateRgnMultiWindow (pWin);
35905b261ecSmrg#endif
36005b261ecSmrg
36105b261ecSmrg  return fResult;
36205b261ecSmrg}
36305b261ecSmrg
36405b261ecSmrg
36505b261ecSmrg/*
36605b261ecSmrg * ReparentWindow - See Porting Layer Definition - p. 42
36705b261ecSmrg */
36805b261ecSmrg
36905b261ecSmrgvoid
37005b261ecSmrgwinReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent)
37105b261ecSmrg{
37205b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
37305b261ecSmrg  winWindowPriv(pWin);
37405b261ecSmrg  winScreenPriv(pScreen);
37505b261ecSmrg
37605b261ecSmrg#if CYGMULTIWINDOW_DEBUG
37705b261ecSmrg  ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin);
37805b261ecSmrg#endif
37905b261ecSmrg
38005b261ecSmrg  WIN_UNWRAP(ReparentWindow);
38105b261ecSmrg  if (pScreen->ReparentWindow)
38205b261ecSmrg    (*pScreen->ReparentWindow)(pWin, pPriorParent);
38305b261ecSmrg  WIN_WRAP(ReparentWindow, winReparentWindowMultiWindow);
38405b261ecSmrg
38505b261ecSmrg  /* Update the Windows window associated with this X window */
38605b261ecSmrg  winUpdateWindowsWindow (pWin);
38705b261ecSmrg}
38805b261ecSmrg
38905b261ecSmrg
39005b261ecSmrg/*
39105b261ecSmrg * RestackWindow - Shuffle the z-order of a window
39205b261ecSmrg */
39305b261ecSmrg
39405b261ecSmrgvoid
39505b261ecSmrgwinRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib)
39605b261ecSmrg{
39705b261ecSmrg  WindowPtr		pPrevWin;
39805b261ecSmrg  UINT			uFlags;
39905b261ecSmrg  HWND			hInsertAfter;
40005b261ecSmrg  HWND                  hWnd = NULL;
40105b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
40205b261ecSmrg  winWindowPriv(pWin);
40305b261ecSmrg  winScreenPriv(pScreen);
40405b261ecSmrg
40505b261ecSmrg#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
40605b261ecSmrg  winTrace ("winRestackMultiWindow - %08x\n", pWin);
40705b261ecSmrg#endif
40805b261ecSmrg
40905b261ecSmrg   WIN_UNWRAP(RestackWindow);
41005b261ecSmrg   if (pScreen->RestackWindow)
41105b261ecSmrg     (*pScreen->RestackWindow)(pWin, pOldNextSib);
41205b261ecSmrg   WIN_WRAP(RestackWindow, winRestackWindowMultiWindow);
41305b261ecSmrg
41405b261ecSmrg#if 1
41505b261ecSmrg  /*
41605b261ecSmrg   * Calling winReorderWindowsMultiWindow here means our window manager
41705b261ecSmrg   * (i.e. Windows Explorer) has initiative to determine Z order.
41805b261ecSmrg   */
41905b261ecSmrg  if (pWin->nextSib != pOldNextSib)
42005b261ecSmrg    winReorderWindowsMultiWindow ();
42105b261ecSmrg#else
42205b261ecSmrg  /* Bail out if no window privates or window handle is invalid */
42305b261ecSmrg  if (!pWinPriv || !pWinPriv->hWnd)
42405b261ecSmrg    return;
42505b261ecSmrg
42605b261ecSmrg  /* Get a pointer to our previous sibling window */
42705b261ecSmrg  pPrevWin = pWin->prevSib;
42805b261ecSmrg
42905b261ecSmrg  /*
43005b261ecSmrg   * Look for a sibling window with
43105b261ecSmrg   * valid privates and window handle
43205b261ecSmrg   */
43305b261ecSmrg  while (pPrevWin
43405b261ecSmrg	 && !winGetWindowPriv(pPrevWin)
43505b261ecSmrg	 && !winGetWindowPriv(pPrevWin)->hWnd)
43605b261ecSmrg    pPrevWin = pPrevWin->prevSib;
43705b261ecSmrg
43805b261ecSmrg  /* Check if we found a valid sibling */
43905b261ecSmrg  if (pPrevWin)
44005b261ecSmrg    {
44105b261ecSmrg      /* Valid sibling - get handle to insert window after */
44205b261ecSmrg      hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd;
44305b261ecSmrg      uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
44405b261ecSmrg
44505b261ecSmrg      hWnd = GetNextWindow (pWinPriv->hWnd, GW_HWNDPREV);
44605b261ecSmrg
44705b261ecSmrg      do
44805b261ecSmrg	{
44905b261ecSmrg	  if (GetProp (hWnd, WIN_WINDOW_PROP))
45005b261ecSmrg	    {
45105b261ecSmrg	      if (hWnd == winGetWindowPriv(pPrevWin)->hWnd)
45205b261ecSmrg		{
45305b261ecSmrg		  uFlags |= SWP_NOZORDER;
45405b261ecSmrg		}
45505b261ecSmrg	      break;
45605b261ecSmrg	    }
45705b261ecSmrg	  hWnd = GetNextWindow (hWnd, GW_HWNDPREV);
45805b261ecSmrg	}
45905b261ecSmrg      while (hWnd);
46005b261ecSmrg    }
46105b261ecSmrg  else
46205b261ecSmrg    {
46305b261ecSmrg      /* No valid sibling - make this window the top window */
46405b261ecSmrg      hInsertAfter = HWND_TOP;
46505b261ecSmrg      uFlags = SWP_NOMOVE | SWP_NOSIZE;
46605b261ecSmrg    }
46705b261ecSmrg
46805b261ecSmrg  /* Perform the restacking operation in Windows */
46905b261ecSmrg  SetWindowPos (pWinPriv->hWnd,
47005b261ecSmrg		hInsertAfter,
47105b261ecSmrg		0, 0,
47205b261ecSmrg		0, 0,
47305b261ecSmrg		uFlags);
47405b261ecSmrg#endif
47505b261ecSmrg}
47605b261ecSmrg
47705b261ecSmrg
47805b261ecSmrg/*
47905b261ecSmrg * winCreateWindowsWindow - Create a Windows window associated with an X window
48005b261ecSmrg */
48105b261ecSmrg
48205b261ecSmrgvoid
48305b261ecSmrgwinCreateWindowsWindow (WindowPtr pWin)
48405b261ecSmrg{
48505b261ecSmrg  int                   iX, iY;
48605b261ecSmrg  int			iWidth;
48705b261ecSmrg  int			iHeight;
48805b261ecSmrg  HWND			hWnd;
48905b261ecSmrg  WNDCLASSEX		wc;
49005b261ecSmrg  winWindowPriv(pWin);
49105b261ecSmrg  HICON			hIcon;
49205b261ecSmrg  HICON			hIconSmall;
49305b261ecSmrg#define CLASS_NAME_LENGTH 512
49405b261ecSmrg  char                  pszClass[CLASS_NAME_LENGTH], pszWindowID[12];
49505b261ecSmrg  char                  *res_name, *res_class, *res_role;
49605b261ecSmrg  static int		s_iWindowID = 0;
49705b261ecSmrg  winPrivScreenPtr	pScreenPriv = pWinPriv->pScreenPriv;
49805b261ecSmrg  WinXSizeHints         hints;
49905b261ecSmrg
50005b261ecSmrg#if CYGMULTIWINDOW_DEBUG
50105b261ecSmrg  ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin);
50205b261ecSmrg#endif
50305b261ecSmrg
50405b261ecSmrg  iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
50505b261ecSmrg  iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
50605b261ecSmrg
50705b261ecSmrg  /* Default positions if none specified */
50805b261ecSmrg  if (!winMultiWindowGetWMNormalHints(pWin, &hints))
50905b261ecSmrg    hints.flags = 0;
51005b261ecSmrg  if ( !(hints.flags & (USPosition|PPosition)) &&
51105b261ecSmrg       !winMultiWindowGetTransientFor (pWin, NULL) &&
51205b261ecSmrg       !pWin->overrideRedirect )
51305b261ecSmrg    {
51405b261ecSmrg      iX = CW_USEDEFAULT;
51505b261ecSmrg      iY = CW_USEDEFAULT;
51605b261ecSmrg    }
51705b261ecSmrg
51805b261ecSmrg  iWidth = pWin->drawable.width;
51905b261ecSmrg  iHeight = pWin->drawable.height;
52005b261ecSmrg
52105b261ecSmrg  winSelectIcons(pWin, &hIcon, &hIconSmall);
52205b261ecSmrg
52305b261ecSmrg  /* Set standard class name prefix so we can identify window easily */
52405b261ecSmrg  strncpy (pszClass, WINDOW_CLASS_X, sizeof(pszClass));
52505b261ecSmrg
52605b261ecSmrg  if (winMultiWindowGetClassHint (pWin, &res_name, &res_class))
52705b261ecSmrg    {
52805b261ecSmrg      strncat (pszClass, "-", 1);
52905b261ecSmrg      strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass));
53005b261ecSmrg      strncat (pszClass, "-", 1);
53105b261ecSmrg      strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass));
53205b261ecSmrg
53305b261ecSmrg      /* Check if a window class is provided by the WM_WINDOW_ROLE property,
53405b261ecSmrg       * if not use the WM_CLASS information.
53505b261ecSmrg       * For further information see:
53605b261ecSmrg       * http://tronche.com/gui/x/icccm/sec-5.html
53705b261ecSmrg       */
53805b261ecSmrg      if (winMultiWindowGetWindowRole (pWin, &res_role) )
53905b261ecSmrg	{
54005b261ecSmrg	  strcat (pszClass, "-");
54105b261ecSmrg	  strcat (pszClass, res_role);
54205b261ecSmrg	  free (res_role);
54305b261ecSmrg	}
54405b261ecSmrg
54505b261ecSmrg      free (res_name);
54605b261ecSmrg      free (res_class);
54705b261ecSmrg    }
54805b261ecSmrg
54905b261ecSmrg  /* Add incrementing window ID to make unique class name */
55005b261ecSmrg  snprintf (pszWindowID, sizeof(pszWindowID), "-%x", s_iWindowID++);
55105b261ecSmrg  pszWindowID[sizeof(pszWindowID)-1] = 0;
55205b261ecSmrg  strcat (pszClass, pszWindowID);
55305b261ecSmrg
55405b261ecSmrg#if CYGMULTIWINDOW_DEBUG
55505b261ecSmrg  ErrorF ("winCreateWindowsWindow - Creating class: %s\n", pszClass);
55605b261ecSmrg#endif
55705b261ecSmrg
55805b261ecSmrg  /* Setup our window class */
55905b261ecSmrg  wc.cbSize = sizeof(wc);
56005b261ecSmrg  wc.style = CS_HREDRAW | CS_VREDRAW;
56105b261ecSmrg  wc.lpfnWndProc = winTopLevelWindowProc;
56205b261ecSmrg  wc.cbClsExtra = 0;
56305b261ecSmrg  wc.cbWndExtra = 0;
56405b261ecSmrg  wc.hInstance = g_hInstance;
56505b261ecSmrg  wc.hIcon = hIcon;
56605b261ecSmrg  wc.hIconSm = hIconSmall;
56705b261ecSmrg  wc.hCursor = 0;
56805b261ecSmrg  wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
56905b261ecSmrg  wc.lpszMenuName = NULL;
57005b261ecSmrg  wc.lpszClassName = pszClass;
57105b261ecSmrg  RegisterClassEx (&wc);
57205b261ecSmrg
57305b261ecSmrg  /* Create the window */
57405b261ecSmrg  /* Make it OVERLAPPED in create call since WS_POPUP doesn't support */
57505b261ecSmrg  /* CW_USEDEFAULT, change back to popup after creation */
57605b261ecSmrg  hWnd = CreateWindowExA (WS_EX_TOOLWINDOW,	/* Extended styles */
57705b261ecSmrg			  pszClass,		/* Class name */
57805b261ecSmrg			  WINDOW_TITLE_X,	/* Window name */
57905b261ecSmrg			  WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
58005b261ecSmrg			  iX,			/* Horizontal position */
58105b261ecSmrg			  iY,			/* Vertical position */
58205b261ecSmrg			  iWidth,		/* Right edge */
58305b261ecSmrg			  iHeight,		/* Bottom edge */
58405b261ecSmrg			  (HWND) NULL,		/* No parent or owner window */
58505b261ecSmrg			  (HMENU) NULL,		/* No menu */
58605b261ecSmrg			  GetModuleHandle (NULL), /* Instance handle */
58705b261ecSmrg			  pWin);		/* ScreenPrivates */
58805b261ecSmrg  if (hWnd == NULL)
58905b261ecSmrg    {
59005b261ecSmrg      ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
59105b261ecSmrg	      (int) GetLastError ());
59205b261ecSmrg    }
59305b261ecSmrg
59405b261ecSmrg  /* Change style back to popup, already placed... */
59505b261ecSmrg  SetWindowLong (hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
59605b261ecSmrg  SetWindowPos (hWnd, 0, 0, 0, 0, 0,
59705b261ecSmrg		SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
59805b261ecSmrg  /* Make sure it gets the proper system menu for a WS_POPUP, too */
59905b261ecSmrg  GetSystemMenu (hWnd, TRUE);
60005b261ecSmrg
60105b261ecSmrg  pWinPriv->hWnd = hWnd;
60205b261ecSmrg
60305b261ecSmrg  /* Cause any .XWinrc menus to be added in main WNDPROC */
60405b261ecSmrg  PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0);
60505b261ecSmrg
60605b261ecSmrg  SetProp (pWinPriv->hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin));
60705b261ecSmrg
60805b261ecSmrg  /* Flag that this Windows window handles its own activation */
60905b261ecSmrg  SetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0);
61005b261ecSmrg
61105b261ecSmrg  /* Call engine-specific create window procedure */
61205b261ecSmrg  (*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin);
61305b261ecSmrg}
61405b261ecSmrg
61505b261ecSmrg
61605b261ecSmrgBool winInDestroyWindowsWindow = FALSE;
61705b261ecSmrg/*
61805b261ecSmrg * winDestroyWindowsWindow - Destroy a Windows window associated
61905b261ecSmrg * with an X window
62005b261ecSmrg */
62105b261ecSmrgstatic void
62205b261ecSmrgwinDestroyWindowsWindow (WindowPtr pWin)
62305b261ecSmrg{
62405b261ecSmrg  MSG			msg;
62505b261ecSmrg  winWindowPriv(pWin);
62605b261ecSmrg  HICON			hiconClass;
62705b261ecSmrg  HICON			hiconSmClass;
62805b261ecSmrg  HMODULE		hInstance;
62905b261ecSmrg  int			iReturn;
63005b261ecSmrg  char			pszClass[512];
63105b261ecSmrg  BOOL			oldstate = winInDestroyWindowsWindow;
63205b261ecSmrg
63305b261ecSmrg#if CYGMULTIWINDOW_DEBUG
63405b261ecSmrg  ErrorF ("winDestroyWindowsWindow\n");
63505b261ecSmrg#endif
63605b261ecSmrg
63705b261ecSmrg  /* Bail out if the Windows window handle is invalid */
63805b261ecSmrg  if (pWinPriv->hWnd == NULL)
63905b261ecSmrg    return;
64005b261ecSmrg
64105b261ecSmrg  winInDestroyWindowsWindow = TRUE;
64205b261ecSmrg
64305b261ecSmrg  /* Store the info we need to destroy after this window is gone */
64405b261ecSmrg  hInstance = (HINSTANCE) GetClassLong (pWinPriv->hWnd, GCL_HMODULE);
64505b261ecSmrg  hiconClass = (HICON) GetClassLong (pWinPriv->hWnd, GCL_HICON);
64605b261ecSmrg  hiconSmClass = (HICON) GetClassLong (pWinPriv->hWnd, GCL_HICONSM);
64705b261ecSmrg  iReturn = GetClassName (pWinPriv->hWnd, pszClass, 512);
64805b261ecSmrg
64905b261ecSmrg  SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, NULL);
65005b261ecSmrg  /* Destroy the Windows window */
65105b261ecSmrg  DestroyWindow (pWinPriv->hWnd);
65205b261ecSmrg
65305b261ecSmrg  /* Null our handle to the Window so referencing it will cause an error */
65405b261ecSmrg  pWinPriv->hWnd = NULL;
65505b261ecSmrg
65605b261ecSmrg  /* Process all messages on our queue */
65705b261ecSmrg  while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
65805b261ecSmrg    {
65905b261ecSmrg      if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg))
66005b261ecSmrg	{
66105b261ecSmrg	  DispatchMessage (&msg);
66205b261ecSmrg	}
66305b261ecSmrg    }
66405b261ecSmrg
66505b261ecSmrg  /* Only if we were able to get the name */
66605b261ecSmrg  if (iReturn)
66705b261ecSmrg    {
66805b261ecSmrg#if CYGMULTIWINDOW_DEBUG
66905b261ecSmrg      ErrorF ("winDestroyWindowsWindow - Unregistering %s: ", pszClass);
67005b261ecSmrg#endif
67105b261ecSmrg      iReturn = UnregisterClass (pszClass, hInstance);
67205b261ecSmrg
67305b261ecSmrg#if CYGMULTIWINDOW_DEBUG
67405b261ecSmrg      ErrorF ("winDestroyWindowsWindow - %d Deleting Icon: ", iReturn);
67505b261ecSmrg#endif
67605b261ecSmrg
67705b261ecSmrg      winDestroyIcon(hiconClass);
67805b261ecSmrg      winDestroyIcon(hiconSmClass);
67905b261ecSmrg    }
68005b261ecSmrg
68105b261ecSmrg  winInDestroyWindowsWindow = oldstate;
68205b261ecSmrg
68305b261ecSmrg#if CYGMULTIWINDOW_DEBUG
68405b261ecSmrg  ErrorF ("-winDestroyWindowsWindow\n");
68505b261ecSmrg#endif
68605b261ecSmrg}
68705b261ecSmrg
68805b261ecSmrg
68905b261ecSmrg/*
69005b261ecSmrg * winUpdateWindowsWindow - Redisplay/redraw a Windows window
69105b261ecSmrg * associated with an X window
69205b261ecSmrg */
69305b261ecSmrg
69405b261ecSmrgstatic void
69505b261ecSmrgwinUpdateWindowsWindow (WindowPtr pWin)
69605b261ecSmrg{
69705b261ecSmrg  winWindowPriv(pWin);
69805b261ecSmrg  HWND			hWnd = pWinPriv->hWnd;
69905b261ecSmrg
70005b261ecSmrg#if CYGMULTIWINDOW_DEBUG
70105b261ecSmrg  ErrorF ("winUpdateWindowsWindow\n");
70205b261ecSmrg#endif
70305b261ecSmrg
70405b261ecSmrg  /* Check if the Windows window's parents have been destroyed */
70505b261ecSmrg  if (pWin->parent != NULL
70605b261ecSmrg      && pWin->parent->parent == NULL
70705b261ecSmrg      && pWin->mapped)
70805b261ecSmrg    {
70905b261ecSmrg      /* Create the Windows window if it has been destroyed */
71005b261ecSmrg      if (hWnd == NULL)
71105b261ecSmrg	{
71205b261ecSmrg	  winCreateWindowsWindow (pWin);
71305b261ecSmrg	  assert (pWinPriv->hWnd != NULL);
71405b261ecSmrg	}
71505b261ecSmrg
71605b261ecSmrg      /* Display the window without activating it */
71705b261ecSmrg      ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE);
71805b261ecSmrg
71905b261ecSmrg      /* Send first paint message */
72005b261ecSmrg      UpdateWindow (pWinPriv->hWnd);
72105b261ecSmrg    }
72205b261ecSmrg  else if (hWnd != NULL)
72305b261ecSmrg    {
72405b261ecSmrg      /* Destroy the Windows window if its parents are destroyed */
72505b261ecSmrg      winDestroyWindowsWindow (pWin);
72605b261ecSmrg      assert (pWinPriv->hWnd == NULL);
72705b261ecSmrg    }
72805b261ecSmrg
72905b261ecSmrg#if CYGMULTIWINDOW_DEBUG
73005b261ecSmrg  ErrorF ("-winUpdateWindowsWindow\n");
73105b261ecSmrg#endif
73205b261ecSmrg}
73305b261ecSmrg
73405b261ecSmrg
73505b261ecSmrg/*
73605b261ecSmrg * winGetWindowID -
73705b261ecSmrg */
73805b261ecSmrg
73905b261ecSmrgXID
74005b261ecSmrgwinGetWindowID (WindowPtr pWin)
74105b261ecSmrg{
74205b261ecSmrg  WindowIDPairRec	wi = {pWin, 0};
74305b261ecSmrg  ClientPtr		c = wClient(pWin);
74405b261ecSmrg
74505b261ecSmrg  /* */
74605b261ecSmrg  FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi);
74705b261ecSmrg
74805b261ecSmrg#if CYGMULTIWINDOW_DEBUG
74905b261ecSmrg  ErrorF ("winGetWindowID - Window ID: %d\n", wi.id);
75005b261ecSmrg#endif
75105b261ecSmrg
75205b261ecSmrg  return wi.id;
75305b261ecSmrg}
75405b261ecSmrg
75505b261ecSmrg
75605b261ecSmrg/*
75705b261ecSmrg * winFindWindow -
75805b261ecSmrg */
75905b261ecSmrg
76005b261ecSmrgstatic void
76105b261ecSmrgwinFindWindow (pointer value, XID id, pointer cdata)
76205b261ecSmrg{
76305b261ecSmrg  WindowIDPairPtr	wi = (WindowIDPairPtr)cdata;
76405b261ecSmrg
76505b261ecSmrg  if (value == wi->value)
76605b261ecSmrg    {
76705b261ecSmrg      wi->id = id;
76805b261ecSmrg    }
76905b261ecSmrg}
77005b261ecSmrg
77105b261ecSmrg
77205b261ecSmrg/*
77305b261ecSmrg * winReorderWindowsMultiWindow -
77405b261ecSmrg */
77505b261ecSmrg
77605b261ecSmrgvoid
77705b261ecSmrgwinReorderWindowsMultiWindow (void)
77805b261ecSmrg{
77905b261ecSmrg  HWND hwnd = NULL;
78005b261ecSmrg  WindowPtr pWin = NULL;
78105b261ecSmrg  WindowPtr pWinSib = NULL;
78205b261ecSmrg  XID vlist[2];
78305b261ecSmrg  static Bool fRestacking = FALSE; /* Avoid recusive calls to this function */
78405b261ecSmrg  DWORD dwCurrentProcessID = GetCurrentProcessId ();
78505b261ecSmrg  DWORD dwWindowProcessID = 0;
78605b261ecSmrg
78705b261ecSmrg#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
78805b261ecSmrg  winTrace ("winReorderWindowsMultiWindow\n");
78905b261ecSmrg#endif
79005b261ecSmrg
79105b261ecSmrg  if (fRestacking)
79205b261ecSmrg    {
79305b261ecSmrg      /* It is a recusive call so immediately exit */
79405b261ecSmrg#if CYGWINDOWING_DEBUG
79505b261ecSmrg      ErrorF ("winReorderWindowsMultiWindow - "
79605b261ecSmrg	      "exit because fRestacking == TRUE\n");
79705b261ecSmrg#endif
79805b261ecSmrg      return;
79905b261ecSmrg    }
80005b261ecSmrg  fRestacking = TRUE;
80105b261ecSmrg
80205b261ecSmrg  /* Loop through top level Window windows, descending in Z order */
80305b261ecSmrg  for ( hwnd = GetTopWindow (NULL);
80405b261ecSmrg	hwnd;
80505b261ecSmrg	hwnd = GetNextWindow (hwnd, GW_HWNDNEXT) )
80605b261ecSmrg    {
80705b261ecSmrg      /* Don't take care of other Cygwin/X process's windows */
80805b261ecSmrg      GetWindowThreadProcessId (hwnd, &dwWindowProcessID);
80905b261ecSmrg
81005b261ecSmrg      if ( GetProp (hwnd, WIN_WINDOW_PROP)
81105b261ecSmrg	   && (dwWindowProcessID == dwCurrentProcessID)
81205b261ecSmrg	   && !IsIconic (hwnd) ) /* ignore minimized windows */
81305b261ecSmrg	{
81405b261ecSmrg	  pWinSib = pWin;
81505b261ecSmrg	  pWin = GetProp (hwnd, WIN_WINDOW_PROP);
81605b261ecSmrg
81705b261ecSmrg	  if (!pWinSib)
81805b261ecSmrg	    { /* 1st window - raise to the top */
81905b261ecSmrg	      vlist[0] = Above;
82005b261ecSmrg
82105b261ecSmrg	      ConfigureWindow (pWin, CWStackMode, vlist, wClient(pWin));
82205b261ecSmrg	    }
82305b261ecSmrg	  else
82405b261ecSmrg	    { /* 2nd or deeper windows - just below the previous one */
82505b261ecSmrg	      vlist[0] = winGetWindowID (pWinSib);
82605b261ecSmrg	      vlist[1] = Below;
82705b261ecSmrg
82805b261ecSmrg	      ConfigureWindow (pWin, CWSibling | CWStackMode,
82905b261ecSmrg			       vlist, wClient(pWin));
83005b261ecSmrg	    }
83105b261ecSmrg	}
83205b261ecSmrg    }
83305b261ecSmrg
83405b261ecSmrg  fRestacking = FALSE;
83505b261ecSmrg}
83605b261ecSmrg
83705b261ecSmrg
83805b261ecSmrg/*
83905b261ecSmrg * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE
84005b261ecSmrg */
84105b261ecSmrg
84205b261ecSmrgvoid
84305b261ecSmrgwinMinimizeWindow (Window id)
84405b261ecSmrg{
84505b261ecSmrg  WindowPtr		pWin;
84605b261ecSmrg  winPrivWinPtr	pWinPriv;
84705b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
84805b261ecSmrg  win32RootlessWindowPtr pRLWinPriv;
84905b261ecSmrg#endif
85005b261ecSmrg  HWND hWnd;
85105b261ecSmrg  ScreenPtr pScreen = NULL;
85205b261ecSmrg  winPrivScreenPtr pScreenPriv = NULL;
85305b261ecSmrg  winScreenInfo *pScreenInfo = NULL;
85405b261ecSmrg
85505b261ecSmrg#if CYGWINDOWING_DEBUG
85605b261ecSmrg  ErrorF ("winMinimizeWindow\n");
85705b261ecSmrg#endif
85805b261ecSmrg
85905b261ecSmrg  pWin = LookupIDByType (id, RT_WINDOW);
86005b261ecSmrg  if (!pWin)
86105b261ecSmrg  {
86205b261ecSmrg      ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__);
86305b261ecSmrg      return;
86405b261ecSmrg  }
86505b261ecSmrg
86605b261ecSmrg  pScreen = pWin->drawable.pScreen;
86705b261ecSmrg  if (pScreen) pScreenPriv = winGetScreenPriv(pScreen);
86805b261ecSmrg  if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
86905b261ecSmrg
87005b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
87105b261ecSmrg  if (pScreenPriv && pScreenInfo->fInternalWM)
87205b261ecSmrg    {
87305b261ecSmrg      pRLWinPriv  = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
87405b261ecSmrg      hWnd = pRLWinPriv->hWnd;
87505b261ecSmrg    }
87605b261ecSmrg  else
87705b261ecSmrg#else
87805b261ecSmrg  if (pScreenPriv)
87905b261ecSmrg#endif
88005b261ecSmrg    {
88105b261ecSmrg      pWinPriv = winGetWindowPriv (pWin);
88205b261ecSmrg      hWnd = pWinPriv->hWnd;
88305b261ecSmrg    }
88405b261ecSmrg
88505b261ecSmrg  ShowWindow (hWnd, SW_MINIMIZE);
88605b261ecSmrg}
88705b261ecSmrg
88805b261ecSmrg
88905b261ecSmrg/*
89005b261ecSmrg * CopyWindow - See Porting Layer Definition - p. 39
89105b261ecSmrg */
89205b261ecSmrgvoid
89305b261ecSmrgwinCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt,
89405b261ecSmrg			  RegionPtr oldRegion)
89505b261ecSmrg{
89605b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
89705b261ecSmrg  winWindowPriv(pWin);
89805b261ecSmrg  winScreenPriv(pScreen);
89905b261ecSmrg
90005b261ecSmrg#if CYGWINDOWING_DEBUG
90105b261ecSmrg  ErrorF ("CopyWindowMultiWindow\n");
90205b261ecSmrg#endif
90305b261ecSmrg  WIN_UNWRAP(CopyWindow);
90405b261ecSmrg  (*pScreen->CopyWindow)(pWin, oldpt, oldRegion);
90505b261ecSmrg  WIN_WRAP(CopyWindow, winCopyWindowMultiWindow);
90605b261ecSmrg}
90705b261ecSmrg
90805b261ecSmrg
90905b261ecSmrg/*
91005b261ecSmrg * MoveWindow - See Porting Layer Definition - p. 42
91105b261ecSmrg */
91205b261ecSmrgvoid
91305b261ecSmrgwinMoveWindowMultiWindow (WindowPtr pWin, int x, int y,
91405b261ecSmrg			  WindowPtr pSib, VTKind kind)
91505b261ecSmrg{
91605b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
91705b261ecSmrg  winWindowPriv(pWin);
91805b261ecSmrg  winScreenPriv(pScreen);
91905b261ecSmrg
92005b261ecSmrg#if CYGWINDOWING_DEBUG
92105b261ecSmrg  ErrorF ("MoveWindowMultiWindow to (%d, %d)\n", x, y);
92205b261ecSmrg#endif
92305b261ecSmrg
92405b261ecSmrg  WIN_UNWRAP(MoveWindow);
92505b261ecSmrg  (*pScreen->MoveWindow)(pWin, x, y, pSib, kind);
92605b261ecSmrg  WIN_WRAP(MoveWindow, winMoveWindowMultiWindow);
92705b261ecSmrg}
92805b261ecSmrg
92905b261ecSmrg
93005b261ecSmrg/*
93105b261ecSmrg * ResizeWindow - See Porting Layer Definition - p. 42
93205b261ecSmrg */
93305b261ecSmrgvoid
93405b261ecSmrgwinResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w,
93505b261ecSmrg			    unsigned int h, WindowPtr pSib)
93605b261ecSmrg{
93705b261ecSmrg  ScreenPtr		pScreen = pWin->drawable.pScreen;
93805b261ecSmrg  winWindowPriv(pWin);
93905b261ecSmrg  winScreenPriv(pScreen);
94005b261ecSmrg
94105b261ecSmrg#if CYGWINDOWING_DEBUG
94205b261ecSmrg  ErrorF ("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x, y, w, h);
94305b261ecSmrg#endif
94405b261ecSmrg  WIN_UNWRAP(ResizeWindow);
94505b261ecSmrg  (*pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
94605b261ecSmrg  WIN_WRAP(ResizeWindow, winResizeWindowMultiWindow);
94705b261ecSmrg}
94805b261ecSmrg
94905b261ecSmrg
95005b261ecSmrg/*
95105b261ecSmrg * winAdjustXWindow
95205b261ecSmrg *
95305b261ecSmrg * Move and resize X window with respect to corresponding Windows window.
95405b261ecSmrg * This is called from WM_MOVE/WM_SIZE handlers when the user performs
95505b261ecSmrg * any windowing operation (move, resize, minimize, maximize, restore).
95605b261ecSmrg *
95705b261ecSmrg * The functionality is the inverse of winPositionWindowMultiWindow, which
95805b261ecSmrg * adjusts Windows window with respect to X window.
95905b261ecSmrg */
96005b261ecSmrgint
96105b261ecSmrgwinAdjustXWindow (WindowPtr pWin, HWND hwnd)
96205b261ecSmrg{
96305b261ecSmrg  RECT rcDraw; /* Rect made from pWin->drawable to be adjusted */
96405b261ecSmrg  RECT rcWin;  /* The source: WindowRect from hwnd */
96505b261ecSmrg  DrawablePtr pDraw;
96605b261ecSmrg  XID vlist[4];
96705b261ecSmrg  LONG dX, dY, dW, dH, x, y;
96805b261ecSmrg  DWORD dwStyle, dwExStyle;
96905b261ecSmrg
97005b261ecSmrg#define WIDTH(rc) (rc.right - rc.left)
97105b261ecSmrg#define HEIGHT(rc) (rc.bottom - rc.top)
97205b261ecSmrg
97305b261ecSmrg#if CYGWINDOWING_DEBUG
97405b261ecSmrg  ErrorF ("winAdjustXWindow\n");
97505b261ecSmrg#endif
97605b261ecSmrg
97705b261ecSmrg  if (IsIconic (hwnd))
97805b261ecSmrg    {
97905b261ecSmrg#if CYGWINDOWING_DEBUG
98005b261ecSmrg      ErrorF ("\timmediately return because the window is iconized\n");
98105b261ecSmrg#endif
98205b261ecSmrg      /*
98305b261ecSmrg       * If the Windows window is minimized, its WindowRect has
98405b261ecSmrg       * meaningless values so we don't adjust X window to it.
98505b261ecSmrg       */
98605b261ecSmrg      vlist[0] = 0;
98705b261ecSmrg      vlist[1] = 0;
98805b261ecSmrg      return ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin));
98905b261ecSmrg    }
99005b261ecSmrg
99105b261ecSmrg  pDraw = &pWin->drawable;
99205b261ecSmrg
99305b261ecSmrg  /* Calculate the window rect from the drawable */
99405b261ecSmrg  x = pDraw->x + GetSystemMetrics (SM_XVIRTUALSCREEN);
99505b261ecSmrg  y = pDraw->y + GetSystemMetrics (SM_YVIRTUALSCREEN);
99605b261ecSmrg  SetRect (&rcDraw, x, y, x + pDraw->width, y + pDraw->height);
99705b261ecSmrg#ifdef CYGMULTIWINDOW_DEBUG
99805b261ecSmrg          winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n",
99905b261ecSmrg              rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom,
100005b261ecSmrg              rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top);
100105b261ecSmrg#endif
100205b261ecSmrg  dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE);
100305b261ecSmrg  dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE);
100405b261ecSmrg#ifdef CYGMULTIWINDOW_DEBUG
100505b261ecSmrg          winDebug("\tWindowStyle: %08x %08x\n", dwStyle, dwExStyle);
100605b261ecSmrg#endif
100705b261ecSmrg  AdjustWindowRectEx (&rcDraw, dwStyle, FALSE, dwExStyle);
100805b261ecSmrg
100905b261ecSmrg  /* The source of adjust */
101005b261ecSmrg  GetWindowRect (hwnd, &rcWin);
101105b261ecSmrg#ifdef CYGMULTIWINDOW_DEBUG
101205b261ecSmrg          winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
101305b261ecSmrg              rcWin.left, rcWin.top, rcWin.right, rcWin.bottom,
101405b261ecSmrg              rcWin.right - rcWin.left, rcWin.bottom - rcWin.top);
101505b261ecSmrg          winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n",
101605b261ecSmrg              rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom,
101705b261ecSmrg              rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top);
101805b261ecSmrg#endif
101905b261ecSmrg
102005b261ecSmrg  if (EqualRect (&rcDraw, &rcWin)) {
102105b261ecSmrg    /* Bail if no adjust is needed */
102205b261ecSmrg#if CYGWINDOWING_DEBUG
102305b261ecSmrg    ErrorF ("\treturn because already adjusted\n");
102405b261ecSmrg#endif
102505b261ecSmrg    return 0;
102605b261ecSmrg  }
102705b261ecSmrg
102805b261ecSmrg  /* Calculate delta values */
102905b261ecSmrg  dX = rcWin.left - rcDraw.left;
103005b261ecSmrg  dY = rcWin.top - rcDraw.top;
103105b261ecSmrg  dW = WIDTH(rcWin) - WIDTH(rcDraw);
103205b261ecSmrg  dH = HEIGHT(rcWin) - HEIGHT(rcDraw);
103305b261ecSmrg
103405b261ecSmrg  /*
103505b261ecSmrg   * Adjust.
103605b261ecSmrg   * We may only need to move (vlist[0] and [1]), or only resize
103705b261ecSmrg   * ([2] and [3]) but currently we set all the parameters and leave
103805b261ecSmrg   * the decision to ConfigureWindow.  The reason is code simplicity.
103905b261ecSmrg  */
104005b261ecSmrg  vlist[0] = pDraw->x + dX - wBorderWidth(pWin);
104105b261ecSmrg  vlist[1] = pDraw->y + dY - wBorderWidth(pWin);
104205b261ecSmrg  vlist[2] = pDraw->width + dW;
104305b261ecSmrg  vlist[3] = pDraw->height + dH;
104405b261ecSmrg#if CYGWINDOWING_DEBUG
104505b261ecSmrg  ErrorF ("\tConfigureWindow to (%ld, %ld) - %ldx%ld\n", vlist[0], vlist[1],
104605b261ecSmrg	  vlist[2], vlist[3]);
104705b261ecSmrg#endif
104805b261ecSmrg  return ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight,
104905b261ecSmrg			  vlist, wClient(pWin));
105005b261ecSmrg
105105b261ecSmrg#undef WIDTH
105205b261ecSmrg#undef HEIGHT
105305b261ecSmrg}
105405b261ecSmrg
1055