winmultiwindowwindow.c revision 1b5d61b8
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
381b5d61b8Smrg
3905b261ecSmrg#include "win.h"
4005b261ecSmrg#include "dixevents.h"
4105b261ecSmrg#include "winmultiwindowclass.h"
421b5d61b8Smrg#include "winmultiwindowicons.h"
4305b261ecSmrg
4405b261ecSmrg/*
4505b261ecSmrg * Prototypes for local functions
4605b261ecSmrg */
4705b261ecSmrg
4805b261ecSmrgvoid
4935c4bbdfSmrg winCreateWindowsWindow(WindowPtr pWin);
5005b261ecSmrg
5105b261ecSmrgstatic void
5235c4bbdfSmrg winDestroyWindowsWindow(WindowPtr pWin);
5305b261ecSmrg
5405b261ecSmrgstatic void
5535c4bbdfSmrg winUpdateWindowsWindow(WindowPtr pWin);
5605b261ecSmrg
5705b261ecSmrgstatic void
5835c4bbdfSmrg winFindWindow(void *value, XID id, void *cdata);
5905b261ecSmrg
606747b715Smrgstatic
6135c4bbdfSmrg    void
6235c4bbdfSmrgwinInitMultiWindowClass(void)
636747b715Smrg{
6435c4bbdfSmrg    static wATOM atomXWinClass = 0;
6535c4bbdfSmrg    WNDCLASSEX wcx;
6635c4bbdfSmrg
6735c4bbdfSmrg    if (atomXWinClass == 0) {
6835c4bbdfSmrg        HICON hIcon, hIconSmall;
6935c4bbdfSmrg
7035c4bbdfSmrg        /* Load the default icons */
7135c4bbdfSmrg        winSelectIcons(&hIcon, &hIconSmall);
7235c4bbdfSmrg
7335c4bbdfSmrg        /* Setup our window class */
7435c4bbdfSmrg        wcx.cbSize = sizeof(WNDCLASSEX);
7535c4bbdfSmrg        wcx.style = CS_HREDRAW | CS_VREDRAW | (g_fNativeGl ? CS_OWNDC : 0);
7635c4bbdfSmrg        wcx.lpfnWndProc = winTopLevelWindowProc;
7735c4bbdfSmrg        wcx.cbClsExtra = 0;
7835c4bbdfSmrg        wcx.cbWndExtra = 0;
7935c4bbdfSmrg        wcx.hInstance = g_hInstance;
8035c4bbdfSmrg        wcx.hIcon = hIcon;
8135c4bbdfSmrg        wcx.hCursor = 0;
8235c4bbdfSmrg        wcx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
8335c4bbdfSmrg        wcx.lpszMenuName = NULL;
8435c4bbdfSmrg        wcx.lpszClassName = WINDOW_CLASS_X;
8535c4bbdfSmrg        wcx.hIconSm = hIconSmall;
8605b261ecSmrg
876747b715Smrg#if CYGMULTIWINDOW_DEBUG
8835c4bbdfSmrg        ErrorF("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X);
896747b715Smrg#endif
9005b261ecSmrg
9135c4bbdfSmrg        atomXWinClass = RegisterClassEx(&wcx);
9235c4bbdfSmrg    }
936747b715Smrg}
9405b261ecSmrg
9505b261ecSmrg/*
9605b261ecSmrg * CreateWindow - See Porting Layer Definition - p. 37
9705b261ecSmrg */
9805b261ecSmrg
9905b261ecSmrgBool
10035c4bbdfSmrgwinCreateWindowMultiWindow(WindowPtr pWin)
10105b261ecSmrg{
10235c4bbdfSmrg    Bool fResult = TRUE;
10335c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
10435c4bbdfSmrg
10535c4bbdfSmrg    winWindowPriv(pWin);
10635c4bbdfSmrg    winScreenPriv(pScreen);
10705b261ecSmrg
10805b261ecSmrg#if CYGMULTIWINDOW_DEBUG
10935c4bbdfSmrg    winTrace("winCreateWindowMultiWindow - pWin: %p\n", pWin);
11035c4bbdfSmrg#endif
11105b261ecSmrg
11235c4bbdfSmrg    WIN_UNWRAP(CreateWindow);
11335c4bbdfSmrg    fResult = (*pScreen->CreateWindow) (pWin);
11435c4bbdfSmrg    WIN_WRAP(CreateWindow, winCreateWindowMultiWindow);
11535c4bbdfSmrg
11635c4bbdfSmrg    /* Initialize some privates values */
11735c4bbdfSmrg    pWinPriv->hRgn = NULL;
11835c4bbdfSmrg    pWinPriv->hWnd = NULL;
11935c4bbdfSmrg    pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen);
12035c4bbdfSmrg    pWinPriv->fXKilled = FALSE;
12135c4bbdfSmrg#ifdef XWIN_GLX_WINDOWS
12235c4bbdfSmrg    pWinPriv->fWglUsed = FALSE;
12335c4bbdfSmrg#endif
12435c4bbdfSmrg
12535c4bbdfSmrg    return fResult;
12635c4bbdfSmrg}
12705b261ecSmrg
12805b261ecSmrg/*
12905b261ecSmrg * DestroyWindow - See Porting Layer Definition - p. 37
13005b261ecSmrg */
13105b261ecSmrg
13205b261ecSmrgBool
13335c4bbdfSmrgwinDestroyWindowMultiWindow(WindowPtr pWin)
13405b261ecSmrg{
13535c4bbdfSmrg    Bool fResult = TRUE;
13635c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
13735c4bbdfSmrg
13835c4bbdfSmrg    winWindowPriv(pWin);
13935c4bbdfSmrg    winScreenPriv(pScreen);
14005b261ecSmrg
14105b261ecSmrg#if CYGMULTIWINDOW_DEBUG
14235c4bbdfSmrg    ErrorF("winDestroyWindowMultiWindow - pWin: %p\n", pWin);
14335c4bbdfSmrg#endif
14435c4bbdfSmrg
14535c4bbdfSmrg    WIN_UNWRAP(DestroyWindow);
14635c4bbdfSmrg    fResult = (*pScreen->DestroyWindow) (pWin);
14735c4bbdfSmrg    WIN_WRAP(DestroyWindow, winDestroyWindowMultiWindow);
14805b261ecSmrg
14935c4bbdfSmrg    /* Flag that the window has been destroyed */
15035c4bbdfSmrg    pWinPriv->fXKilled = TRUE;
15135c4bbdfSmrg
15235c4bbdfSmrg    /* Kill the MS Windows window associated with this window */
15335c4bbdfSmrg    winDestroyWindowsWindow(pWin);
15435c4bbdfSmrg
15535c4bbdfSmrg    return fResult;
15635c4bbdfSmrg}
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
16735c4bbdfSmrgwinPositionWindowMultiWindow(WindowPtr pWin, int x, int y)
16805b261ecSmrg{
16935c4bbdfSmrg    Bool fResult = TRUE;
17035c4bbdfSmrg    int iX, iY, iWidth, iHeight;
17135c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
17235c4bbdfSmrg
17335c4bbdfSmrg    winWindowPriv(pWin);
17435c4bbdfSmrg    winScreenPriv(pScreen);
17535c4bbdfSmrg
17635c4bbdfSmrg    HWND hWnd = pWinPriv->hWnd;
17735c4bbdfSmrg    RECT rcNew;
17835c4bbdfSmrg    RECT rcOld;
17935c4bbdfSmrg
18005b261ecSmrg#if CYGMULTIWINDOW_DEBUG
18135c4bbdfSmrg    RECT rcClient;
18235c4bbdfSmrg    RECT *lpRc;
18305b261ecSmrg#endif
18435c4bbdfSmrg    DWORD dwExStyle;
18535c4bbdfSmrg    DWORD dwStyle;
18605b261ecSmrg
18705b261ecSmrg#if CYGMULTIWINDOW_DEBUG
18835c4bbdfSmrg    winTrace("winPositionWindowMultiWindow - pWin: %p\n", pWin);
18905b261ecSmrg#endif
19035c4bbdfSmrg
19135c4bbdfSmrg    WIN_UNWRAP(PositionWindow);
19235c4bbdfSmrg    fResult = (*pScreen->PositionWindow) (pWin, x, y);
19335c4bbdfSmrg    WIN_WRAP(PositionWindow, winPositionWindowMultiWindow);
19435c4bbdfSmrg
19505b261ecSmrg#if CYGWINDOWING_DEBUG
19635c4bbdfSmrg    ErrorF("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n", x, y);
19705b261ecSmrg#endif
19805b261ecSmrg
19935c4bbdfSmrg    /* Bail out if the Windows window handle is bad */
20035c4bbdfSmrg    if (!hWnd) {
20105b261ecSmrg#if CYGWINDOWING_DEBUG
20235c4bbdfSmrg        ErrorF("\timmediately return since hWnd is NULL\n");
20305b261ecSmrg#endif
20435c4bbdfSmrg        return fResult;
20505b261ecSmrg    }
20605b261ecSmrg
20735c4bbdfSmrg    /* Get the Windows window style and extended style */
20835c4bbdfSmrg    dwExStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);
20935c4bbdfSmrg    dwStyle = GetWindowLongPtr(hWnd, GWL_STYLE);
21005b261ecSmrg
21135c4bbdfSmrg    /* Get the X and Y location of the X window */
21235c4bbdfSmrg    iX = pWin->drawable.x + GetSystemMetrics(SM_XVIRTUALSCREEN);
21335c4bbdfSmrg    iY = pWin->drawable.y + GetSystemMetrics(SM_YVIRTUALSCREEN);
21405b261ecSmrg
21535c4bbdfSmrg    /* Get the height and width of the X window */
21635c4bbdfSmrg    iWidth = pWin->drawable.width;
21735c4bbdfSmrg    iHeight = pWin->drawable.height;
21805b261ecSmrg
21935c4bbdfSmrg    /* Store the origin, height, and width in a rectangle structure */
22035c4bbdfSmrg    SetRect(&rcNew, iX, iY, iX + iWidth, iY + iHeight);
22105b261ecSmrg
22205b261ecSmrg#if CYGMULTIWINDOW_DEBUG
22335c4bbdfSmrg    lpRc = &rcNew;
22435c4bbdfSmrg    ErrorF("winPositionWindowMultiWindow - drawable (%d, %d)-(%d, %d)\n",
22535c4bbdfSmrg           (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
22605b261ecSmrg#endif
22705b261ecSmrg
22835c4bbdfSmrg    /*
22935c4bbdfSmrg     * Calculate the required size of the Windows window rectangle,
23035c4bbdfSmrg     * given the size of the Windows window client area.
23135c4bbdfSmrg     */
23235c4bbdfSmrg    AdjustWindowRectEx(&rcNew, dwStyle, FALSE, dwExStyle);
23305b261ecSmrg
23435c4bbdfSmrg    /* Get a rectangle describing the old Windows window */
23535c4bbdfSmrg    GetWindowRect(hWnd, &rcOld);
23605b261ecSmrg
23705b261ecSmrg#if CYGMULTIWINDOW_DEBUG
23835c4bbdfSmrg    /* Get a rectangle describing the Windows window client area */
23935c4bbdfSmrg    GetClientRect(hWnd, &rcClient);
24035c4bbdfSmrg
24135c4bbdfSmrg    lpRc = &rcNew;
24235c4bbdfSmrg    ErrorF("winPositionWindowMultiWindow - rcNew (%d, %d)-(%d, %d)\n",
24335c4bbdfSmrg           (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
24435c4bbdfSmrg
24535c4bbdfSmrg    lpRc = &rcOld;
24635c4bbdfSmrg    ErrorF("winPositionWindowMultiWindow - rcOld (%d, %d)-(%d, %d)\n",
24735c4bbdfSmrg           (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
24835c4bbdfSmrg
24935c4bbdfSmrg    lpRc = &rcClient;
25035c4bbdfSmrg    ErrorF("rcClient (%d, %d)-(%d, %d)\n",
25135c4bbdfSmrg           (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
25235c4bbdfSmrg#endif
25335c4bbdfSmrg
25435c4bbdfSmrg    /* Check if the old rectangle and new rectangle are the same */
25535c4bbdfSmrg    if (!EqualRect(&rcNew, &rcOld)) {
25605b261ecSmrg#if CYGMULTIWINDOW_DEBUG
25735c4bbdfSmrg        ErrorF("winPositionWindowMultiWindow - Need to move\n");
25805b261ecSmrg#endif
25905b261ecSmrg
26005b261ecSmrg#if CYGWINDOWING_DEBUG
26135c4bbdfSmrg        ErrorF("\tMoveWindow to (%d, %d) - %dx%d\n", (int)rcNew.left, (int)rcNew.top,
26235c4bbdfSmrg               (int)(rcNew.right - rcNew.left), (int)(rcNew.bottom - rcNew.top));
26335c4bbdfSmrg#endif
26435c4bbdfSmrg        /* Change the position and dimensions of the Windows window */
26535c4bbdfSmrg        MoveWindow(hWnd,
26635c4bbdfSmrg                   rcNew.left, rcNew.top,
26735c4bbdfSmrg                   rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, TRUE);
26805b261ecSmrg    }
26935c4bbdfSmrg    else {
27005b261ecSmrg#if CYGMULTIWINDOW_DEBUG
27135c4bbdfSmrg        ErrorF("winPositionWindowMultiWindow - Not need to move\n");
27205b261ecSmrg#endif
27305b261ecSmrg    }
27405b261ecSmrg
27535c4bbdfSmrg    return fResult;
27605b261ecSmrg}
27705b261ecSmrg
27805b261ecSmrg/*
27905b261ecSmrg * ChangeWindowAttributes - See Porting Layer Definition - p. 37
28005b261ecSmrg */
28105b261ecSmrg
28205b261ecSmrgBool
28335c4bbdfSmrgwinChangeWindowAttributesMultiWindow(WindowPtr pWin, unsigned long mask)
28405b261ecSmrg{
28535c4bbdfSmrg    Bool fResult = TRUE;
28635c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
28735c4bbdfSmrg
28835c4bbdfSmrg    winScreenPriv(pScreen);
28905b261ecSmrg
29005b261ecSmrg#if CYGMULTIWINDOW_DEBUG
29135c4bbdfSmrg    ErrorF("winChangeWindowAttributesMultiWindow - pWin: %p\n", pWin);
29235c4bbdfSmrg#endif
29335c4bbdfSmrg
29435c4bbdfSmrg    WIN_UNWRAP(ChangeWindowAttributes);
29535c4bbdfSmrg    fResult = (*pScreen->ChangeWindowAttributes) (pWin, mask);
29635c4bbdfSmrg    WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesMultiWindow);
29705b261ecSmrg
29835c4bbdfSmrg    /*
29935c4bbdfSmrg     * NOTE: We do not currently need to do anything here.
30035c4bbdfSmrg     */
30135c4bbdfSmrg
30235c4bbdfSmrg    return fResult;
30335c4bbdfSmrg}
30405b261ecSmrg
30505b261ecSmrg/*
30605b261ecSmrg * UnmapWindow - See Porting Layer Definition - p. 37
30705b261ecSmrg * Also referred to as UnrealizeWindow
30805b261ecSmrg */
30905b261ecSmrg
31005b261ecSmrgBool
31135c4bbdfSmrgwinUnmapWindowMultiWindow(WindowPtr pWin)
31205b261ecSmrg{
31335c4bbdfSmrg    Bool fResult = TRUE;
31435c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
31535c4bbdfSmrg
31635c4bbdfSmrg    winWindowPriv(pWin);
31735c4bbdfSmrg    winScreenPriv(pScreen);
31805b261ecSmrg
31905b261ecSmrg#if CYGMULTIWINDOW_DEBUG
32035c4bbdfSmrg    ErrorF("winUnmapWindowMultiWindow - pWin: %p\n", pWin);
32135c4bbdfSmrg#endif
32235c4bbdfSmrg
32335c4bbdfSmrg    WIN_UNWRAP(UnrealizeWindow);
32435c4bbdfSmrg    fResult = (*pScreen->UnrealizeWindow) (pWin);
32535c4bbdfSmrg    WIN_WRAP(UnrealizeWindow, winUnmapWindowMultiWindow);
32605b261ecSmrg
32735c4bbdfSmrg    /* Flag that the window has been killed */
32835c4bbdfSmrg    pWinPriv->fXKilled = TRUE;
32935c4bbdfSmrg
33035c4bbdfSmrg    /* Destroy the Windows window associated with this X window */
33135c4bbdfSmrg    winDestroyWindowsWindow(pWin);
33235c4bbdfSmrg
33335c4bbdfSmrg    return fResult;
33435c4bbdfSmrg}
33505b261ecSmrg
33605b261ecSmrg/*
33705b261ecSmrg * MapWindow - See Porting Layer Definition - p. 37
33805b261ecSmrg * Also referred to as RealizeWindow
33905b261ecSmrg */
34005b261ecSmrg
34105b261ecSmrgBool
34235c4bbdfSmrgwinMapWindowMultiWindow(WindowPtr pWin)
34305b261ecSmrg{
34435c4bbdfSmrg    Bool fResult = TRUE;
34535c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
34635c4bbdfSmrg
34735c4bbdfSmrg    winWindowPriv(pWin);
34835c4bbdfSmrg    winScreenPriv(pScreen);
34905b261ecSmrg
35005b261ecSmrg#if CYGMULTIWINDOW_DEBUG
35135c4bbdfSmrg    ErrorF("winMapWindowMultiWindow - pWin: %p\n", pWin);
35205b261ecSmrg#endif
35305b261ecSmrg
35435c4bbdfSmrg    WIN_UNWRAP(RealizeWindow);
35535c4bbdfSmrg    fResult = (*pScreen->RealizeWindow) (pWin);
35635c4bbdfSmrg    WIN_WRAP(RealizeWindow, winMapWindowMultiWindow);
35705b261ecSmrg
35835c4bbdfSmrg    /* Flag that this window has not been destroyed */
35935c4bbdfSmrg    pWinPriv->fXKilled = FALSE;
36005b261ecSmrg
36135c4bbdfSmrg    /* Refresh/redisplay the Windows window associated with this X window */
36235c4bbdfSmrg    winUpdateWindowsWindow(pWin);
36305b261ecSmrg
36435c4bbdfSmrg    /* Update the Windows window's shape */
36535c4bbdfSmrg    winReshapeMultiWindow(pWin);
36635c4bbdfSmrg    winUpdateRgnMultiWindow(pWin);
36735c4bbdfSmrg
36835c4bbdfSmrg    return fResult;
36935c4bbdfSmrg}
37005b261ecSmrg
37105b261ecSmrg/*
37205b261ecSmrg * ReparentWindow - See Porting Layer Definition - p. 42
37305b261ecSmrg */
37405b261ecSmrg
37505b261ecSmrgvoid
37635c4bbdfSmrgwinReparentWindowMultiWindow(WindowPtr pWin, WindowPtr pPriorParent)
37705b261ecSmrg{
37835c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
37905b261ecSmrg
38035c4bbdfSmrg    winScreenPriv(pScreen);
38105b261ecSmrg
38235c4bbdfSmrg    winDebug
38335c4bbdfSmrg        ("winReparentMultiWindow - pWin:%p XID:0x%x, reparent from pWin:%p XID:0x%x to pWin:%p XID:0x%x\n",
38435c4bbdfSmrg         pWin, (unsigned int)pWin->drawable.id,
38535c4bbdfSmrg         pPriorParent, (unsigned int)pPriorParent->drawable.id,
38635c4bbdfSmrg         pWin->parent, (unsigned int)pWin->parent->drawable.id);
38735c4bbdfSmrg
38835c4bbdfSmrg    WIN_UNWRAP(ReparentWindow);
38935c4bbdfSmrg    if (pScreen->ReparentWindow)
39035c4bbdfSmrg        (*pScreen->ReparentWindow) (pWin, pPriorParent);
39135c4bbdfSmrg    WIN_WRAP(ReparentWindow, winReparentWindowMultiWindow);
39205b261ecSmrg
39335c4bbdfSmrg    /* Update the Windows window associated with this X window */
39435c4bbdfSmrg    winUpdateWindowsWindow(pWin);
39535c4bbdfSmrg}
39605b261ecSmrg
39705b261ecSmrg/*
39805b261ecSmrg * RestackWindow - Shuffle the z-order of a window
39905b261ecSmrg */
40005b261ecSmrg
40105b261ecSmrgvoid
40235c4bbdfSmrgwinRestackWindowMultiWindow(WindowPtr pWin, WindowPtr pOldNextSib)
40305b261ecSmrg{
4046747b715Smrg#if 0
40535c4bbdfSmrg    WindowPtr pPrevWin;
40635c4bbdfSmrg    UINT uFlags;
40735c4bbdfSmrg    HWND hInsertAfter;
40835c4bbdfSmrg    HWND hWnd = NULL;
4096747b715Smrg#endif
41035c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
41135c4bbdfSmrg
41235c4bbdfSmrg    winScreenPriv(pScreen);
41305b261ecSmrg
41405b261ecSmrg#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
41535c4bbdfSmrg    winTrace("winRestackMultiWindow - %p\n", pWin);
41635c4bbdfSmrg#endif
41735c4bbdfSmrg
41835c4bbdfSmrg    WIN_UNWRAP(RestackWindow);
41935c4bbdfSmrg    if (pScreen->RestackWindow)
42035c4bbdfSmrg        (*pScreen->RestackWindow) (pWin, pOldNextSib);
42135c4bbdfSmrg    WIN_WRAP(RestackWindow, winRestackWindowMultiWindow);
42235c4bbdfSmrg
42305b261ecSmrg#if 1
42435c4bbdfSmrg    /*
42535c4bbdfSmrg     * Calling winReorderWindowsMultiWindow here means our window manager
42635c4bbdfSmrg     * (i.e. Windows Explorer) has initiative to determine Z order.
42735c4bbdfSmrg     */
42835c4bbdfSmrg    if (pWin->nextSib != pOldNextSib)
42935c4bbdfSmrg        winReorderWindowsMultiWindow();
43005b261ecSmrg#else
43135c4bbdfSmrg    /* Bail out if no window privates or window handle is invalid */
43235c4bbdfSmrg    if (!pWinPriv || !pWinPriv->hWnd)
43335c4bbdfSmrg        return;
43435c4bbdfSmrg
43535c4bbdfSmrg    /* Get a pointer to our previous sibling window */
43635c4bbdfSmrg    pPrevWin = pWin->prevSib;
43735c4bbdfSmrg
43835c4bbdfSmrg    /*
43935c4bbdfSmrg     * Look for a sibling window with
44035c4bbdfSmrg     * valid privates and window handle
44135c4bbdfSmrg     */
44235c4bbdfSmrg    while (pPrevWin && !winGetWindowPriv(pPrevWin)
44335c4bbdfSmrg           && !winGetWindowPriv(pPrevWin)->hWnd)
44435c4bbdfSmrg        pPrevWin = pPrevWin->prevSib;
44535c4bbdfSmrg
44635c4bbdfSmrg    /* Check if we found a valid sibling */
44735c4bbdfSmrg    if (pPrevWin) {
44835c4bbdfSmrg        /* Valid sibling - get handle to insert window after */
44935c4bbdfSmrg        hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd;
45035c4bbdfSmrg        uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
45135c4bbdfSmrg
45235c4bbdfSmrg        hWnd = GetNextWindow(pWinPriv->hWnd, GW_HWNDPREV);
45335c4bbdfSmrg
45435c4bbdfSmrg        do {
45535c4bbdfSmrg            if (GetProp(hWnd, WIN_WINDOW_PROP)) {
45635c4bbdfSmrg                if (hWnd == winGetWindowPriv(pPrevWin)->hWnd) {
45735c4bbdfSmrg                    uFlags |= SWP_NOZORDER;
45835c4bbdfSmrg                }
45935c4bbdfSmrg                break;
46035c4bbdfSmrg            }
46135c4bbdfSmrg            hWnd = GetNextWindow(hWnd, GW_HWNDPREV);
46235c4bbdfSmrg        }
46335c4bbdfSmrg        while (hWnd);
46405b261ecSmrg    }
46535c4bbdfSmrg    else {
46635c4bbdfSmrg        /* No valid sibling - make this window the top window */
46735c4bbdfSmrg        hInsertAfter = HWND_TOP;
46835c4bbdfSmrg        uFlags = SWP_NOMOVE | SWP_NOSIZE;
46905b261ecSmrg    }
47035c4bbdfSmrg
47135c4bbdfSmrg    /* Perform the restacking operation in Windows */
47235c4bbdfSmrg    SetWindowPos(pWinPriv->hWnd, hInsertAfter, 0, 0, 0, 0, uFlags);
47305b261ecSmrg#endif
47405b261ecSmrg}
47505b261ecSmrg
47605b261ecSmrg/*
47705b261ecSmrg * winCreateWindowsWindow - Create a Windows window associated with an X window
47805b261ecSmrg */
47905b261ecSmrg
48005b261ecSmrgvoid
48135c4bbdfSmrgwinCreateWindowsWindow(WindowPtr pWin)
48205b261ecSmrg{
48335c4bbdfSmrg    int iX, iY;
48435c4bbdfSmrg    int iWidth;
48535c4bbdfSmrg    int iHeight;
48635c4bbdfSmrg    HWND hWnd;
48735c4bbdfSmrg    HWND hFore = NULL;
48835c4bbdfSmrg
48935c4bbdfSmrg    winWindowPriv(pWin);
49035c4bbdfSmrg    WinXSizeHints hints;
49135c4bbdfSmrg    Window daddyId;
49235c4bbdfSmrg    DWORD dwStyle, dwExStyle;
49335c4bbdfSmrg    RECT rc;
49435c4bbdfSmrg
49535c4bbdfSmrg    winInitMultiWindowClass();
49635c4bbdfSmrg
49735c4bbdfSmrg    winDebug("winCreateWindowsTopLevelWindow - pWin:%p XID:0x%x \n", pWin,
49835c4bbdfSmrg             (unsigned int)pWin->drawable.id);
49935c4bbdfSmrg
50035c4bbdfSmrg    iX = pWin->drawable.x + GetSystemMetrics(SM_XVIRTUALSCREEN);
50135c4bbdfSmrg    iY = pWin->drawable.y + GetSystemMetrics(SM_YVIRTUALSCREEN);
50235c4bbdfSmrg
50335c4bbdfSmrg    iWidth = pWin->drawable.width;
50435c4bbdfSmrg    iHeight = pWin->drawable.height;
50535c4bbdfSmrg
50635c4bbdfSmrg    /* If it's an InputOutput window, and so is going to end up being made visible,
50735c4bbdfSmrg       make sure the window actually ends up somewhere where it will be visible
50835c4bbdfSmrg
50935c4bbdfSmrg       To handle arrangements of monitors which form a non-rectangular virtual
51035c4bbdfSmrg       desktop, check if the window will end up with it's top-left corner on any
51135c4bbdfSmrg       monitor
51235c4bbdfSmrg    */
51335c4bbdfSmrg    if (pWin->drawable.class != InputOnly) {
51435c4bbdfSmrg        POINT pt = { iX, iY };
51535c4bbdfSmrg        if (MonitorFromPoint(pt, MONITOR_DEFAULTTONULL) == NULL)
51635c4bbdfSmrg            {
51735c4bbdfSmrg                iX = CW_USEDEFAULT;
51835c4bbdfSmrg                iY = CW_USEDEFAULT;
51935c4bbdfSmrg            }
52035c4bbdfSmrg    }
52105b261ecSmrg
52235c4bbdfSmrg    winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX,
52335c4bbdfSmrg             iY);
52435c4bbdfSmrg
52535c4bbdfSmrg    if (winMultiWindowGetTransientFor(pWin, &daddyId)) {
52635c4bbdfSmrg        if (daddyId) {
52735c4bbdfSmrg            WindowPtr pParent;
52835c4bbdfSmrg            int res = dixLookupWindow(&pParent, daddyId, serverClient, DixReadAccess);
52935c4bbdfSmrg            if (res == Success)
53035c4bbdfSmrg                {
53135c4bbdfSmrg                    winPrivWinPtr pParentPriv = winGetWindowPriv(pParent);
53235c4bbdfSmrg                    hFore = pParentPriv->hWnd;
53335c4bbdfSmrg                }
53435c4bbdfSmrg        }
53535c4bbdfSmrg    }
53635c4bbdfSmrg    else {
53735c4bbdfSmrg        /* Default positions if none specified */
53835c4bbdfSmrg        if (!winMultiWindowGetWMNormalHints(pWin, &hints))
53935c4bbdfSmrg            hints.flags = 0;
54035c4bbdfSmrg        if (!(hints.flags & (USPosition | PPosition)) &&
54135c4bbdfSmrg            !pWin->overrideRedirect) {
54235c4bbdfSmrg            iX = CW_USEDEFAULT;
54335c4bbdfSmrg            iY = CW_USEDEFAULT;
54435c4bbdfSmrg        }
54535c4bbdfSmrg    }
54605b261ecSmrg
54735c4bbdfSmrg    /* Make it WS_OVERLAPPED in create call since WS_POPUP doesn't support */
54835c4bbdfSmrg    /* CW_USEDEFAULT, change back to popup after creation */
54935c4bbdfSmrg    dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
55035c4bbdfSmrg    dwExStyle = WS_EX_TOOLWINDOW;
55135c4bbdfSmrg
55235c4bbdfSmrg    /*
55335c4bbdfSmrg       Calculate the window coordinates containing the requested client area,
55435c4bbdfSmrg       being careful to preseve CW_USEDEFAULT
55535c4bbdfSmrg     */
55635c4bbdfSmrg    rc.top = (iY != CW_USEDEFAULT) ? iY : 0;
55735c4bbdfSmrg    rc.left = (iX != CW_USEDEFAULT) ? iX : 0;
55835c4bbdfSmrg    rc.bottom = rc.top + iHeight;
55935c4bbdfSmrg    rc.right = rc.left + iWidth;
56035c4bbdfSmrg    AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle);
56135c4bbdfSmrg    if (iY != CW_USEDEFAULT)
56235c4bbdfSmrg        iY = rc.top;
56335c4bbdfSmrg    if (iX != CW_USEDEFAULT)
56435c4bbdfSmrg        iX = rc.left;
56535c4bbdfSmrg    iHeight = rc.bottom - rc.top;
56635c4bbdfSmrg    iWidth = rc.right - rc.left;
56735c4bbdfSmrg
56835c4bbdfSmrg    winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX,
56935c4bbdfSmrg             iY);
57035c4bbdfSmrg
57135c4bbdfSmrg    /* Create the window */
57235c4bbdfSmrg    hWnd = CreateWindowExA(dwExStyle,   /* Extended styles */
57335c4bbdfSmrg                           WINDOW_CLASS_X,      /* Class name */
57435c4bbdfSmrg                           WINDOW_TITLE_X,      /* Window name */
57535c4bbdfSmrg                           dwStyle,     /* Styles */
57635c4bbdfSmrg                           iX,  /* Horizontal position */
57735c4bbdfSmrg                           iY,  /* Vertical position */
57835c4bbdfSmrg                           iWidth,      /* Right edge */
57935c4bbdfSmrg                           iHeight,     /* Bottom edge */
58035c4bbdfSmrg                           hFore,       /* Null or Parent window if transient */
58135c4bbdfSmrg                           (HMENU) NULL,        /* No menu */
58235c4bbdfSmrg                           GetModuleHandle(NULL),       /* Instance handle */
58335c4bbdfSmrg                           pWin);       /* ScreenPrivates */
58435c4bbdfSmrg    if (hWnd == NULL) {
58535c4bbdfSmrg        ErrorF("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
58635c4bbdfSmrg               (int) GetLastError());
58735c4bbdfSmrg    }
58835c4bbdfSmrg    pWinPriv->hWnd = hWnd;
58905b261ecSmrg
59035c4bbdfSmrg    /* Change style back to popup, already placed... */
59135c4bbdfSmrg    SetWindowLongPtr(hWnd, GWL_STYLE,
59235c4bbdfSmrg                     WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
59335c4bbdfSmrg    SetWindowPos(hWnd, 0, 0, 0, 0, 0,
59435c4bbdfSmrg                 SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE |
59535c4bbdfSmrg                 SWP_NOACTIVATE);
59605b261ecSmrg
59735c4bbdfSmrg    /* Adjust the X window to match the window placement we actually got... */
59835c4bbdfSmrg    winAdjustXWindow(pWin, hWnd);
59905b261ecSmrg
60035c4bbdfSmrg    /* Make sure it gets the proper system menu for a WS_POPUP, too */
60135c4bbdfSmrg    GetSystemMenu(hWnd, TRUE);
60205b261ecSmrg
60335c4bbdfSmrg    /* Cause any .XWinrc menus to be added in main WNDPROC */
60435c4bbdfSmrg    PostMessage(hWnd, WM_INIT_SYS_MENU, 0, 0);
60505b261ecSmrg
60635c4bbdfSmrg    SetProp(hWnd, WIN_WID_PROP, (HANDLE) (INT_PTR) winGetWindowID(pWin));
60735c4bbdfSmrg
60835c4bbdfSmrg    /* Flag that this Windows window handles its own activation */
60935c4bbdfSmrg    SetProp(hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0);
61035c4bbdfSmrg}
61105b261ecSmrg
61205b261ecSmrgBool winInDestroyWindowsWindow = FALSE;
61335c4bbdfSmrg
61405b261ecSmrg/*
61505b261ecSmrg * winDestroyWindowsWindow - Destroy a Windows window associated
61605b261ecSmrg * with an X window
61705b261ecSmrg */
61805b261ecSmrgstatic void
61935c4bbdfSmrgwinDestroyWindowsWindow(WindowPtr pWin)
62005b261ecSmrg{
62135c4bbdfSmrg    MSG msg;
62205b261ecSmrg
62335c4bbdfSmrg    winWindowPriv(pWin);
62435c4bbdfSmrg    BOOL oldstate = winInDestroyWindowsWindow;
62535c4bbdfSmrg    HICON hIcon;
62635c4bbdfSmrg    HICON hIconSm;
62705b261ecSmrg
62835c4bbdfSmrg    winDebug("winDestroyWindowsWindow - pWin:%p XID:0x%x \n", pWin,
62935c4bbdfSmrg             (unsigned int)pWin->drawable.id);
63005b261ecSmrg
63135c4bbdfSmrg    /* Bail out if the Windows window handle is invalid */
63235c4bbdfSmrg    if (pWinPriv->hWnd == NULL)
63335c4bbdfSmrg        return;
63405b261ecSmrg
63535c4bbdfSmrg    winInDestroyWindowsWindow = TRUE;
63605b261ecSmrg
63735c4bbdfSmrg    /* Store the info we need to destroy after this window is gone */
63835c4bbdfSmrg    hIcon = (HICON) SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_BIG, 0);
63935c4bbdfSmrg    hIconSm = (HICON) SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_SMALL, 0);
64005b261ecSmrg
64135c4bbdfSmrg    /* Destroy the Windows window */
64235c4bbdfSmrg    DestroyWindow(pWinPriv->hWnd);
64305b261ecSmrg
64435c4bbdfSmrg    /* Null our handle to the Window so referencing it will cause an error */
64535c4bbdfSmrg    pWinPriv->hWnd = NULL;
64635c4bbdfSmrg
64735c4bbdfSmrg    /* Destroy any icons we created for this window */
64835c4bbdfSmrg    winDestroyIcon(hIcon);
64935c4bbdfSmrg    winDestroyIcon(hIconSm);
65035c4bbdfSmrg
65135c4bbdfSmrg#ifdef XWIN_GLX_WINDOWS
65235c4bbdfSmrg    /* No longer note WGL used on this window */
65335c4bbdfSmrg    pWinPriv->fWglUsed = FALSE;
65405b261ecSmrg#endif
65505b261ecSmrg
65635c4bbdfSmrg    /* Process all messages on our queue */
65735c4bbdfSmrg    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
65835c4bbdfSmrg        if (g_hDlgDepthChange == 0 || !IsDialogMessage(g_hDlgDepthChange, &msg)) {
65935c4bbdfSmrg            DispatchMessage(&msg);
66035c4bbdfSmrg        }
66135c4bbdfSmrg    }
66235c4bbdfSmrg
66335c4bbdfSmrg    winInDestroyWindowsWindow = oldstate;
66435c4bbdfSmrg
66535c4bbdfSmrg    winDebug("winDestroyWindowsWindow - done\n");
66635c4bbdfSmrg}
66705b261ecSmrg
66805b261ecSmrg/*
66905b261ecSmrg * winUpdateWindowsWindow - Redisplay/redraw a Windows window
67005b261ecSmrg * associated with an X window
67105b261ecSmrg */
67205b261ecSmrg
67305b261ecSmrgstatic void
67435c4bbdfSmrgwinUpdateWindowsWindow(WindowPtr pWin)
67505b261ecSmrg{
67635c4bbdfSmrg    winWindowPriv(pWin);
67735c4bbdfSmrg    HWND hWnd = pWinPriv->hWnd;
67805b261ecSmrg
67905b261ecSmrg#if CYGMULTIWINDOW_DEBUG
68035c4bbdfSmrg    ErrorF("winUpdateWindowsWindow\n");
68105b261ecSmrg#endif
68205b261ecSmrg
68335c4bbdfSmrg    /* Check if the Windows window's parents have been destroyed */
68435c4bbdfSmrg    if (pWin->parent != NULL && pWin->parent->parent == NULL && pWin->mapped) {
68535c4bbdfSmrg        /* Create the Windows window if it has been destroyed */
68635c4bbdfSmrg        if (hWnd == NULL) {
68735c4bbdfSmrg            winCreateWindowsWindow(pWin);
68835c4bbdfSmrg            assert(pWinPriv->hWnd != NULL);
68935c4bbdfSmrg        }
69035c4bbdfSmrg
69135c4bbdfSmrg        /* Display the window without activating it */
69235c4bbdfSmrg        if (pWin->drawable.class != InputOnly)
69335c4bbdfSmrg            ShowWindow(pWinPriv->hWnd, SW_SHOWNOACTIVATE);
69435c4bbdfSmrg
69535c4bbdfSmrg        /* Send first paint message */
69635c4bbdfSmrg        UpdateWindow(pWinPriv->hWnd);
69705b261ecSmrg    }
69835c4bbdfSmrg    else if (hWnd != NULL) {
69935c4bbdfSmrg        /* Destroy the Windows window if its parents are destroyed */
70035c4bbdfSmrg        winDestroyWindowsWindow(pWin);
70135c4bbdfSmrg        assert(pWinPriv->hWnd == NULL);
70205b261ecSmrg    }
70305b261ecSmrg
70405b261ecSmrg#if CYGMULTIWINDOW_DEBUG
70535c4bbdfSmrg    ErrorF("-winUpdateWindowsWindow\n");
70605b261ecSmrg#endif
70705b261ecSmrg}
70805b261ecSmrg
70905b261ecSmrg/*
71035c4bbdfSmrg * winGetWindowID -
71105b261ecSmrg */
71205b261ecSmrg
71305b261ecSmrgXID
71435c4bbdfSmrgwinGetWindowID(WindowPtr pWin)
71505b261ecSmrg{
71635c4bbdfSmrg    WindowIDPairRec wi = { pWin, 0 };
71735c4bbdfSmrg    ClientPtr c = wClient(pWin);
71835c4bbdfSmrg
71935c4bbdfSmrg    /* */
72035c4bbdfSmrg    FindClientResourcesByType(c, RT_WINDOW, winFindWindow, &wi);
72105b261ecSmrg
72205b261ecSmrg#if CYGMULTIWINDOW_DEBUG
72335c4bbdfSmrg    ErrorF("winGetWindowID - Window ID: %u\n", (unsigned int)wi.id);
72405b261ecSmrg#endif
72505b261ecSmrg
72635c4bbdfSmrg    return wi.id;
72705b261ecSmrg}
72805b261ecSmrg
72905b261ecSmrg/*
73035c4bbdfSmrg * winFindWindow -
73105b261ecSmrg */
73205b261ecSmrg
73305b261ecSmrgstatic void
73435c4bbdfSmrgwinFindWindow(void *value, XID id, void *cdata)
73505b261ecSmrg{
73635c4bbdfSmrg    WindowIDPairPtr wi = (WindowIDPairPtr) cdata;
73705b261ecSmrg
73835c4bbdfSmrg    if (value == wi->value) {
73935c4bbdfSmrg        wi->id = id;
74005b261ecSmrg    }
74105b261ecSmrg}
74205b261ecSmrg
74305b261ecSmrg/*
74435c4bbdfSmrg * winReorderWindowsMultiWindow -
74505b261ecSmrg */
74605b261ecSmrg
74705b261ecSmrgvoid
74835c4bbdfSmrgwinReorderWindowsMultiWindow(void)
74905b261ecSmrg{
75035c4bbdfSmrg    HWND hwnd = NULL;
75135c4bbdfSmrg    WindowPtr pWin = NULL;
75235c4bbdfSmrg    WindowPtr pWinSib = NULL;
75335c4bbdfSmrg    XID vlist[2];
75435c4bbdfSmrg    static Bool fRestacking = FALSE;    /* Avoid recusive calls to this function */
75535c4bbdfSmrg    DWORD dwCurrentProcessID = GetCurrentProcessId();
75635c4bbdfSmrg    DWORD dwWindowProcessID = 0;
75705b261ecSmrg
75805b261ecSmrg#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
75935c4bbdfSmrg    winTrace("winReorderWindowsMultiWindow\n");
76005b261ecSmrg#endif
76105b261ecSmrg
76235c4bbdfSmrg    if (fRestacking) {
76335c4bbdfSmrg        /* It is a recusive call so immediately exit */
76405b261ecSmrg#if CYGWINDOWING_DEBUG
76535c4bbdfSmrg        ErrorF("winReorderWindowsMultiWindow - "
76635c4bbdfSmrg               "exit because fRestacking == TRUE\n");
76705b261ecSmrg#endif
76835c4bbdfSmrg        return;
76905b261ecSmrg    }
77035c4bbdfSmrg    fRestacking = TRUE;
77135c4bbdfSmrg
77235c4bbdfSmrg    /* Loop through top level Window windows, descending in Z order */
77335c4bbdfSmrg    for (hwnd = GetTopWindow(NULL);
77435c4bbdfSmrg         hwnd; hwnd = GetNextWindow(hwnd, GW_HWNDNEXT)) {
77535c4bbdfSmrg        /* Don't take care of other Cygwin/X process's windows */
77635c4bbdfSmrg        GetWindowThreadProcessId(hwnd, &dwWindowProcessID);
77735c4bbdfSmrg
77835c4bbdfSmrg        if (GetProp(hwnd, WIN_WINDOW_PROP)
77935c4bbdfSmrg            && (dwWindowProcessID == dwCurrentProcessID)
78035c4bbdfSmrg            && !IsIconic(hwnd)) {       /* ignore minimized windows */
78135c4bbdfSmrg            pWinSib = pWin;
78235c4bbdfSmrg            pWin = GetProp(hwnd, WIN_WINDOW_PROP);
78335c4bbdfSmrg
78435c4bbdfSmrg            if (!pWinSib) {     /* 1st window - raise to the top */
78535c4bbdfSmrg                vlist[0] = Above;
78635c4bbdfSmrg
78735c4bbdfSmrg                ConfigureWindow(pWin, CWStackMode, vlist, wClient(pWin));
78835c4bbdfSmrg            }
78935c4bbdfSmrg            else {              /* 2nd or deeper windows - just below the previous one */
79035c4bbdfSmrg                vlist[0] = winGetWindowID(pWinSib);
79135c4bbdfSmrg                vlist[1] = Below;
79235c4bbdfSmrg
79335c4bbdfSmrg                ConfigureWindow(pWin, CWSibling | CWStackMode,
79435c4bbdfSmrg                                vlist, wClient(pWin));
79535c4bbdfSmrg            }
79635c4bbdfSmrg        }
79705b261ecSmrg    }
79805b261ecSmrg
79935c4bbdfSmrg    fRestacking = FALSE;
80005b261ecSmrg}
80105b261ecSmrg
80205b261ecSmrg/*
80305b261ecSmrg * CopyWindow - See Porting Layer Definition - p. 39
80405b261ecSmrg */
80505b261ecSmrgvoid
80635c4bbdfSmrgwinCopyWindowMultiWindow(WindowPtr pWin, DDXPointRec oldpt, RegionPtr oldRegion)
80705b261ecSmrg{
80835c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
80935c4bbdfSmrg
81035c4bbdfSmrg    winScreenPriv(pScreen);
81105b261ecSmrg
81205b261ecSmrg#if CYGWINDOWING_DEBUG
81335c4bbdfSmrg    ErrorF("CopyWindowMultiWindow\n");
81405b261ecSmrg#endif
81535c4bbdfSmrg    WIN_UNWRAP(CopyWindow);
81635c4bbdfSmrg    (*pScreen->CopyWindow) (pWin, oldpt, oldRegion);
81735c4bbdfSmrg    WIN_WRAP(CopyWindow, winCopyWindowMultiWindow);
81805b261ecSmrg}
81905b261ecSmrg
82005b261ecSmrg/*
82105b261ecSmrg * MoveWindow - See Porting Layer Definition - p. 42
82205b261ecSmrg */
82305b261ecSmrgvoid
82435c4bbdfSmrgwinMoveWindowMultiWindow(WindowPtr pWin, int x, int y,
82535c4bbdfSmrg                         WindowPtr pSib, VTKind kind)
82605b261ecSmrg{
82735c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
82835c4bbdfSmrg
82935c4bbdfSmrg    winScreenPriv(pScreen);
83005b261ecSmrg
83105b261ecSmrg#if CYGWINDOWING_DEBUG
83235c4bbdfSmrg    ErrorF("MoveWindowMultiWindow to (%d, %d)\n", x, y);
83305b261ecSmrg#endif
83405b261ecSmrg
83535c4bbdfSmrg    WIN_UNWRAP(MoveWindow);
83635c4bbdfSmrg    (*pScreen->MoveWindow) (pWin, x, y, pSib, kind);
83735c4bbdfSmrg    WIN_WRAP(MoveWindow, winMoveWindowMultiWindow);
83805b261ecSmrg}
83905b261ecSmrg
84005b261ecSmrg/*
84105b261ecSmrg * ResizeWindow - See Porting Layer Definition - p. 42
84205b261ecSmrg */
84305b261ecSmrgvoid
84435c4bbdfSmrgwinResizeWindowMultiWindow(WindowPtr pWin, int x, int y, unsigned int w,
84535c4bbdfSmrg                           unsigned int h, WindowPtr pSib)
84605b261ecSmrg{
84735c4bbdfSmrg    ScreenPtr pScreen = pWin->drawable.pScreen;
84835c4bbdfSmrg
84935c4bbdfSmrg    winScreenPriv(pScreen);
85005b261ecSmrg
85105b261ecSmrg#if CYGWINDOWING_DEBUG
85235c4bbdfSmrg    ErrorF("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x, y, w, h);
85305b261ecSmrg#endif
85435c4bbdfSmrg    WIN_UNWRAP(ResizeWindow);
85535c4bbdfSmrg    (*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
85635c4bbdfSmrg    WIN_WRAP(ResizeWindow, winResizeWindowMultiWindow);
85705b261ecSmrg}
85805b261ecSmrg
85905b261ecSmrg/*
86005b261ecSmrg * winAdjustXWindow
86105b261ecSmrg *
86205b261ecSmrg * Move and resize X window with respect to corresponding Windows window.
86305b261ecSmrg * This is called from WM_MOVE/WM_SIZE handlers when the user performs
86405b261ecSmrg * any windowing operation (move, resize, minimize, maximize, restore).
86505b261ecSmrg *
86605b261ecSmrg * The functionality is the inverse of winPositionWindowMultiWindow, which
86705b261ecSmrg * adjusts Windows window with respect to X window.
86805b261ecSmrg */
86905b261ecSmrgint
87035c4bbdfSmrgwinAdjustXWindow(WindowPtr pWin, HWND hwnd)
87105b261ecSmrg{
87235c4bbdfSmrg    RECT rcDraw;                /* Rect made from pWin->drawable to be adjusted */
87335c4bbdfSmrg    RECT rcWin;                 /* The source: WindowRect from hwnd */
87435c4bbdfSmrg    DrawablePtr pDraw;
87535c4bbdfSmrg    XID vlist[4];
87635c4bbdfSmrg    LONG dX, dY, dW, dH, x, y;
87735c4bbdfSmrg    DWORD dwStyle, dwExStyle;
87805b261ecSmrg
87905b261ecSmrg#define WIDTH(rc) (rc.right - rc.left)
88005b261ecSmrg#define HEIGHT(rc) (rc.bottom - rc.top)
88135c4bbdfSmrg
88205b261ecSmrg#if CYGWINDOWING_DEBUG
88335c4bbdfSmrg    ErrorF("winAdjustXWindow\n");
88405b261ecSmrg#endif
88505b261ecSmrg
88635c4bbdfSmrg    if (IsIconic(hwnd)) {
88705b261ecSmrg#if CYGWINDOWING_DEBUG
88835c4bbdfSmrg        ErrorF("\timmediately return because the window is iconized\n");
88935c4bbdfSmrg#endif
89035c4bbdfSmrg        /*
89135c4bbdfSmrg         * If the Windows window is minimized, its WindowRect has
89235c4bbdfSmrg         * meaningless values so we don't adjust X window to it.
89335c4bbdfSmrg         */
89435c4bbdfSmrg        vlist[0] = 0;
89535c4bbdfSmrg        vlist[1] = 0;
89635c4bbdfSmrg        return ConfigureWindow(pWin, CWX | CWY, vlist, wClient(pWin));
89705b261ecSmrg    }
89805b261ecSmrg
89935c4bbdfSmrg    pDraw = &pWin->drawable;
90035c4bbdfSmrg
90135c4bbdfSmrg    /* Calculate the window rect from the drawable */
90235c4bbdfSmrg    x = pDraw->x + GetSystemMetrics(SM_XVIRTUALSCREEN);
90335c4bbdfSmrg    y = pDraw->y + GetSystemMetrics(SM_YVIRTUALSCREEN);
90435c4bbdfSmrg    SetRect(&rcDraw, x, y, x + pDraw->width, y + pDraw->height);
90505b261ecSmrg#ifdef CYGMULTIWINDOW_DEBUG
90635c4bbdfSmrg    winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n",
90735c4bbdfSmrg             (int)rcDraw.left, (int)rcDraw.top, (int)rcDraw.right, (int)rcDraw.bottom,
90835c4bbdfSmrg             (int)(rcDraw.right - rcDraw.left), (int)(rcDraw.bottom - rcDraw.top));
90905b261ecSmrg#endif
91035c4bbdfSmrg    dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
91135c4bbdfSmrg    dwStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
91205b261ecSmrg#ifdef CYGMULTIWINDOW_DEBUG
91335c4bbdfSmrg    winDebug("\tWindowStyle: %08x %08x\n", (unsigned int)dwStyle, (unsigned int)dwExStyle);
91405b261ecSmrg#endif
91535c4bbdfSmrg    AdjustWindowRectEx(&rcDraw, dwStyle, FALSE, dwExStyle);
91605b261ecSmrg
91735c4bbdfSmrg    /* The source of adjust */
91835c4bbdfSmrg    GetWindowRect(hwnd, &rcWin);
91905b261ecSmrg#ifdef CYGMULTIWINDOW_DEBUG
92035c4bbdfSmrg    winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
92135c4bbdfSmrg             (int)rcWin.left, (int)rcWin.top, (int)rcWin.right, (int)rcWin.bottom,
92235c4bbdfSmrg             (int)(rcWin.right - rcWin.left), (int)(rcWin.bottom - rcWin.top));
92335c4bbdfSmrg    winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n",
92435c4bbdfSmrg             (int)rcDraw.left, (int)rcDraw.top, (int)rcDraw.right, (int)rcDraw.bottom,
92535c4bbdfSmrg             (int)(rcDraw.right - rcDraw.left), (int)(rcDraw.bottom - rcDraw.top));
92605b261ecSmrg#endif
92705b261ecSmrg
92835c4bbdfSmrg    if (EqualRect(&rcDraw, &rcWin)) {
92935c4bbdfSmrg        /* Bail if no adjust is needed */
93005b261ecSmrg#if CYGWINDOWING_DEBUG
93135c4bbdfSmrg        ErrorF("\treturn because already adjusted\n");
93235c4bbdfSmrg#endif
93335c4bbdfSmrg        return 0;
93435c4bbdfSmrg    }
93535c4bbdfSmrg
93635c4bbdfSmrg    /* Calculate delta values */
93735c4bbdfSmrg    dX = rcWin.left - rcDraw.left;
93835c4bbdfSmrg    dY = rcWin.top - rcDraw.top;
93935c4bbdfSmrg    dW = WIDTH(rcWin) - WIDTH(rcDraw);
94035c4bbdfSmrg    dH = HEIGHT(rcWin) - HEIGHT(rcDraw);
94135c4bbdfSmrg
94235c4bbdfSmrg    /*
94335c4bbdfSmrg     * Adjust.
94435c4bbdfSmrg     * We may only need to move (vlist[0] and [1]), or only resize
94535c4bbdfSmrg     * ([2] and [3]) but currently we set all the parameters and leave
94635c4bbdfSmrg     * the decision to ConfigureWindow.  The reason is code simplicity.
94735c4bbdfSmrg     */
94835c4bbdfSmrg    vlist[0] = pDraw->x + dX - wBorderWidth(pWin);
94935c4bbdfSmrg    vlist[1] = pDraw->y + dY - wBorderWidth(pWin);
95035c4bbdfSmrg    vlist[2] = pDraw->width + dW;
95135c4bbdfSmrg    vlist[3] = pDraw->height + dH;
95205b261ecSmrg#if CYGWINDOWING_DEBUG
95335c4bbdfSmrg    ErrorF("\tConfigureWindow to (%u, %u) - %ux%u\n",
95435c4bbdfSmrg           (unsigned int)vlist[0], (unsigned int)vlist[1],
95535c4bbdfSmrg           (unsigned int)vlist[2], (unsigned int)vlist[3]);
95605b261ecSmrg#endif
95735c4bbdfSmrg    return ConfigureWindow(pWin, CWX | CWY | CWWidth | CWHeight,
95835c4bbdfSmrg                           vlist, wClient(pWin));
95935c4bbdfSmrg
96005b261ecSmrg#undef WIDTH
96105b261ecSmrg#undef HEIGHT
96205b261ecSmrg}
963