winmultiwindowwindow.c revision 35c4bbdf
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
4205b261ecSmrg/*
4305b261ecSmrg * Prototypes for local functions
4405b261ecSmrg */
4505b261ecSmrg
4605b261ecSmrgvoid
4735c4bbdfSmrg winCreateWindowsWindow(WindowPtr pWin);
4805b261ecSmrg
4905b261ecSmrgstatic void
5035c4bbdfSmrg winDestroyWindowsWindow(WindowPtr pWin);
5105b261ecSmrg
5205b261ecSmrgstatic void
5335c4bbdfSmrg winUpdateWindowsWindow(WindowPtr pWin);
5405b261ecSmrg
5505b261ecSmrgstatic void
5635c4bbdfSmrg winFindWindow(void *value, XID id, void *cdata);
5705b261ecSmrg
586747b715Smrgstatic
5935c4bbdfSmrg    void
6035c4bbdfSmrgwinInitMultiWindowClass(void)
616747b715Smrg{
6235c4bbdfSmrg    static wATOM atomXWinClass = 0;
6335c4bbdfSmrg    WNDCLASSEX wcx;
6435c4bbdfSmrg
6535c4bbdfSmrg    if (atomXWinClass == 0) {
6635c4bbdfSmrg        HICON hIcon, hIconSmall;
6735c4bbdfSmrg
6835c4bbdfSmrg        /* Load the default icons */
6935c4bbdfSmrg        winSelectIcons(&hIcon, &hIconSmall);
7035c4bbdfSmrg
7135c4bbdfSmrg        /* Setup our window class */
7235c4bbdfSmrg        wcx.cbSize = sizeof(WNDCLASSEX);
7335c4bbdfSmrg        wcx.style = CS_HREDRAW | CS_VREDRAW | (g_fNativeGl ? CS_OWNDC : 0);
7435c4bbdfSmrg        wcx.lpfnWndProc = winTopLevelWindowProc;
7535c4bbdfSmrg        wcx.cbClsExtra = 0;
7635c4bbdfSmrg        wcx.cbWndExtra = 0;
7735c4bbdfSmrg        wcx.hInstance = g_hInstance;
7835c4bbdfSmrg        wcx.hIcon = hIcon;
7935c4bbdfSmrg        wcx.hCursor = 0;
8035c4bbdfSmrg        wcx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
8135c4bbdfSmrg        wcx.lpszMenuName = NULL;
8235c4bbdfSmrg        wcx.lpszClassName = WINDOW_CLASS_X;
8335c4bbdfSmrg        wcx.hIconSm = hIconSmall;
8405b261ecSmrg
856747b715Smrg#if CYGMULTIWINDOW_DEBUG
8635c4bbdfSmrg        ErrorF("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X);
876747b715Smrg#endif
8805b261ecSmrg
8935c4bbdfSmrg        atomXWinClass = RegisterClassEx(&wcx);
9035c4bbdfSmrg    }
916747b715Smrg}
9205b261ecSmrg
9305b261ecSmrg/*
9405b261ecSmrg * CreateWindow - See Porting Layer Definition - p. 37
9505b261ecSmrg */
9605b261ecSmrg
9705b261ecSmrgBool
9835c4bbdfSmrgwinCreateWindowMultiWindow(WindowPtr pWin)
9905b261ecSmrg{
10035c4bbdfSmrg    Bool fResult = TRUE;
10135c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
10235c4bbdfSmrg
10335c4bbdfSmrg    winWindowPriv(pWin);
10435c4bbdfSmrg    winScreenPriv(pScreen);
10505b261ecSmrg
10605b261ecSmrg#if CYGMULTIWINDOW_DEBUG
10735c4bbdfSmrg    winTrace("winCreateWindowMultiWindow - pWin: %p\n", pWin);
10835c4bbdfSmrg#endif
10905b261ecSmrg
11035c4bbdfSmrg    WIN_UNWRAP(CreateWindow);
11135c4bbdfSmrg    fResult = (*pScreen->CreateWindow) (pWin);
11235c4bbdfSmrg    WIN_WRAP(CreateWindow, winCreateWindowMultiWindow);
11335c4bbdfSmrg
11435c4bbdfSmrg    /* Initialize some privates values */
11535c4bbdfSmrg    pWinPriv->hRgn = NULL;
11635c4bbdfSmrg    pWinPriv->hWnd = NULL;
11735c4bbdfSmrg    pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen);
11835c4bbdfSmrg    pWinPriv->fXKilled = FALSE;
11935c4bbdfSmrg#ifdef XWIN_GLX_WINDOWS
12035c4bbdfSmrg    pWinPriv->fWglUsed = FALSE;
12135c4bbdfSmrg#endif
12235c4bbdfSmrg
12335c4bbdfSmrg    return fResult;
12435c4bbdfSmrg}
12505b261ecSmrg
12605b261ecSmrg/*
12705b261ecSmrg * DestroyWindow - See Porting Layer Definition - p. 37
12805b261ecSmrg */
12905b261ecSmrg
13005b261ecSmrgBool
13135c4bbdfSmrgwinDestroyWindowMultiWindow(WindowPtr pWin)
13205b261ecSmrg{
13335c4bbdfSmrg    Bool fResult = TRUE;
13435c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
13535c4bbdfSmrg
13635c4bbdfSmrg    winWindowPriv(pWin);
13735c4bbdfSmrg    winScreenPriv(pScreen);
13805b261ecSmrg
13905b261ecSmrg#if CYGMULTIWINDOW_DEBUG
14035c4bbdfSmrg    ErrorF("winDestroyWindowMultiWindow - pWin: %p\n", pWin);
14135c4bbdfSmrg#endif
14235c4bbdfSmrg
14335c4bbdfSmrg    WIN_UNWRAP(DestroyWindow);
14435c4bbdfSmrg    fResult = (*pScreen->DestroyWindow) (pWin);
14535c4bbdfSmrg    WIN_WRAP(DestroyWindow, winDestroyWindowMultiWindow);
14605b261ecSmrg
14735c4bbdfSmrg    /* Flag that the window has been destroyed */
14835c4bbdfSmrg    pWinPriv->fXKilled = TRUE;
14935c4bbdfSmrg
15035c4bbdfSmrg    /* Kill the MS Windows window associated with this window */
15135c4bbdfSmrg    winDestroyWindowsWindow(pWin);
15235c4bbdfSmrg
15335c4bbdfSmrg    return fResult;
15435c4bbdfSmrg}
15505b261ecSmrg
15605b261ecSmrg/*
15705b261ecSmrg * PositionWindow - See Porting Layer Definition - p. 37
15805b261ecSmrg *
15905b261ecSmrg * This function adjusts the position and size of Windows window
16005b261ecSmrg * with respect to the underlying X window.  This is the inverse
16105b261ecSmrg * of winAdjustXWindow, which adjusts X window to Windows window.
16205b261ecSmrg */
16305b261ecSmrg
16405b261ecSmrgBool
16535c4bbdfSmrgwinPositionWindowMultiWindow(WindowPtr pWin, int x, int y)
16605b261ecSmrg{
16735c4bbdfSmrg    Bool fResult = TRUE;
16835c4bbdfSmrg    int iX, iY, iWidth, iHeight;
16935c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
17035c4bbdfSmrg
17135c4bbdfSmrg    winWindowPriv(pWin);
17235c4bbdfSmrg    winScreenPriv(pScreen);
17335c4bbdfSmrg
17435c4bbdfSmrg    HWND hWnd = pWinPriv->hWnd;
17535c4bbdfSmrg    RECT rcNew;
17635c4bbdfSmrg    RECT rcOld;
17735c4bbdfSmrg
17805b261ecSmrg#if CYGMULTIWINDOW_DEBUG
17935c4bbdfSmrg    RECT rcClient;
18035c4bbdfSmrg    RECT *lpRc;
18105b261ecSmrg#endif
18235c4bbdfSmrg    DWORD dwExStyle;
18335c4bbdfSmrg    DWORD dwStyle;
18405b261ecSmrg
18505b261ecSmrg#if CYGMULTIWINDOW_DEBUG
18635c4bbdfSmrg    winTrace("winPositionWindowMultiWindow - pWin: %p\n", pWin);
18705b261ecSmrg#endif
18835c4bbdfSmrg
18935c4bbdfSmrg    WIN_UNWRAP(PositionWindow);
19035c4bbdfSmrg    fResult = (*pScreen->PositionWindow) (pWin, x, y);
19135c4bbdfSmrg    WIN_WRAP(PositionWindow, winPositionWindowMultiWindow);
19235c4bbdfSmrg
19305b261ecSmrg#if CYGWINDOWING_DEBUG
19435c4bbdfSmrg    ErrorF("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n", x, y);
19505b261ecSmrg#endif
19605b261ecSmrg
19735c4bbdfSmrg    /* Bail out if the Windows window handle is bad */
19835c4bbdfSmrg    if (!hWnd) {
19905b261ecSmrg#if CYGWINDOWING_DEBUG
20035c4bbdfSmrg        ErrorF("\timmediately return since hWnd is NULL\n");
20105b261ecSmrg#endif
20235c4bbdfSmrg        return fResult;
20305b261ecSmrg    }
20405b261ecSmrg
20535c4bbdfSmrg    /* Get the Windows window style and extended style */
20635c4bbdfSmrg    dwExStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);
20735c4bbdfSmrg    dwStyle = GetWindowLongPtr(hWnd, GWL_STYLE);
20805b261ecSmrg
20935c4bbdfSmrg    /* Get the X and Y location of the X window */
21035c4bbdfSmrg    iX = pWin->drawable.x + GetSystemMetrics(SM_XVIRTUALSCREEN);
21135c4bbdfSmrg    iY = pWin->drawable.y + GetSystemMetrics(SM_YVIRTUALSCREEN);
21205b261ecSmrg
21335c4bbdfSmrg    /* Get the height and width of the X window */
21435c4bbdfSmrg    iWidth = pWin->drawable.width;
21535c4bbdfSmrg    iHeight = pWin->drawable.height;
21605b261ecSmrg
21735c4bbdfSmrg    /* Store the origin, height, and width in a rectangle structure */
21835c4bbdfSmrg    SetRect(&rcNew, iX, iY, iX + iWidth, iY + iHeight);
21905b261ecSmrg
22005b261ecSmrg#if CYGMULTIWINDOW_DEBUG
22135c4bbdfSmrg    lpRc = &rcNew;
22235c4bbdfSmrg    ErrorF("winPositionWindowMultiWindow - drawable (%d, %d)-(%d, %d)\n",
22335c4bbdfSmrg           (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
22405b261ecSmrg#endif
22505b261ecSmrg
22635c4bbdfSmrg    /*
22735c4bbdfSmrg     * Calculate the required size of the Windows window rectangle,
22835c4bbdfSmrg     * given the size of the Windows window client area.
22935c4bbdfSmrg     */
23035c4bbdfSmrg    AdjustWindowRectEx(&rcNew, dwStyle, FALSE, dwExStyle);
23105b261ecSmrg
23235c4bbdfSmrg    /* Get a rectangle describing the old Windows window */
23335c4bbdfSmrg    GetWindowRect(hWnd, &rcOld);
23405b261ecSmrg
23505b261ecSmrg#if CYGMULTIWINDOW_DEBUG
23635c4bbdfSmrg    /* Get a rectangle describing the Windows window client area */
23735c4bbdfSmrg    GetClientRect(hWnd, &rcClient);
23835c4bbdfSmrg
23935c4bbdfSmrg    lpRc = &rcNew;
24035c4bbdfSmrg    ErrorF("winPositionWindowMultiWindow - rcNew (%d, %d)-(%d, %d)\n",
24135c4bbdfSmrg           (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
24235c4bbdfSmrg
24335c4bbdfSmrg    lpRc = &rcOld;
24435c4bbdfSmrg    ErrorF("winPositionWindowMultiWindow - rcOld (%d, %d)-(%d, %d)\n",
24535c4bbdfSmrg           (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
24635c4bbdfSmrg
24735c4bbdfSmrg    lpRc = &rcClient;
24835c4bbdfSmrg    ErrorF("rcClient (%d, %d)-(%d, %d)\n",
24935c4bbdfSmrg           (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
25035c4bbdfSmrg#endif
25135c4bbdfSmrg
25235c4bbdfSmrg    /* Check if the old rectangle and new rectangle are the same */
25335c4bbdfSmrg    if (!EqualRect(&rcNew, &rcOld)) {
25405b261ecSmrg#if CYGMULTIWINDOW_DEBUG
25535c4bbdfSmrg        ErrorF("winPositionWindowMultiWindow - Need to move\n");
25605b261ecSmrg#endif
25705b261ecSmrg
25805b261ecSmrg#if CYGWINDOWING_DEBUG
25935c4bbdfSmrg        ErrorF("\tMoveWindow to (%d, %d) - %dx%d\n", (int)rcNew.left, (int)rcNew.top,
26035c4bbdfSmrg               (int)(rcNew.right - rcNew.left), (int)(rcNew.bottom - rcNew.top));
26135c4bbdfSmrg#endif
26235c4bbdfSmrg        /* Change the position and dimensions of the Windows window */
26335c4bbdfSmrg        MoveWindow(hWnd,
26435c4bbdfSmrg                   rcNew.left, rcNew.top,
26535c4bbdfSmrg                   rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, TRUE);
26605b261ecSmrg    }
26735c4bbdfSmrg    else {
26805b261ecSmrg#if CYGMULTIWINDOW_DEBUG
26935c4bbdfSmrg        ErrorF("winPositionWindowMultiWindow - Not need to move\n");
27005b261ecSmrg#endif
27105b261ecSmrg    }
27205b261ecSmrg
27335c4bbdfSmrg    return fResult;
27405b261ecSmrg}
27505b261ecSmrg
27605b261ecSmrg/*
27705b261ecSmrg * ChangeWindowAttributes - See Porting Layer Definition - p. 37
27805b261ecSmrg */
27905b261ecSmrg
28005b261ecSmrgBool
28135c4bbdfSmrgwinChangeWindowAttributesMultiWindow(WindowPtr pWin, unsigned long mask)
28205b261ecSmrg{
28335c4bbdfSmrg    Bool fResult = TRUE;
28435c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
28535c4bbdfSmrg
28635c4bbdfSmrg    winScreenPriv(pScreen);
28705b261ecSmrg
28805b261ecSmrg#if CYGMULTIWINDOW_DEBUG
28935c4bbdfSmrg    ErrorF("winChangeWindowAttributesMultiWindow - pWin: %p\n", pWin);
29035c4bbdfSmrg#endif
29135c4bbdfSmrg
29235c4bbdfSmrg    WIN_UNWRAP(ChangeWindowAttributes);
29335c4bbdfSmrg    fResult = (*pScreen->ChangeWindowAttributes) (pWin, mask);
29435c4bbdfSmrg    WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesMultiWindow);
29505b261ecSmrg
29635c4bbdfSmrg    /*
29735c4bbdfSmrg     * NOTE: We do not currently need to do anything here.
29835c4bbdfSmrg     */
29935c4bbdfSmrg
30035c4bbdfSmrg    return fResult;
30135c4bbdfSmrg}
30205b261ecSmrg
30305b261ecSmrg/*
30405b261ecSmrg * UnmapWindow - See Porting Layer Definition - p. 37
30505b261ecSmrg * Also referred to as UnrealizeWindow
30605b261ecSmrg */
30705b261ecSmrg
30805b261ecSmrgBool
30935c4bbdfSmrgwinUnmapWindowMultiWindow(WindowPtr pWin)
31005b261ecSmrg{
31135c4bbdfSmrg    Bool fResult = TRUE;
31235c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
31335c4bbdfSmrg
31435c4bbdfSmrg    winWindowPriv(pWin);
31535c4bbdfSmrg    winScreenPriv(pScreen);
31605b261ecSmrg
31705b261ecSmrg#if CYGMULTIWINDOW_DEBUG
31835c4bbdfSmrg    ErrorF("winUnmapWindowMultiWindow - pWin: %p\n", pWin);
31935c4bbdfSmrg#endif
32035c4bbdfSmrg
32135c4bbdfSmrg    WIN_UNWRAP(UnrealizeWindow);
32235c4bbdfSmrg    fResult = (*pScreen->UnrealizeWindow) (pWin);
32335c4bbdfSmrg    WIN_WRAP(UnrealizeWindow, winUnmapWindowMultiWindow);
32405b261ecSmrg
32535c4bbdfSmrg    /* Flag that the window has been killed */
32635c4bbdfSmrg    pWinPriv->fXKilled = TRUE;
32735c4bbdfSmrg
32835c4bbdfSmrg    /* Destroy the Windows window associated with this X window */
32935c4bbdfSmrg    winDestroyWindowsWindow(pWin);
33035c4bbdfSmrg
33135c4bbdfSmrg    return fResult;
33235c4bbdfSmrg}
33305b261ecSmrg
33405b261ecSmrg/*
33505b261ecSmrg * MapWindow - See Porting Layer Definition - p. 37
33605b261ecSmrg * Also referred to as RealizeWindow
33705b261ecSmrg */
33805b261ecSmrg
33905b261ecSmrgBool
34035c4bbdfSmrgwinMapWindowMultiWindow(WindowPtr pWin)
34105b261ecSmrg{
34235c4bbdfSmrg    Bool fResult = TRUE;
34335c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
34435c4bbdfSmrg
34535c4bbdfSmrg    winWindowPriv(pWin);
34635c4bbdfSmrg    winScreenPriv(pScreen);
34705b261ecSmrg
34805b261ecSmrg#if CYGMULTIWINDOW_DEBUG
34935c4bbdfSmrg    ErrorF("winMapWindowMultiWindow - pWin: %p\n", pWin);
35005b261ecSmrg#endif
35105b261ecSmrg
35235c4bbdfSmrg    WIN_UNWRAP(RealizeWindow);
35335c4bbdfSmrg    fResult = (*pScreen->RealizeWindow) (pWin);
35435c4bbdfSmrg    WIN_WRAP(RealizeWindow, winMapWindowMultiWindow);
35505b261ecSmrg
35635c4bbdfSmrg    /* Flag that this window has not been destroyed */
35735c4bbdfSmrg    pWinPriv->fXKilled = FALSE;
35805b261ecSmrg
35935c4bbdfSmrg    /* Refresh/redisplay the Windows window associated with this X window */
36035c4bbdfSmrg    winUpdateWindowsWindow(pWin);
36105b261ecSmrg
36235c4bbdfSmrg    /* Update the Windows window's shape */
36335c4bbdfSmrg    winReshapeMultiWindow(pWin);
36435c4bbdfSmrg    winUpdateRgnMultiWindow(pWin);
36535c4bbdfSmrg
36635c4bbdfSmrg    return fResult;
36735c4bbdfSmrg}
36805b261ecSmrg
36905b261ecSmrg/*
37005b261ecSmrg * ReparentWindow - See Porting Layer Definition - p. 42
37105b261ecSmrg */
37205b261ecSmrg
37305b261ecSmrgvoid
37435c4bbdfSmrgwinReparentWindowMultiWindow(WindowPtr pWin, WindowPtr pPriorParent)
37505b261ecSmrg{
37635c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
37705b261ecSmrg
37835c4bbdfSmrg    winScreenPriv(pScreen);
37905b261ecSmrg
38035c4bbdfSmrg    winDebug
38135c4bbdfSmrg        ("winReparentMultiWindow - pWin:%p XID:0x%x, reparent from pWin:%p XID:0x%x to pWin:%p XID:0x%x\n",
38235c4bbdfSmrg         pWin, (unsigned int)pWin->drawable.id,
38335c4bbdfSmrg         pPriorParent, (unsigned int)pPriorParent->drawable.id,
38435c4bbdfSmrg         pWin->parent, (unsigned int)pWin->parent->drawable.id);
38535c4bbdfSmrg
38635c4bbdfSmrg    WIN_UNWRAP(ReparentWindow);
38735c4bbdfSmrg    if (pScreen->ReparentWindow)
38835c4bbdfSmrg        (*pScreen->ReparentWindow) (pWin, pPriorParent);
38935c4bbdfSmrg    WIN_WRAP(ReparentWindow, winReparentWindowMultiWindow);
39005b261ecSmrg
39135c4bbdfSmrg    /* Update the Windows window associated with this X window */
39235c4bbdfSmrg    winUpdateWindowsWindow(pWin);
39335c4bbdfSmrg}
39405b261ecSmrg
39505b261ecSmrg/*
39605b261ecSmrg * RestackWindow - Shuffle the z-order of a window
39705b261ecSmrg */
39805b261ecSmrg
39905b261ecSmrgvoid
40035c4bbdfSmrgwinRestackWindowMultiWindow(WindowPtr pWin, WindowPtr pOldNextSib)
40105b261ecSmrg{
4026747b715Smrg#if 0
40335c4bbdfSmrg    WindowPtr pPrevWin;
40435c4bbdfSmrg    UINT uFlags;
40535c4bbdfSmrg    HWND hInsertAfter;
40635c4bbdfSmrg    HWND hWnd = NULL;
4076747b715Smrg#endif
40835c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
40935c4bbdfSmrg
41035c4bbdfSmrg    winScreenPriv(pScreen);
41105b261ecSmrg
41205b261ecSmrg#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
41335c4bbdfSmrg    winTrace("winRestackMultiWindow - %p\n", pWin);
41435c4bbdfSmrg#endif
41535c4bbdfSmrg
41635c4bbdfSmrg    WIN_UNWRAP(RestackWindow);
41735c4bbdfSmrg    if (pScreen->RestackWindow)
41835c4bbdfSmrg        (*pScreen->RestackWindow) (pWin, pOldNextSib);
41935c4bbdfSmrg    WIN_WRAP(RestackWindow, winRestackWindowMultiWindow);
42035c4bbdfSmrg
42105b261ecSmrg#if 1
42235c4bbdfSmrg    /*
42335c4bbdfSmrg     * Calling winReorderWindowsMultiWindow here means our window manager
42435c4bbdfSmrg     * (i.e. Windows Explorer) has initiative to determine Z order.
42535c4bbdfSmrg     */
42635c4bbdfSmrg    if (pWin->nextSib != pOldNextSib)
42735c4bbdfSmrg        winReorderWindowsMultiWindow();
42805b261ecSmrg#else
42935c4bbdfSmrg    /* Bail out if no window privates or window handle is invalid */
43035c4bbdfSmrg    if (!pWinPriv || !pWinPriv->hWnd)
43135c4bbdfSmrg        return;
43235c4bbdfSmrg
43335c4bbdfSmrg    /* Get a pointer to our previous sibling window */
43435c4bbdfSmrg    pPrevWin = pWin->prevSib;
43535c4bbdfSmrg
43635c4bbdfSmrg    /*
43735c4bbdfSmrg     * Look for a sibling window with
43835c4bbdfSmrg     * valid privates and window handle
43935c4bbdfSmrg     */
44035c4bbdfSmrg    while (pPrevWin && !winGetWindowPriv(pPrevWin)
44135c4bbdfSmrg           && !winGetWindowPriv(pPrevWin)->hWnd)
44235c4bbdfSmrg        pPrevWin = pPrevWin->prevSib;
44335c4bbdfSmrg
44435c4bbdfSmrg    /* Check if we found a valid sibling */
44535c4bbdfSmrg    if (pPrevWin) {
44635c4bbdfSmrg        /* Valid sibling - get handle to insert window after */
44735c4bbdfSmrg        hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd;
44835c4bbdfSmrg        uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
44935c4bbdfSmrg
45035c4bbdfSmrg        hWnd = GetNextWindow(pWinPriv->hWnd, GW_HWNDPREV);
45135c4bbdfSmrg
45235c4bbdfSmrg        do {
45335c4bbdfSmrg            if (GetProp(hWnd, WIN_WINDOW_PROP)) {
45435c4bbdfSmrg                if (hWnd == winGetWindowPriv(pPrevWin)->hWnd) {
45535c4bbdfSmrg                    uFlags |= SWP_NOZORDER;
45635c4bbdfSmrg                }
45735c4bbdfSmrg                break;
45835c4bbdfSmrg            }
45935c4bbdfSmrg            hWnd = GetNextWindow(hWnd, GW_HWNDPREV);
46035c4bbdfSmrg        }
46135c4bbdfSmrg        while (hWnd);
46205b261ecSmrg    }
46335c4bbdfSmrg    else {
46435c4bbdfSmrg        /* No valid sibling - make this window the top window */
46535c4bbdfSmrg        hInsertAfter = HWND_TOP;
46635c4bbdfSmrg        uFlags = SWP_NOMOVE | SWP_NOSIZE;
46705b261ecSmrg    }
46835c4bbdfSmrg
46935c4bbdfSmrg    /* Perform the restacking operation in Windows */
47035c4bbdfSmrg    SetWindowPos(pWinPriv->hWnd, hInsertAfter, 0, 0, 0, 0, uFlags);
47105b261ecSmrg#endif
47205b261ecSmrg}
47305b261ecSmrg
47405b261ecSmrg/*
47505b261ecSmrg * winCreateWindowsWindow - Create a Windows window associated with an X window
47605b261ecSmrg */
47705b261ecSmrg
47805b261ecSmrgvoid
47935c4bbdfSmrgwinCreateWindowsWindow(WindowPtr pWin)
48005b261ecSmrg{
48135c4bbdfSmrg    int iX, iY;
48235c4bbdfSmrg    int iWidth;
48335c4bbdfSmrg    int iHeight;
48435c4bbdfSmrg    HWND hWnd;
48535c4bbdfSmrg    HWND hFore = NULL;
48635c4bbdfSmrg
48735c4bbdfSmrg    winWindowPriv(pWin);
48835c4bbdfSmrg    winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv;
48935c4bbdfSmrg    WinXSizeHints hints;
49035c4bbdfSmrg    Window daddyId;
49135c4bbdfSmrg    DWORD dwStyle, dwExStyle;
49235c4bbdfSmrg    RECT rc;
49335c4bbdfSmrg
49435c4bbdfSmrg    winInitMultiWindowClass();
49535c4bbdfSmrg
49635c4bbdfSmrg    winDebug("winCreateWindowsTopLevelWindow - pWin:%p XID:0x%x \n", pWin,
49735c4bbdfSmrg             (unsigned int)pWin->drawable.id);
49835c4bbdfSmrg
49935c4bbdfSmrg    iX = pWin->drawable.x + GetSystemMetrics(SM_XVIRTUALSCREEN);
50035c4bbdfSmrg    iY = pWin->drawable.y + GetSystemMetrics(SM_YVIRTUALSCREEN);
50135c4bbdfSmrg
50235c4bbdfSmrg    iWidth = pWin->drawable.width;
50335c4bbdfSmrg    iHeight = pWin->drawable.height;
50435c4bbdfSmrg
50535c4bbdfSmrg    /* If it's an InputOutput window, and so is going to end up being made visible,
50635c4bbdfSmrg       make sure the window actually ends up somewhere where it will be visible
50735c4bbdfSmrg
50835c4bbdfSmrg       To handle arrangements of monitors which form a non-rectangular virtual
50935c4bbdfSmrg       desktop, check if the window will end up with it's top-left corner on any
51035c4bbdfSmrg       monitor
51135c4bbdfSmrg    */
51235c4bbdfSmrg    if (pWin->drawable.class != InputOnly) {
51335c4bbdfSmrg        POINT pt = { iX, iY };
51435c4bbdfSmrg        if (MonitorFromPoint(pt, MONITOR_DEFAULTTONULL) == NULL)
51535c4bbdfSmrg            {
51635c4bbdfSmrg                iX = CW_USEDEFAULT;
51735c4bbdfSmrg                iY = CW_USEDEFAULT;
51835c4bbdfSmrg            }
51935c4bbdfSmrg    }
52005b261ecSmrg
52135c4bbdfSmrg    winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX,
52235c4bbdfSmrg             iY);
52335c4bbdfSmrg
52435c4bbdfSmrg    if (winMultiWindowGetTransientFor(pWin, &daddyId)) {
52535c4bbdfSmrg        if (daddyId) {
52635c4bbdfSmrg            WindowPtr pParent;
52735c4bbdfSmrg            int res = dixLookupWindow(&pParent, daddyId, serverClient, DixReadAccess);
52835c4bbdfSmrg            if (res == Success)
52935c4bbdfSmrg                {
53035c4bbdfSmrg                    winPrivWinPtr pParentPriv = winGetWindowPriv(pParent);
53135c4bbdfSmrg                    hFore = pParentPriv->hWnd;
53235c4bbdfSmrg                }
53335c4bbdfSmrg        }
53435c4bbdfSmrg    }
53535c4bbdfSmrg    else {
53635c4bbdfSmrg        /* Default positions if none specified */
53735c4bbdfSmrg        if (!winMultiWindowGetWMNormalHints(pWin, &hints))
53835c4bbdfSmrg            hints.flags = 0;
53935c4bbdfSmrg        if (!(hints.flags & (USPosition | PPosition)) &&
54035c4bbdfSmrg            !pWin->overrideRedirect) {
54135c4bbdfSmrg            iX = CW_USEDEFAULT;
54235c4bbdfSmrg            iY = CW_USEDEFAULT;
54335c4bbdfSmrg        }
54435c4bbdfSmrg    }
54505b261ecSmrg
54635c4bbdfSmrg    /* Make it WS_OVERLAPPED in create call since WS_POPUP doesn't support */
54735c4bbdfSmrg    /* CW_USEDEFAULT, change back to popup after creation */
54835c4bbdfSmrg    dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
54935c4bbdfSmrg    dwExStyle = WS_EX_TOOLWINDOW;
55035c4bbdfSmrg
55135c4bbdfSmrg    /*
55235c4bbdfSmrg       Calculate the window coordinates containing the requested client area,
55335c4bbdfSmrg       being careful to preseve CW_USEDEFAULT
55435c4bbdfSmrg     */
55535c4bbdfSmrg    rc.top = (iY != CW_USEDEFAULT) ? iY : 0;
55635c4bbdfSmrg    rc.left = (iX != CW_USEDEFAULT) ? iX : 0;
55735c4bbdfSmrg    rc.bottom = rc.top + iHeight;
55835c4bbdfSmrg    rc.right = rc.left + iWidth;
55935c4bbdfSmrg    AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle);
56035c4bbdfSmrg    if (iY != CW_USEDEFAULT)
56135c4bbdfSmrg        iY = rc.top;
56235c4bbdfSmrg    if (iX != CW_USEDEFAULT)
56335c4bbdfSmrg        iX = rc.left;
56435c4bbdfSmrg    iHeight = rc.bottom - rc.top;
56535c4bbdfSmrg    iWidth = rc.right - rc.left;
56635c4bbdfSmrg
56735c4bbdfSmrg    winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX,
56835c4bbdfSmrg             iY);
56935c4bbdfSmrg
57035c4bbdfSmrg    /* Create the window */
57135c4bbdfSmrg    hWnd = CreateWindowExA(dwExStyle,   /* Extended styles */
57235c4bbdfSmrg                           WINDOW_CLASS_X,      /* Class name */
57335c4bbdfSmrg                           WINDOW_TITLE_X,      /* Window name */
57435c4bbdfSmrg                           dwStyle,     /* Styles */
57535c4bbdfSmrg                           iX,  /* Horizontal position */
57635c4bbdfSmrg                           iY,  /* Vertical position */
57735c4bbdfSmrg                           iWidth,      /* Right edge */
57835c4bbdfSmrg                           iHeight,     /* Bottom edge */
57935c4bbdfSmrg                           hFore,       /* Null or Parent window if transient */
58035c4bbdfSmrg                           (HMENU) NULL,        /* No menu */
58135c4bbdfSmrg                           GetModuleHandle(NULL),       /* Instance handle */
58235c4bbdfSmrg                           pWin);       /* ScreenPrivates */
58335c4bbdfSmrg    if (hWnd == NULL) {
58435c4bbdfSmrg        ErrorF("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
58535c4bbdfSmrg               (int) GetLastError());
58635c4bbdfSmrg    }
58735c4bbdfSmrg    pWinPriv->hWnd = hWnd;
58805b261ecSmrg
58935c4bbdfSmrg    /* Change style back to popup, already placed... */
59035c4bbdfSmrg    SetWindowLongPtr(hWnd, GWL_STYLE,
59135c4bbdfSmrg                     WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
59235c4bbdfSmrg    SetWindowPos(hWnd, 0, 0, 0, 0, 0,
59335c4bbdfSmrg                 SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE |
59435c4bbdfSmrg                 SWP_NOACTIVATE);
59505b261ecSmrg
59635c4bbdfSmrg    /* Adjust the X window to match the window placement we actually got... */
59735c4bbdfSmrg    winAdjustXWindow(pWin, hWnd);
59805b261ecSmrg
59935c4bbdfSmrg    /* Make sure it gets the proper system menu for a WS_POPUP, too */
60035c4bbdfSmrg    GetSystemMenu(hWnd, TRUE);
60105b261ecSmrg
60235c4bbdfSmrg    /* Cause any .XWinrc menus to be added in main WNDPROC */
60335c4bbdfSmrg    PostMessage(hWnd, WM_INIT_SYS_MENU, 0, 0);
60405b261ecSmrg
60535c4bbdfSmrg    SetProp(hWnd, WIN_WID_PROP, (HANDLE) (INT_PTR) winGetWindowID(pWin));
60635c4bbdfSmrg
60735c4bbdfSmrg    /* Flag that this Windows window handles its own activation */
60835c4bbdfSmrg    SetProp(hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0);
60905b261ecSmrg
61035c4bbdfSmrg    /* Call engine-specific create window procedure */
61135c4bbdfSmrg    (*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin);
61235c4bbdfSmrg}
61305b261ecSmrg
61405b261ecSmrgBool winInDestroyWindowsWindow = FALSE;
61535c4bbdfSmrg
61605b261ecSmrg/*
61705b261ecSmrg * winDestroyWindowsWindow - Destroy a Windows window associated
61805b261ecSmrg * with an X window
61905b261ecSmrg */
62005b261ecSmrgstatic void
62135c4bbdfSmrgwinDestroyWindowsWindow(WindowPtr pWin)
62205b261ecSmrg{
62335c4bbdfSmrg    MSG msg;
62405b261ecSmrg
62535c4bbdfSmrg    winWindowPriv(pWin);
62635c4bbdfSmrg    BOOL oldstate = winInDestroyWindowsWindow;
62735c4bbdfSmrg    HICON hIcon;
62835c4bbdfSmrg    HICON hIconSm;
62905b261ecSmrg
63035c4bbdfSmrg    winDebug("winDestroyWindowsWindow - pWin:%p XID:0x%x \n", pWin,
63135c4bbdfSmrg             (unsigned int)pWin->drawable.id);
63205b261ecSmrg
63335c4bbdfSmrg    /* Bail out if the Windows window handle is invalid */
63435c4bbdfSmrg    if (pWinPriv->hWnd == NULL)
63535c4bbdfSmrg        return;
63605b261ecSmrg
63735c4bbdfSmrg    winInDestroyWindowsWindow = TRUE;
63805b261ecSmrg
63935c4bbdfSmrg    /* Store the info we need to destroy after this window is gone */
64035c4bbdfSmrg    hIcon = (HICON) SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_BIG, 0);
64135c4bbdfSmrg    hIconSm = (HICON) SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_SMALL, 0);
64205b261ecSmrg
64335c4bbdfSmrg    /* Destroy the Windows window */
64435c4bbdfSmrg    DestroyWindow(pWinPriv->hWnd);
64505b261ecSmrg
64635c4bbdfSmrg    /* Null our handle to the Window so referencing it will cause an error */
64735c4bbdfSmrg    pWinPriv->hWnd = NULL;
64835c4bbdfSmrg
64935c4bbdfSmrg    /* Destroy any icons we created for this window */
65035c4bbdfSmrg    winDestroyIcon(hIcon);
65135c4bbdfSmrg    winDestroyIcon(hIconSm);
65235c4bbdfSmrg
65335c4bbdfSmrg#ifdef XWIN_GLX_WINDOWS
65435c4bbdfSmrg    /* No longer note WGL used on this window */
65535c4bbdfSmrg    pWinPriv->fWglUsed = FALSE;
65605b261ecSmrg#endif
65705b261ecSmrg
65835c4bbdfSmrg    /* Process all messages on our queue */
65935c4bbdfSmrg    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
66035c4bbdfSmrg        if (g_hDlgDepthChange == 0 || !IsDialogMessage(g_hDlgDepthChange, &msg)) {
66135c4bbdfSmrg            DispatchMessage(&msg);
66235c4bbdfSmrg        }
66335c4bbdfSmrg    }
66435c4bbdfSmrg
66535c4bbdfSmrg    winInDestroyWindowsWindow = oldstate;
66635c4bbdfSmrg
66735c4bbdfSmrg    winDebug("winDestroyWindowsWindow - done\n");
66835c4bbdfSmrg}
66905b261ecSmrg
67005b261ecSmrg/*
67105b261ecSmrg * winUpdateWindowsWindow - Redisplay/redraw a Windows window
67205b261ecSmrg * associated with an X window
67305b261ecSmrg */
67405b261ecSmrg
67505b261ecSmrgstatic void
67635c4bbdfSmrgwinUpdateWindowsWindow(WindowPtr pWin)
67705b261ecSmrg{
67835c4bbdfSmrg    winWindowPriv(pWin);
67935c4bbdfSmrg    HWND hWnd = pWinPriv->hWnd;
68005b261ecSmrg
68105b261ecSmrg#if CYGMULTIWINDOW_DEBUG
68235c4bbdfSmrg    ErrorF("winUpdateWindowsWindow\n");
68305b261ecSmrg#endif
68405b261ecSmrg
68535c4bbdfSmrg    /* Check if the Windows window's parents have been destroyed */
68635c4bbdfSmrg    if (pWin->parent != NULL && pWin->parent->parent == NULL && pWin->mapped) {
68735c4bbdfSmrg        /* Create the Windows window if it has been destroyed */
68835c4bbdfSmrg        if (hWnd == NULL) {
68935c4bbdfSmrg            winCreateWindowsWindow(pWin);
69035c4bbdfSmrg            assert(pWinPriv->hWnd != NULL);
69135c4bbdfSmrg        }
69235c4bbdfSmrg
69335c4bbdfSmrg        /* Display the window without activating it */
69435c4bbdfSmrg        if (pWin->drawable.class != InputOnly)
69535c4bbdfSmrg            ShowWindow(pWinPriv->hWnd, SW_SHOWNOACTIVATE);
69635c4bbdfSmrg
69735c4bbdfSmrg        /* Send first paint message */
69835c4bbdfSmrg        UpdateWindow(pWinPriv->hWnd);
69905b261ecSmrg    }
70035c4bbdfSmrg    else if (hWnd != NULL) {
70135c4bbdfSmrg        /* Destroy the Windows window if its parents are destroyed */
70235c4bbdfSmrg        winDestroyWindowsWindow(pWin);
70335c4bbdfSmrg        assert(pWinPriv->hWnd == NULL);
70405b261ecSmrg    }
70505b261ecSmrg
70605b261ecSmrg#if CYGMULTIWINDOW_DEBUG
70735c4bbdfSmrg    ErrorF("-winUpdateWindowsWindow\n");
70805b261ecSmrg#endif
70905b261ecSmrg}
71005b261ecSmrg
71105b261ecSmrg/*
71235c4bbdfSmrg * winGetWindowID -
71305b261ecSmrg */
71405b261ecSmrg
71505b261ecSmrgXID
71635c4bbdfSmrgwinGetWindowID(WindowPtr pWin)
71705b261ecSmrg{
71835c4bbdfSmrg    WindowIDPairRec wi = { pWin, 0 };
71935c4bbdfSmrg    ClientPtr c = wClient(pWin);
72035c4bbdfSmrg
72135c4bbdfSmrg    /* */
72235c4bbdfSmrg    FindClientResourcesByType(c, RT_WINDOW, winFindWindow, &wi);
72305b261ecSmrg
72405b261ecSmrg#if CYGMULTIWINDOW_DEBUG
72535c4bbdfSmrg    ErrorF("winGetWindowID - Window ID: %u\n", (unsigned int)wi.id);
72605b261ecSmrg#endif
72705b261ecSmrg
72835c4bbdfSmrg    return wi.id;
72905b261ecSmrg}
73005b261ecSmrg
73105b261ecSmrg/*
73235c4bbdfSmrg * winFindWindow -
73305b261ecSmrg */
73405b261ecSmrg
73505b261ecSmrgstatic void
73635c4bbdfSmrgwinFindWindow(void *value, XID id, void *cdata)
73705b261ecSmrg{
73835c4bbdfSmrg    WindowIDPairPtr wi = (WindowIDPairPtr) cdata;
73905b261ecSmrg
74035c4bbdfSmrg    if (value == wi->value) {
74135c4bbdfSmrg        wi->id = id;
74205b261ecSmrg    }
74305b261ecSmrg}
74405b261ecSmrg
74505b261ecSmrg/*
74635c4bbdfSmrg * winReorderWindowsMultiWindow -
74705b261ecSmrg */
74805b261ecSmrg
74905b261ecSmrgvoid
75035c4bbdfSmrgwinReorderWindowsMultiWindow(void)
75105b261ecSmrg{
75235c4bbdfSmrg    HWND hwnd = NULL;
75335c4bbdfSmrg    WindowPtr pWin = NULL;
75435c4bbdfSmrg    WindowPtr pWinSib = NULL;
75535c4bbdfSmrg    XID vlist[2];
75635c4bbdfSmrg    static Bool fRestacking = FALSE;    /* Avoid recusive calls to this function */
75735c4bbdfSmrg    DWORD dwCurrentProcessID = GetCurrentProcessId();
75835c4bbdfSmrg    DWORD dwWindowProcessID = 0;
75905b261ecSmrg
76005b261ecSmrg#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
76135c4bbdfSmrg    winTrace("winReorderWindowsMultiWindow\n");
76205b261ecSmrg#endif
76305b261ecSmrg
76435c4bbdfSmrg    if (fRestacking) {
76535c4bbdfSmrg        /* It is a recusive call so immediately exit */
76605b261ecSmrg#if CYGWINDOWING_DEBUG
76735c4bbdfSmrg        ErrorF("winReorderWindowsMultiWindow - "
76835c4bbdfSmrg               "exit because fRestacking == TRUE\n");
76905b261ecSmrg#endif
77035c4bbdfSmrg        return;
77105b261ecSmrg    }
77235c4bbdfSmrg    fRestacking = TRUE;
77335c4bbdfSmrg
77435c4bbdfSmrg    /* Loop through top level Window windows, descending in Z order */
77535c4bbdfSmrg    for (hwnd = GetTopWindow(NULL);
77635c4bbdfSmrg         hwnd; hwnd = GetNextWindow(hwnd, GW_HWNDNEXT)) {
77735c4bbdfSmrg        /* Don't take care of other Cygwin/X process's windows */
77835c4bbdfSmrg        GetWindowThreadProcessId(hwnd, &dwWindowProcessID);
77935c4bbdfSmrg
78035c4bbdfSmrg        if (GetProp(hwnd, WIN_WINDOW_PROP)
78135c4bbdfSmrg            && (dwWindowProcessID == dwCurrentProcessID)
78235c4bbdfSmrg            && !IsIconic(hwnd)) {       /* ignore minimized windows */
78335c4bbdfSmrg            pWinSib = pWin;
78435c4bbdfSmrg            pWin = GetProp(hwnd, WIN_WINDOW_PROP);
78535c4bbdfSmrg
78635c4bbdfSmrg            if (!pWinSib) {     /* 1st window - raise to the top */
78735c4bbdfSmrg                vlist[0] = Above;
78835c4bbdfSmrg
78935c4bbdfSmrg                ConfigureWindow(pWin, CWStackMode, vlist, wClient(pWin));
79035c4bbdfSmrg            }
79135c4bbdfSmrg            else {              /* 2nd or deeper windows - just below the previous one */
79235c4bbdfSmrg                vlist[0] = winGetWindowID(pWinSib);
79335c4bbdfSmrg                vlist[1] = Below;
79435c4bbdfSmrg
79535c4bbdfSmrg                ConfigureWindow(pWin, CWSibling | CWStackMode,
79635c4bbdfSmrg                                vlist, wClient(pWin));
79735c4bbdfSmrg            }
79835c4bbdfSmrg        }
79905b261ecSmrg    }
80005b261ecSmrg
80135c4bbdfSmrg    fRestacking = FALSE;
80205b261ecSmrg}
80305b261ecSmrg
80405b261ecSmrg/*
80505b261ecSmrg * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE
80605b261ecSmrg */
80705b261ecSmrg
80805b261ecSmrgvoid
80935c4bbdfSmrgwinMinimizeWindow(Window id)
81005b261ecSmrg{
81135c4bbdfSmrg    WindowPtr pWin;
81235c4bbdfSmrg    winPrivWinPtr pWinPriv;
81335c4bbdfSmrg
81405b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
81535c4bbdfSmrg    win32RootlessWindowPtr pRLWinPriv;
81605b261ecSmrg#endif
81735c4bbdfSmrg    HWND hWnd;
81835c4bbdfSmrg    ScreenPtr pScreen = NULL;
81935c4bbdfSmrg    winPrivScreenPtr pScreenPriv = NULL;
82005b261ecSmrg
82105b261ecSmrg#if CYGWINDOWING_DEBUG
82235c4bbdfSmrg    ErrorF("winMinimizeWindow\n");
82305b261ecSmrg#endif
82405b261ecSmrg
82535c4bbdfSmrg    dixLookupResourceByType((void *) &pWin, id, RT_WINDOW, NullClient,
82635c4bbdfSmrg                            DixUnknownAccess);
82735c4bbdfSmrg    if (!pWin) {
82835c4bbdfSmrg        ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__);
82935c4bbdfSmrg        return;
83035c4bbdfSmrg    }
83105b261ecSmrg
83235c4bbdfSmrg    pScreen = pWin->drawable.pScreen;
83335c4bbdfSmrg    if (pScreen)
83435c4bbdfSmrg        pScreenPriv = winGetScreenPriv(pScreen);
83505b261ecSmrg
83605b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
83735c4bbdfSmrg    if (pScreenPriv && pScreenPriv->pScreenInfo->fInternalWM) {
83835c4bbdfSmrg        pRLWinPriv =
83935c4bbdfSmrg            (win32RootlessWindowPtr) RootlessFrameForWindow(pWin, FALSE);
84035c4bbdfSmrg        hWnd = pRLWinPriv->hWnd;
84105b261ecSmrg    }
84235c4bbdfSmrg    else
84305b261ecSmrg#else
84435c4bbdfSmrg    if (pScreenPriv)
84505b261ecSmrg#endif
84605b261ecSmrg    {
84735c4bbdfSmrg        pWinPriv = winGetWindowPriv(pWin);
84835c4bbdfSmrg        hWnd = pWinPriv->hWnd;
84905b261ecSmrg    }
85005b261ecSmrg
85135c4bbdfSmrg    ShowWindow(hWnd, SW_MINIMIZE);
85205b261ecSmrg}
85305b261ecSmrg
85405b261ecSmrg/*
85505b261ecSmrg * CopyWindow - See Porting Layer Definition - p. 39
85605b261ecSmrg */
85705b261ecSmrgvoid
85835c4bbdfSmrgwinCopyWindowMultiWindow(WindowPtr pWin, DDXPointRec oldpt, RegionPtr oldRegion)
85905b261ecSmrg{
86035c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
86135c4bbdfSmrg
86235c4bbdfSmrg    winScreenPriv(pScreen);
86305b261ecSmrg
86405b261ecSmrg#if CYGWINDOWING_DEBUG
86535c4bbdfSmrg    ErrorF("CopyWindowMultiWindow\n");
86605b261ecSmrg#endif
86735c4bbdfSmrg    WIN_UNWRAP(CopyWindow);
86835c4bbdfSmrg    (*pScreen->CopyWindow) (pWin, oldpt, oldRegion);
86935c4bbdfSmrg    WIN_WRAP(CopyWindow, winCopyWindowMultiWindow);
87005b261ecSmrg}
87105b261ecSmrg
87205b261ecSmrg/*
87305b261ecSmrg * MoveWindow - See Porting Layer Definition - p. 42
87405b261ecSmrg */
87505b261ecSmrgvoid
87635c4bbdfSmrgwinMoveWindowMultiWindow(WindowPtr pWin, int x, int y,
87735c4bbdfSmrg                         WindowPtr pSib, VTKind kind)
87805b261ecSmrg{
87935c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
88035c4bbdfSmrg
88135c4bbdfSmrg    winScreenPriv(pScreen);
88205b261ecSmrg
88305b261ecSmrg#if CYGWINDOWING_DEBUG
88435c4bbdfSmrg    ErrorF("MoveWindowMultiWindow to (%d, %d)\n", x, y);
88505b261ecSmrg#endif
88605b261ecSmrg
88735c4bbdfSmrg    WIN_UNWRAP(MoveWindow);
88835c4bbdfSmrg    (*pScreen->MoveWindow) (pWin, x, y, pSib, kind);
88935c4bbdfSmrg    WIN_WRAP(MoveWindow, winMoveWindowMultiWindow);
89005b261ecSmrg}
89105b261ecSmrg
89205b261ecSmrg/*
89305b261ecSmrg * ResizeWindow - See Porting Layer Definition - p. 42
89405b261ecSmrg */
89505b261ecSmrgvoid
89635c4bbdfSmrgwinResizeWindowMultiWindow(WindowPtr pWin, int x, int y, unsigned int w,
89735c4bbdfSmrg                           unsigned int h, WindowPtr pSib)
89805b261ecSmrg{
89935c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
90035c4bbdfSmrg
90135c4bbdfSmrg    winScreenPriv(pScreen);
90205b261ecSmrg
90305b261ecSmrg#if CYGWINDOWING_DEBUG
90435c4bbdfSmrg    ErrorF("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x, y, w, h);
90505b261ecSmrg#endif
90635c4bbdfSmrg    WIN_UNWRAP(ResizeWindow);
90735c4bbdfSmrg    (*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
90835c4bbdfSmrg    WIN_WRAP(ResizeWindow, winResizeWindowMultiWindow);
90905b261ecSmrg}
91005b261ecSmrg
91105b261ecSmrg/*
91205b261ecSmrg * winAdjustXWindow
91305b261ecSmrg *
91405b261ecSmrg * Move and resize X window with respect to corresponding Windows window.
91505b261ecSmrg * This is called from WM_MOVE/WM_SIZE handlers when the user performs
91605b261ecSmrg * any windowing operation (move, resize, minimize, maximize, restore).
91705b261ecSmrg *
91805b261ecSmrg * The functionality is the inverse of winPositionWindowMultiWindow, which
91905b261ecSmrg * adjusts Windows window with respect to X window.
92005b261ecSmrg */
92105b261ecSmrgint
92235c4bbdfSmrgwinAdjustXWindow(WindowPtr pWin, HWND hwnd)
92305b261ecSmrg{
92435c4bbdfSmrg    RECT rcDraw;                /* Rect made from pWin->drawable to be adjusted */
92535c4bbdfSmrg    RECT rcWin;                 /* The source: WindowRect from hwnd */
92635c4bbdfSmrg    DrawablePtr pDraw;
92735c4bbdfSmrg    XID vlist[4];
92835c4bbdfSmrg    LONG dX, dY, dW, dH, x, y;
92935c4bbdfSmrg    DWORD dwStyle, dwExStyle;
93005b261ecSmrg
93105b261ecSmrg#define WIDTH(rc) (rc.right - rc.left)
93205b261ecSmrg#define HEIGHT(rc) (rc.bottom - rc.top)
93335c4bbdfSmrg
93405b261ecSmrg#if CYGWINDOWING_DEBUG
93535c4bbdfSmrg    ErrorF("winAdjustXWindow\n");
93605b261ecSmrg#endif
93705b261ecSmrg
93835c4bbdfSmrg    if (IsIconic(hwnd)) {
93905b261ecSmrg#if CYGWINDOWING_DEBUG
94035c4bbdfSmrg        ErrorF("\timmediately return because the window is iconized\n");
94135c4bbdfSmrg#endif
94235c4bbdfSmrg        /*
94335c4bbdfSmrg         * If the Windows window is minimized, its WindowRect has
94435c4bbdfSmrg         * meaningless values so we don't adjust X window to it.
94535c4bbdfSmrg         */
94635c4bbdfSmrg        vlist[0] = 0;
94735c4bbdfSmrg        vlist[1] = 0;
94835c4bbdfSmrg        return ConfigureWindow(pWin, CWX | CWY, vlist, wClient(pWin));
94905b261ecSmrg    }
95005b261ecSmrg
95135c4bbdfSmrg    pDraw = &pWin->drawable;
95235c4bbdfSmrg
95335c4bbdfSmrg    /* Calculate the window rect from the drawable */
95435c4bbdfSmrg    x = pDraw->x + GetSystemMetrics(SM_XVIRTUALSCREEN);
95535c4bbdfSmrg    y = pDraw->y + GetSystemMetrics(SM_YVIRTUALSCREEN);
95635c4bbdfSmrg    SetRect(&rcDraw, x, y, x + pDraw->width, y + pDraw->height);
95705b261ecSmrg#ifdef CYGMULTIWINDOW_DEBUG
95835c4bbdfSmrg    winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n",
95935c4bbdfSmrg             (int)rcDraw.left, (int)rcDraw.top, (int)rcDraw.right, (int)rcDraw.bottom,
96035c4bbdfSmrg             (int)(rcDraw.right - rcDraw.left), (int)(rcDraw.bottom - rcDraw.top));
96105b261ecSmrg#endif
96235c4bbdfSmrg    dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
96335c4bbdfSmrg    dwStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
96405b261ecSmrg#ifdef CYGMULTIWINDOW_DEBUG
96535c4bbdfSmrg    winDebug("\tWindowStyle: %08x %08x\n", (unsigned int)dwStyle, (unsigned int)dwExStyle);
96605b261ecSmrg#endif
96735c4bbdfSmrg    AdjustWindowRectEx(&rcDraw, dwStyle, FALSE, dwExStyle);
96805b261ecSmrg
96935c4bbdfSmrg    /* The source of adjust */
97035c4bbdfSmrg    GetWindowRect(hwnd, &rcWin);
97105b261ecSmrg#ifdef CYGMULTIWINDOW_DEBUG
97235c4bbdfSmrg    winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
97335c4bbdfSmrg             (int)rcWin.left, (int)rcWin.top, (int)rcWin.right, (int)rcWin.bottom,
97435c4bbdfSmrg             (int)(rcWin.right - rcWin.left), (int)(rcWin.bottom - rcWin.top));
97535c4bbdfSmrg    winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n",
97635c4bbdfSmrg             (int)rcDraw.left, (int)rcDraw.top, (int)rcDraw.right, (int)rcDraw.bottom,
97735c4bbdfSmrg             (int)(rcDraw.right - rcDraw.left), (int)(rcDraw.bottom - rcDraw.top));
97805b261ecSmrg#endif
97905b261ecSmrg
98035c4bbdfSmrg    if (EqualRect(&rcDraw, &rcWin)) {
98135c4bbdfSmrg        /* Bail if no adjust is needed */
98205b261ecSmrg#if CYGWINDOWING_DEBUG
98335c4bbdfSmrg        ErrorF("\treturn because already adjusted\n");
98435c4bbdfSmrg#endif
98535c4bbdfSmrg        return 0;
98635c4bbdfSmrg    }
98735c4bbdfSmrg
98835c4bbdfSmrg    /* Calculate delta values */
98935c4bbdfSmrg    dX = rcWin.left - rcDraw.left;
99035c4bbdfSmrg    dY = rcWin.top - rcDraw.top;
99135c4bbdfSmrg    dW = WIDTH(rcWin) - WIDTH(rcDraw);
99235c4bbdfSmrg    dH = HEIGHT(rcWin) - HEIGHT(rcDraw);
99335c4bbdfSmrg
99435c4bbdfSmrg    /*
99535c4bbdfSmrg     * Adjust.
99635c4bbdfSmrg     * We may only need to move (vlist[0] and [1]), or only resize
99735c4bbdfSmrg     * ([2] and [3]) but currently we set all the parameters and leave
99835c4bbdfSmrg     * the decision to ConfigureWindow.  The reason is code simplicity.
99935c4bbdfSmrg     */
100035c4bbdfSmrg    vlist[0] = pDraw->x + dX - wBorderWidth(pWin);
100135c4bbdfSmrg    vlist[1] = pDraw->y + dY - wBorderWidth(pWin);
100235c4bbdfSmrg    vlist[2] = pDraw->width + dW;
100335c4bbdfSmrg    vlist[3] = pDraw->height + dH;
100405b261ecSmrg#if CYGWINDOWING_DEBUG
100535c4bbdfSmrg    ErrorF("\tConfigureWindow to (%u, %u) - %ux%u\n",
100635c4bbdfSmrg           (unsigned int)vlist[0], (unsigned int)vlist[1],
100735c4bbdfSmrg           (unsigned int)vlist[2], (unsigned int)vlist[3]);
100805b261ecSmrg#endif
100935c4bbdfSmrg    return ConfigureWindow(pWin, CWX | CWY | CWWidth | CWHeight,
101035c4bbdfSmrg                           vlist, wClient(pWin));
101135c4bbdfSmrg
101205b261ecSmrg#undef WIDTH
101305b261ecSmrg#undef HEIGHT
101405b261ecSmrg}
1015