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
38ed6184dfSmrg
3905b261ecSmrg#include "win.h"
4005b261ecSmrg#include "dixevents.h"
4105b261ecSmrg#include "winmultiwindowclass.h"
4205b261ecSmrg#include "winprefs.h"
4305b261ecSmrg#include "winmsg.h"
4405b261ecSmrg#include "inputstr.h"
45ed6184dfSmrg#include <dwmapi.h>
46ed6184dfSmrg
47ed6184dfSmrg#ifndef WM_DWMCOMPOSITIONCHANGED
48ed6184dfSmrg#define WM_DWMCOMPOSITIONCHANGED 0x031e
49ed6184dfSmrg#endif
5005b261ecSmrg
5135c4bbdfSmrgextern void winUpdateWindowPosition(HWND hWnd, HWND * zstyle);
5205b261ecSmrg
5305b261ecSmrg/*
5405b261ecSmrg * Local globals
5505b261ecSmrg */
5605b261ecSmrg
5735c4bbdfSmrgstatic UINT_PTR g_uipMousePollingTimerID = 0;
5805b261ecSmrg
5905b261ecSmrg/*
6005b261ecSmrg * Constant defines
6105b261ecSmrg */
6205b261ecSmrg
6305b261ecSmrg#define WIN_MULTIWINDOW_SHAPE		YES
6405b261ecSmrg
6505b261ecSmrg/*
6605b261ecSmrg * ConstrainSize - Taken from TWM sources - Respects hints for sizing
6705b261ecSmrg */
6805b261ecSmrg#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) )
6905b261ecSmrgstatic void
7035c4bbdfSmrgConstrainSize(WinXSizeHints hints, int *widthp, int *heightp)
7105b261ecSmrg{
7235c4bbdfSmrg    int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta;
7335c4bbdfSmrg    int baseWidth, baseHeight;
7435c4bbdfSmrg    int dwidth = *widthp, dheight = *heightp;
7535c4bbdfSmrg
7635c4bbdfSmrg    if (hints.flags & PMinSize) {
7735c4bbdfSmrg        minWidth = hints.min_width;
7835c4bbdfSmrg        minHeight = hints.min_height;
7905b261ecSmrg    }
8035c4bbdfSmrg    else if (hints.flags & PBaseSize) {
8135c4bbdfSmrg        minWidth = hints.base_width;
8235c4bbdfSmrg        minHeight = hints.base_height;
8305b261ecSmrg    }
8435c4bbdfSmrg    else
8535c4bbdfSmrg        minWidth = minHeight = 1;
8635c4bbdfSmrg
8735c4bbdfSmrg    if (hints.flags & PBaseSize) {
8835c4bbdfSmrg        baseWidth = hints.base_width;
8935c4bbdfSmrg        baseHeight = hints.base_height;
9005b261ecSmrg    }
9135c4bbdfSmrg    else if (hints.flags & PMinSize) {
9235c4bbdfSmrg        baseWidth = hints.min_width;
9335c4bbdfSmrg        baseHeight = hints.min_height;
9435c4bbdfSmrg    }
9535c4bbdfSmrg    else
9635c4bbdfSmrg        baseWidth = baseHeight = 0;
9705b261ecSmrg
9835c4bbdfSmrg    if (hints.flags & PMaxSize) {
9935c4bbdfSmrg        maxWidth = hints.max_width;
10035c4bbdfSmrg        maxHeight = hints.max_height;
10105b261ecSmrg    }
10235c4bbdfSmrg    else {
10335c4bbdfSmrg        maxWidth = MAXINT;
10435c4bbdfSmrg        maxHeight = MAXINT;
10505b261ecSmrg    }
10605b261ecSmrg
10735c4bbdfSmrg    if (hints.flags & PResizeInc) {
10835c4bbdfSmrg        xinc = hints.width_inc;
10935c4bbdfSmrg        yinc = hints.height_inc;
11005b261ecSmrg    }
11135c4bbdfSmrg    else
11235c4bbdfSmrg        xinc = yinc = 1;
11335c4bbdfSmrg
11435c4bbdfSmrg    /*
11535c4bbdfSmrg     * First, clamp to min and max values
11635c4bbdfSmrg     */
11735c4bbdfSmrg    if (dwidth < minWidth)
11835c4bbdfSmrg        dwidth = minWidth;
11935c4bbdfSmrg    if (dheight < minHeight)
12035c4bbdfSmrg        dheight = minHeight;
12135c4bbdfSmrg
12235c4bbdfSmrg    if (dwidth > maxWidth)
12335c4bbdfSmrg        dwidth = maxWidth;
12435c4bbdfSmrg    if (dheight > maxHeight)
12535c4bbdfSmrg        dheight = maxHeight;
12635c4bbdfSmrg
12735c4bbdfSmrg    /*
12835c4bbdfSmrg     * Second, fit to base + N * inc
12935c4bbdfSmrg     */
13035c4bbdfSmrg    dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth;
13135c4bbdfSmrg    dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight;
13235c4bbdfSmrg
13335c4bbdfSmrg    /*
13435c4bbdfSmrg     * Third, adjust for aspect ratio
13535c4bbdfSmrg     */
13635c4bbdfSmrg
13735c4bbdfSmrg    /*
13835c4bbdfSmrg     * The math looks like this:
13935c4bbdfSmrg     *
14035c4bbdfSmrg     * minAspectX    dwidth     maxAspectX
14135c4bbdfSmrg     * ---------- <= ------- <= ----------
14235c4bbdfSmrg     * minAspectY    dheight    maxAspectY
14335c4bbdfSmrg     *
14435c4bbdfSmrg     * If that is multiplied out, then the width and height are
14535c4bbdfSmrg     * invalid in the following situations:
14635c4bbdfSmrg     *
14735c4bbdfSmrg     * minAspectX * dheight > minAspectY * dwidth
14835c4bbdfSmrg     * maxAspectX * dheight < maxAspectY * dwidth
14935c4bbdfSmrg     *
15035c4bbdfSmrg     */
15135c4bbdfSmrg
15235c4bbdfSmrg    if (hints.flags & PAspect) {
15335c4bbdfSmrg        if (hints.min_aspect.x * dheight > hints.min_aspect.y * dwidth) {
15435c4bbdfSmrg            delta =
15535c4bbdfSmrg                makemult(hints.min_aspect.x * dheight / hints.min_aspect.y -
15635c4bbdfSmrg                         dwidth, xinc);
15735c4bbdfSmrg            if (dwidth + delta <= maxWidth)
15835c4bbdfSmrg                dwidth += delta;
15935c4bbdfSmrg            else {
16035c4bbdfSmrg                delta =
16135c4bbdfSmrg                    makemult(dheight -
16235c4bbdfSmrg                             dwidth * hints.min_aspect.y / hints.min_aspect.x,
16335c4bbdfSmrg                             yinc);
16435c4bbdfSmrg                if (dheight - delta >= minHeight)
16535c4bbdfSmrg                    dheight -= delta;
16605b261ecSmrg            }
16705b261ecSmrg        }
16835c4bbdfSmrg
16935c4bbdfSmrg        if (hints.max_aspect.x * dheight < hints.max_aspect.y * dwidth) {
17035c4bbdfSmrg            delta =
17135c4bbdfSmrg                makemult(dwidth * hints.max_aspect.y / hints.max_aspect.x -
17235c4bbdfSmrg                         dheight, yinc);
17335c4bbdfSmrg            if (dheight + delta <= maxHeight)
17435c4bbdfSmrg                dheight += delta;
17535c4bbdfSmrg            else {
17635c4bbdfSmrg                delta =
17735c4bbdfSmrg                    makemult(dwidth -
17835c4bbdfSmrg                             hints.max_aspect.x * dheight / hints.max_aspect.y,
17935c4bbdfSmrg                             xinc);
18035c4bbdfSmrg                if (dwidth - delta >= minWidth)
18135c4bbdfSmrg                    dwidth -= delta;
18205b261ecSmrg            }
18305b261ecSmrg        }
18405b261ecSmrg    }
18505b261ecSmrg
18635c4bbdfSmrg    /* Return computed values */
18735c4bbdfSmrg    *widthp = dwidth;
18835c4bbdfSmrg    *heightp = dheight;
18935c4bbdfSmrg}
19005b261ecSmrg
19135c4bbdfSmrg#undef makemult
19205b261ecSmrg
19305b261ecSmrg/*
19405b261ecSmrg * ValidateSizing - Ensures size request respects hints
19505b261ecSmrg */
19605b261ecSmrgstatic int
19735c4bbdfSmrgValidateSizing(HWND hwnd, WindowPtr pWin, WPARAM wParam, LPARAM lParam)
19805b261ecSmrg{
19935c4bbdfSmrg    WinXSizeHints sizeHints;
20035c4bbdfSmrg    RECT *rect;
20135c4bbdfSmrg    int iWidth, iHeight;
20235c4bbdfSmrg    RECT rcClient, rcWindow;
20335c4bbdfSmrg    int iBorderWidthX, iBorderWidthY;
20435c4bbdfSmrg
20535c4bbdfSmrg    /* Invalid input checking */
20635c4bbdfSmrg    if (pWin == NULL || lParam == 0)
20735c4bbdfSmrg        return FALSE;
20835c4bbdfSmrg
20935c4bbdfSmrg    /* No size hints, no checking */
21035c4bbdfSmrg    if (!winMultiWindowGetWMNormalHints(pWin, &sizeHints))
21135c4bbdfSmrg        return FALSE;
21235c4bbdfSmrg
21335c4bbdfSmrg    /* Avoid divide-by-zero */
21435c4bbdfSmrg    if (sizeHints.flags & PResizeInc) {
21535c4bbdfSmrg        if (sizeHints.width_inc == 0)
21635c4bbdfSmrg            sizeHints.width_inc = 1;
21735c4bbdfSmrg        if (sizeHints.height_inc == 0)
21835c4bbdfSmrg            sizeHints.height_inc = 1;
21905b261ecSmrg    }
22035c4bbdfSmrg
22135c4bbdfSmrg    rect = (RECT *) lParam;
22235c4bbdfSmrg
22335c4bbdfSmrg    iWidth = rect->right - rect->left;
22435c4bbdfSmrg    iHeight = rect->bottom - rect->top;
22535c4bbdfSmrg
22635c4bbdfSmrg    /* Now remove size of any borders and title bar */
22735c4bbdfSmrg    GetClientRect(hwnd, &rcClient);
22835c4bbdfSmrg    GetWindowRect(hwnd, &rcWindow);
22935c4bbdfSmrg    iBorderWidthX =
23035c4bbdfSmrg        (rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left);
23135c4bbdfSmrg    iBorderWidthY =
23235c4bbdfSmrg        (rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top);
23335c4bbdfSmrg    iWidth -= iBorderWidthX;
23435c4bbdfSmrg    iHeight -= iBorderWidthY;
23535c4bbdfSmrg
23635c4bbdfSmrg    /* Constrain the size to legal values */
23735c4bbdfSmrg    ConstrainSize(sizeHints, &iWidth, &iHeight);
23835c4bbdfSmrg
23935c4bbdfSmrg    /* Add back the size of borders and title bar */
24035c4bbdfSmrg    iWidth += iBorderWidthX;
24135c4bbdfSmrg    iHeight += iBorderWidthY;
24235c4bbdfSmrg
24335c4bbdfSmrg    /* Adjust size according to where we're dragging from */
24435c4bbdfSmrg    switch (wParam) {
24535c4bbdfSmrg    case WMSZ_TOP:
24635c4bbdfSmrg    case WMSZ_TOPRIGHT:
24735c4bbdfSmrg    case WMSZ_BOTTOM:
24835c4bbdfSmrg    case WMSZ_BOTTOMRIGHT:
24935c4bbdfSmrg    case WMSZ_RIGHT:
25035c4bbdfSmrg        rect->right = rect->left + iWidth;
25135c4bbdfSmrg        break;
25235c4bbdfSmrg    default:
25335c4bbdfSmrg        rect->left = rect->right - iWidth;
25435c4bbdfSmrg        break;
25535c4bbdfSmrg    }
25635c4bbdfSmrg    switch (wParam) {
25735c4bbdfSmrg    case WMSZ_BOTTOM:
25835c4bbdfSmrg    case WMSZ_BOTTOMRIGHT:
25935c4bbdfSmrg    case WMSZ_BOTTOMLEFT:
26035c4bbdfSmrg    case WMSZ_RIGHT:
26135c4bbdfSmrg    case WMSZ_LEFT:
26235c4bbdfSmrg        rect->bottom = rect->top + iHeight;
26335c4bbdfSmrg        break;
26435c4bbdfSmrg    default:
26535c4bbdfSmrg        rect->top = rect->bottom - iHeight;
26635c4bbdfSmrg        break;
26735c4bbdfSmrg    }
26835c4bbdfSmrg    return TRUE;
26905b261ecSmrg}
27005b261ecSmrg
27105b261ecSmrgextern Bool winInDestroyWindowsWindow;
27205b261ecSmrgstatic Bool winInRaiseWindow = FALSE;
27335c4bbdfSmrgstatic void
27435c4bbdfSmrgwinRaiseWindow(WindowPtr pWin)
27505b261ecSmrg{
27635c4bbdfSmrg    if (!winInDestroyWindowsWindow && !winInRaiseWindow) {
27735c4bbdfSmrg        BOOL oldstate = winInRaiseWindow;
27835c4bbdfSmrg        XID vlist[1] = { 0 };
27935c4bbdfSmrg        winInRaiseWindow = TRUE;
28035c4bbdfSmrg        /* Call configure window directly to make sure it gets processed
28135c4bbdfSmrg         * in time
28235c4bbdfSmrg         */
28335c4bbdfSmrg        ConfigureWindow(pWin, CWStackMode, vlist, serverClient);
28435c4bbdfSmrg        winInRaiseWindow = oldstate;
28535c4bbdfSmrg    }
28605b261ecSmrg}
28705b261ecSmrg
2886747b715Smrgstatic
28935c4bbdfSmrg    void
29035c4bbdfSmrgwinStartMousePolling(winPrivScreenPtr s_pScreenPriv)
2916747b715Smrg{
29235c4bbdfSmrg    /*
29335c4bbdfSmrg     * Timer to poll mouse position.  This is needed to make
29435c4bbdfSmrg     * programs like xeyes follow the mouse properly when the
29535c4bbdfSmrg     * mouse pointer is outside of any X window.
29635c4bbdfSmrg     */
29735c4bbdfSmrg    if (g_uipMousePollingTimerID == 0)
29835c4bbdfSmrg        g_uipMousePollingTimerID = SetTimer(s_pScreenPriv->hwndScreen,
29935c4bbdfSmrg                                            WIN_POLLING_MOUSE_TIMER_ID,
30035c4bbdfSmrg                                            MOUSE_POLLING_INTERVAL, NULL);
3016747b715Smrg}
30205b261ecSmrg
303ed6184dfSmrg/* Undocumented */
304ed6184dfSmrgtypedef struct _ACCENTPOLICY
305ed6184dfSmrg{
306ed6184dfSmrg    ULONG AccentState;
307ed6184dfSmrg    ULONG AccentFlags;
308ed6184dfSmrg    ULONG GradientColor;
309ed6184dfSmrg    ULONG AnimationId;
310ed6184dfSmrg} ACCENTPOLICY;
311ed6184dfSmrg
312ed6184dfSmrg#define ACCENT_ENABLE_BLURBEHIND 3
313ed6184dfSmrg
314ed6184dfSmrgtypedef struct _WINCOMPATTR
315ed6184dfSmrg{
316ed6184dfSmrg    DWORD attribute;
317ed6184dfSmrg    PVOID pData;
318ed6184dfSmrg    ULONG dataSize;
319ed6184dfSmrg} WINCOMPATTR;
320ed6184dfSmrg
321ed6184dfSmrg#define WCA_ACCENT_POLICY 19
322ed6184dfSmrg
323ed6184dfSmrgtypedef WINBOOL WINAPI (*PFNSETWINDOWCOMPOSITIONATTRIBUTE)(HWND, WINCOMPATTR *);
324ed6184dfSmrg
325ed6184dfSmrgstatic void
326ed6184dfSmrgCheckForAlpha(HWND hWnd, WindowPtr pWin, winScreenInfo *pScreenInfo)
327ed6184dfSmrg{
328ed6184dfSmrg    /* Check (once) which API we should use */
329ed6184dfSmrg    static Bool doOnce = TRUE;
330ed6184dfSmrg    static PFNSETWINDOWCOMPOSITIONATTRIBUTE pSetWindowCompositionAttribute = NULL;
331ed6184dfSmrg    static Bool useDwmEnableBlurBehindWindow = FALSE;
332ed6184dfSmrg
333ed6184dfSmrg    if (doOnce)
334ed6184dfSmrg        {
335ed6184dfSmrg            OSVERSIONINFOEX osvi = {0};
336ed6184dfSmrg            osvi.dwOSVersionInfoSize = sizeof(osvi);
337ed6184dfSmrg            GetVersionEx((LPOSVERSIONINFO)&osvi);
338ed6184dfSmrg
339ed6184dfSmrg            /* SetWindowCompositionAttribute() exists on Windows 7 and later,
340ed6184dfSmrg               but doesn't work for this purpose, so first check for Windows 10
341ed6184dfSmrg               or later */
342ed6184dfSmrg            if (osvi.dwMajorVersion >= 10)
343ed6184dfSmrg                {
344ed6184dfSmrg                    HMODULE hUser32 = GetModuleHandle("user32");
345ed6184dfSmrg
346ed6184dfSmrg                    if (hUser32)
347ed6184dfSmrg                        pSetWindowCompositionAttribute = (PFNSETWINDOWCOMPOSITIONATTRIBUTE) GetProcAddress(hUser32, "SetWindowCompositionAttribute");
348ed6184dfSmrg                    winDebug("SetWindowCompositionAttribute %s\n", pSetWindowCompositionAttribute ? "found" : "not found");
349ed6184dfSmrg                }
350ed6184dfSmrg            /* On Windows 7 and Windows Vista, use DwmEnableBlurBehindWindow() */
351ed6184dfSmrg            else if ((osvi.dwMajorVersion == 6) && (osvi.dwMinorVersion <= 1))
352ed6184dfSmrg                {
353ed6184dfSmrg                    useDwmEnableBlurBehindWindow = TRUE;
354ed6184dfSmrg                }
355ed6184dfSmrg            /* On Windows 8 and Windows 8.1, using the alpha channel on those
356ed6184dfSmrg               seems near impossible, so we don't do anything. */
357ed6184dfSmrg
358ed6184dfSmrg            doOnce = FALSE;
359ed6184dfSmrg        }
360ed6184dfSmrg
361ed6184dfSmrg    /* alpha-channel use is wanted */
362ed6184dfSmrg    if (!g_fCompositeAlpha || !pScreenInfo->fCompositeWM)
363ed6184dfSmrg        return;
364ed6184dfSmrg
365ed6184dfSmrg    /* Image has alpha ... */
366ed6184dfSmrg    if (pWin->drawable.depth != 32)
367ed6184dfSmrg        return;
368ed6184dfSmrg
369ed6184dfSmrg    /* ... and we can do something useful with it? */
370ed6184dfSmrg    if (pSetWindowCompositionAttribute)
371ed6184dfSmrg        {
372ed6184dfSmrg            WINBOOL rc;
373ed6184dfSmrg            /* Use the (undocumented) SetWindowCompositionAttribute, if
374ed6184dfSmrg               available, to turn on alpha channel use on Windows 10. */
375ed6184dfSmrg            ACCENTPOLICY policy = { ACCENT_ENABLE_BLURBEHIND, 0, 0, 0 } ;
376ed6184dfSmrg            WINCOMPATTR data = { WCA_ACCENT_POLICY,  &policy, sizeof(ACCENTPOLICY) };
377ed6184dfSmrg
378ed6184dfSmrg            /* This turns on DWM looking at the alpha-channel of this window */
379ed6184dfSmrg            winDebug("enabling alpha for XID %08x hWnd %p, using SetWindowCompositionAttribute()\n", (unsigned int)pWin->drawable.id, hWnd);
380ed6184dfSmrg            rc = pSetWindowCompositionAttribute(hWnd, &data);
381ed6184dfSmrg            if (!rc)
382ed6184dfSmrg                ErrorF("SetWindowCompositionAttribute failed: %d\n", (int)GetLastError());
383ed6184dfSmrg        }
384ed6184dfSmrg    else if (useDwmEnableBlurBehindWindow)
385ed6184dfSmrg        {
386ed6184dfSmrg            HRESULT rc;
387ed6184dfSmrg            WINBOOL enabled;
388ed6184dfSmrg
389ed6184dfSmrg            rc = DwmIsCompositionEnabled(&enabled);
390ed6184dfSmrg            if ((rc == S_OK) && enabled)
391ed6184dfSmrg                {
392ed6184dfSmrg                    /* Use DwmEnableBlurBehindWindow, to turn on alpha channel
393ed6184dfSmrg                       use on Windows Vista and Windows 7 */
394ed6184dfSmrg                    DWM_BLURBEHIND bbh;
395ed6184dfSmrg                    bbh.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION | DWM_BB_TRANSITIONONMAXIMIZED;
396ed6184dfSmrg                    bbh.fEnable = TRUE;
397ed6184dfSmrg                    bbh.hRgnBlur = NULL;
398ed6184dfSmrg                    bbh.fTransitionOnMaximized = TRUE; /* What does this do ??? */
399ed6184dfSmrg
400ed6184dfSmrg                    /* This terribly-named function actually controls if DWM
401ed6184dfSmrg                       looks at the alpha channel of this window */
402ed6184dfSmrg                    winDebug("enabling alpha for XID %08x hWnd %p, using DwmEnableBlurBehindWindow()\n", (unsigned int)pWin->drawable.id, hWnd);
403ed6184dfSmrg                    rc = DwmEnableBlurBehindWindow(hWnd, &bbh);
404ed6184dfSmrg                    if (rc != S_OK)
405ed6184dfSmrg                        ErrorF("DwmEnableBlurBehindWindow failed: %x, %d\n", (int)rc, (int)GetLastError());
406ed6184dfSmrg                }
407ed6184dfSmrg        }
408ed6184dfSmrg}
409ed6184dfSmrg
41005b261ecSmrg/*
41105b261ecSmrg * winTopLevelWindowProc - Window procedure for all top-level Windows windows.
41205b261ecSmrg */
41305b261ecSmrg
41405b261ecSmrgLRESULT CALLBACK
41535c4bbdfSmrgwinTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
41605b261ecSmrg{
41735c4bbdfSmrg    POINT ptMouse;
41835c4bbdfSmrg    PAINTSTRUCT ps;
41935c4bbdfSmrg    WindowPtr pWin = NULL;
42035c4bbdfSmrg    winPrivWinPtr pWinPriv = NULL;
42135c4bbdfSmrg    ScreenPtr s_pScreen = NULL;
42235c4bbdfSmrg    winPrivScreenPtr s_pScreenPriv = NULL;
42335c4bbdfSmrg    winScreenInfo *s_pScreenInfo = NULL;
42435c4bbdfSmrg    HWND hwndScreen = NULL;
42535c4bbdfSmrg    DrawablePtr pDraw = NULL;
42635c4bbdfSmrg    winWMMessageRec wmMsg;
42735c4bbdfSmrg    Bool fWMMsgInitialized = FALSE;
42835c4bbdfSmrg    static Bool s_fTracking = FALSE;
42935c4bbdfSmrg    Bool needRestack = FALSE;
43035c4bbdfSmrg    LRESULT ret;
43135c4bbdfSmrg    static Bool hasEnteredSizeMove = FALSE;
43205b261ecSmrg
43305b261ecSmrg#if CYGDEBUG
43435c4bbdfSmrg    winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam,
43535c4bbdfSmrg                         lParam);
43605b261ecSmrg#endif
43705b261ecSmrg
438ed6184dfSmrg    /*
439ed6184dfSmrg       If this is WM_CREATE, set up the Windows window properties which point to
440ed6184dfSmrg       X window information, before we populate local convenience variables...
441ed6184dfSmrg     */
442ed6184dfSmrg    if (message == WM_CREATE) {
443ed6184dfSmrg        SetProp(hwnd,
444ed6184dfSmrg                WIN_WINDOW_PROP,
445ed6184dfSmrg                (HANDLE) ((LPCREATESTRUCT) lParam)->lpCreateParams);
446ed6184dfSmrg        SetProp(hwnd,
447ed6184dfSmrg                WIN_WID_PROP,
448ed6184dfSmrg                (HANDLE) (INT_PTR)winGetWindowID(((LPCREATESTRUCT) lParam)->
449ed6184dfSmrg                                                 lpCreateParams));
450ed6184dfSmrg    }
451ed6184dfSmrg
45235c4bbdfSmrg    /* Check if the Windows window property for our X window pointer is valid */
45335c4bbdfSmrg    if ((pWin = GetProp(hwnd, WIN_WINDOW_PROP)) != NULL) {
45435c4bbdfSmrg        /* Our X window pointer is valid */
45535c4bbdfSmrg
45635c4bbdfSmrg        /* Get pointers to the drawable and the screen */
45735c4bbdfSmrg        pDraw = &pWin->drawable;
45835c4bbdfSmrg        s_pScreen = pWin->drawable.pScreen;
45905b261ecSmrg
46035c4bbdfSmrg        /* Get a pointer to our window privates */
46135c4bbdfSmrg        pWinPriv = winGetWindowPriv(pWin);
46205b261ecSmrg
46335c4bbdfSmrg        /* Get pointers to our screen privates and screen info */
46435c4bbdfSmrg        s_pScreenPriv = pWinPriv->pScreenPriv;
46535c4bbdfSmrg        s_pScreenInfo = s_pScreenPriv->pScreenInfo;
46605b261ecSmrg
46735c4bbdfSmrg        /* Get the handle for our screen-sized window */
46835c4bbdfSmrg        hwndScreen = s_pScreenPriv->hwndScreen;
46905b261ecSmrg
47035c4bbdfSmrg        /* */
47135c4bbdfSmrg        wmMsg.msg = 0;
47235c4bbdfSmrg        wmMsg.hwndWindow = hwnd;
47335c4bbdfSmrg        wmMsg.iWindow = (Window) (INT_PTR) GetProp(hwnd, WIN_WID_PROP);
47405b261ecSmrg
47535c4bbdfSmrg        wmMsg.iX = pDraw->x;
47635c4bbdfSmrg        wmMsg.iY = pDraw->y;
47735c4bbdfSmrg        wmMsg.iWidth = pDraw->width;
47835c4bbdfSmrg        wmMsg.iHeight = pDraw->height;
47905b261ecSmrg
48035c4bbdfSmrg        fWMMsgInitialized = TRUE;
48105b261ecSmrg
48205b261ecSmrg#if 0
48335c4bbdfSmrg        /*
48435c4bbdfSmrg         * Print some debugging information
48535c4bbdfSmrg         */
48635c4bbdfSmrg
48735c4bbdfSmrg        ErrorF("hWnd %08X\n", hwnd);
48835c4bbdfSmrg        ErrorF("pWin %08X\n", pWin);
48935c4bbdfSmrg        ErrorF("pDraw %08X\n", pDraw);
49035c4bbdfSmrg        ErrorF("\ttype %08X\n", pWin->drawable.type);
49135c4bbdfSmrg        ErrorF("\tclass %08X\n", pWin->drawable.class);
49235c4bbdfSmrg        ErrorF("\tdepth %08X\n", pWin->drawable.depth);
49335c4bbdfSmrg        ErrorF("\tbitsPerPixel %08X\n", pWin->drawable.bitsPerPixel);
49435c4bbdfSmrg        ErrorF("\tid %08X\n", pWin->drawable.id);
49535c4bbdfSmrg        ErrorF("\tx %08X\n", pWin->drawable.x);
49635c4bbdfSmrg        ErrorF("\ty %08X\n", pWin->drawable.y);
49735c4bbdfSmrg        ErrorF("\twidth %08X\n", pWin->drawable.width);
49835c4bbdfSmrg        ErrorF("\thenght %08X\n", pWin->drawable.height);
49935c4bbdfSmrg        ErrorF("\tpScreen %08X\n", pWin->drawable.pScreen);
50035c4bbdfSmrg        ErrorF("\tserialNumber %08X\n", pWin->drawable.serialNumber);
50135c4bbdfSmrg        ErrorF("g_iWindowPrivateKey %p\n", g_iWindowPrivateKey);
50235c4bbdfSmrg        ErrorF("pWinPriv %08X\n", pWinPriv);
50335c4bbdfSmrg        ErrorF("s_pScreenPriv %08X\n", s_pScreenPriv);
50435c4bbdfSmrg        ErrorF("s_pScreenInfo %08X\n", s_pScreenInfo);
50535c4bbdfSmrg        ErrorF("hwndScreen %08X\n", hwndScreen);
50605b261ecSmrg#endif
50705b261ecSmrg    }
50805b261ecSmrg
50935c4bbdfSmrg    /* Branch on message type */
51035c4bbdfSmrg    switch (message) {
51105b261ecSmrg    case WM_CREATE:
51235c4bbdfSmrg        /*
51335c4bbdfSmrg         * Make X windows' Z orders sync with Windows windows because
51435c4bbdfSmrg         * there can be AlwaysOnTop windows overlapped on the window
51535c4bbdfSmrg         * currently being created.
51635c4bbdfSmrg         */
51735c4bbdfSmrg        winReorderWindowsMultiWindow();
51835c4bbdfSmrg
51935c4bbdfSmrg        /* Fix a 'round title bar corner background should be transparent not black' problem when first painted */
52035c4bbdfSmrg        {
52135c4bbdfSmrg            RECT rWindow;
52235c4bbdfSmrg            HRGN hRgnWindow;
52335c4bbdfSmrg
52435c4bbdfSmrg            GetWindowRect(hwnd, &rWindow);
52535c4bbdfSmrg            hRgnWindow = CreateRectRgnIndirect(&rWindow);
52635c4bbdfSmrg            SetWindowRgn(hwnd, hRgnWindow, TRUE);
52735c4bbdfSmrg            DeleteObject(hRgnWindow);
52835c4bbdfSmrg        }
52935c4bbdfSmrg
53035c4bbdfSmrg        SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) XMING_SIGNATURE);
53135c4bbdfSmrg
532ed6184dfSmrg        CheckForAlpha(hwnd, pWin, s_pScreenInfo);
533ed6184dfSmrg
53435c4bbdfSmrg        return 0;
53505b261ecSmrg
53605b261ecSmrg    case WM_INIT_SYS_MENU:
53735c4bbdfSmrg        /*
53835c4bbdfSmrg         * Add whatever the setup file wants to for this window
53935c4bbdfSmrg         */
54035c4bbdfSmrg        SetupSysMenu(hwnd);
54135c4bbdfSmrg        return 0;
54205b261ecSmrg
54305b261ecSmrg    case WM_SYSCOMMAND:
54435c4bbdfSmrg        /*
54535c4bbdfSmrg         * Any window menu items go through here
54635c4bbdfSmrg         */
5471b5d61b8Smrg        if (HandleCustomWM_COMMAND(hwnd, LOWORD(wParam), s_pScreenPriv)) {
54835c4bbdfSmrg            /* Don't pass customized menus to DefWindowProc */
54935c4bbdfSmrg            return 0;
55035c4bbdfSmrg        }
55135c4bbdfSmrg        if (wParam == SC_RESTORE || wParam == SC_MAXIMIZE) {
55235c4bbdfSmrg            WINDOWPLACEMENT wndpl;
55335c4bbdfSmrg
55435c4bbdfSmrg            wndpl.length = sizeof(wndpl);
55535c4bbdfSmrg            if (GetWindowPlacement(hwnd, &wndpl) &&
55635c4bbdfSmrg                wndpl.showCmd == SW_SHOWMINIMIZED)
55735c4bbdfSmrg                needRestack = TRUE;
55835c4bbdfSmrg        }
55935c4bbdfSmrg        break;
56005b261ecSmrg
56105b261ecSmrg    case WM_INITMENU:
56235c4bbdfSmrg        /* Checks/Unchecks any menu items before they are displayed */
56335c4bbdfSmrg        HandleCustomWM_INITMENU(hwnd, (HMENU)wParam);
56435c4bbdfSmrg        break;
56505b261ecSmrg
5666747b715Smrg    case WM_ERASEBKGND:
56735c4bbdfSmrg        /*
56835c4bbdfSmrg         * Pretend that we did erase the background but we don't care,
56935c4bbdfSmrg         * since we repaint the entire region anyhow
57035c4bbdfSmrg         * This avoids some flickering when resizing.
57135c4bbdfSmrg         */
57235c4bbdfSmrg        return TRUE;
5736747b715Smrg
57405b261ecSmrg    case WM_PAINT:
57535c4bbdfSmrg        /* Only paint if our window handle is valid */
576ed6184dfSmrg        if (hwnd == NULL)
57735c4bbdfSmrg            break;
57835c4bbdfSmrg
57935c4bbdfSmrg#ifdef XWIN_GLX_WINDOWS
58035c4bbdfSmrg        if (pWinPriv->fWglUsed) {
58135c4bbdfSmrg            /*
58235c4bbdfSmrg               For regions which are being drawn by GL, the shadow framebuffer doesn't have the
58335c4bbdfSmrg               correct bits, so don't bitblt from the shadow framebuffer
58435c4bbdfSmrg
58535c4bbdfSmrg               XXX: For now, just leave it alone, but ideally we want to send an expose event to
58635c4bbdfSmrg               the window so it really redraws the affected region...
58735c4bbdfSmrg             */
588ed6184dfSmrg            BeginPaint(hwnd, &ps);
58935c4bbdfSmrg            ValidateRect(hwnd, &(ps.rcPaint));
590ed6184dfSmrg            EndPaint(hwnd, &ps);
59135c4bbdfSmrg        }
59235c4bbdfSmrg        else
59335c4bbdfSmrg#endif
594ed6184dfSmrg            /* Call the engine dependent repainter */
595ed6184dfSmrg            if (*s_pScreenPriv->pwinBltExposedWindowRegion)
596ed6184dfSmrg                (*s_pScreenPriv->pwinBltExposedWindowRegion) (s_pScreen, pWin);
59735c4bbdfSmrg
59835c4bbdfSmrg        return 0;
59905b261ecSmrg
60005b261ecSmrg    case WM_MOUSEMOVE:
60135c4bbdfSmrg        /* Unpack the client area mouse coordinates */
60235c4bbdfSmrg        ptMouse.x = GET_X_LPARAM(lParam);
60335c4bbdfSmrg        ptMouse.y = GET_Y_LPARAM(lParam);
60435c4bbdfSmrg
60535c4bbdfSmrg        /* Translate the client area mouse coordinates to screen coordinates */
60635c4bbdfSmrg        ClientToScreen(hwnd, &ptMouse);
60735c4bbdfSmrg
60835c4bbdfSmrg        /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */
60935c4bbdfSmrg        ptMouse.x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
61035c4bbdfSmrg        ptMouse.y -= GetSystemMetrics(SM_YVIRTUALSCREEN);
61135c4bbdfSmrg
61235c4bbdfSmrg        /* We can't do anything without privates */
61335c4bbdfSmrg        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
61435c4bbdfSmrg            break;
61535c4bbdfSmrg
61635c4bbdfSmrg        /* Has the mouse pointer crossed screens? */
61735c4bbdfSmrg        if (s_pScreen != miPointerGetScreen(g_pwinPointer))
61835c4bbdfSmrg            miPointerSetScreen(g_pwinPointer, s_pScreenInfo->dwScreen,
61935c4bbdfSmrg                               ptMouse.x - s_pScreenInfo->dwXOffset,
62035c4bbdfSmrg                               ptMouse.y - s_pScreenInfo->dwYOffset);
62135c4bbdfSmrg
62235c4bbdfSmrg        /* Are we tracking yet? */
62335c4bbdfSmrg        if (!s_fTracking) {
62435c4bbdfSmrg            TRACKMOUSEEVENT tme;
62535c4bbdfSmrg
62635c4bbdfSmrg            /* Setup data structure */
62735c4bbdfSmrg            ZeroMemory(&tme, sizeof(tme));
62835c4bbdfSmrg            tme.cbSize = sizeof(tme);
62935c4bbdfSmrg            tme.dwFlags = TME_LEAVE;
63035c4bbdfSmrg            tme.hwndTrack = hwnd;
63135c4bbdfSmrg
63235c4bbdfSmrg            /* Call the tracking function */
63335c4bbdfSmrg            if (!TrackMouseEvent(&tme))
63435c4bbdfSmrg                ErrorF("winTopLevelWindowProc - TrackMouseEvent failed\n");
63535c4bbdfSmrg
63635c4bbdfSmrg            /* Flag that we are tracking now */
63735c4bbdfSmrg            s_fTracking = TRUE;
63835c4bbdfSmrg        }
63935c4bbdfSmrg
64035c4bbdfSmrg        /* Hide or show the Windows mouse cursor */
64135c4bbdfSmrg        if (g_fSoftwareCursor && g_fCursor) {
64235c4bbdfSmrg            /* Hide Windows cursor */
64335c4bbdfSmrg            g_fCursor = FALSE;
64435c4bbdfSmrg            ShowCursor(FALSE);
64535c4bbdfSmrg        }
64635c4bbdfSmrg
64735c4bbdfSmrg        /* Kill the timer used to poll mouse events */
64835c4bbdfSmrg        if (g_uipMousePollingTimerID != 0) {
64935c4bbdfSmrg            KillTimer(s_pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID);
65035c4bbdfSmrg            g_uipMousePollingTimerID = 0;
65135c4bbdfSmrg        }
65235c4bbdfSmrg
65335c4bbdfSmrg        /* Deliver absolute cursor position to X Server */
65435c4bbdfSmrg        winEnqueueMotion(ptMouse.x - s_pScreenInfo->dwXOffset,
65535c4bbdfSmrg                         ptMouse.y - s_pScreenInfo->dwYOffset);
65635c4bbdfSmrg
65735c4bbdfSmrg        return 0;
65835c4bbdfSmrg
65905b261ecSmrg    case WM_NCMOUSEMOVE:
66035c4bbdfSmrg        /*
66135c4bbdfSmrg         * We break instead of returning 0 since we need to call
66235c4bbdfSmrg         * DefWindowProc to get the mouse cursor changes
66335c4bbdfSmrg         * and min/max/close button highlighting in Windows XP.
66435c4bbdfSmrg         * The Platform SDK says that you should return 0 if you
66535c4bbdfSmrg         * process this message, but it fails to mention that you
66635c4bbdfSmrg         * will give up any default functionality if you do return 0.
66735c4bbdfSmrg         */
66835c4bbdfSmrg
66935c4bbdfSmrg        /* We can't do anything without privates */
67035c4bbdfSmrg        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
67135c4bbdfSmrg            break;
67235c4bbdfSmrg
67335c4bbdfSmrg        /* Non-client mouse movement, show Windows cursor */
67435c4bbdfSmrg        if (g_fSoftwareCursor && !g_fCursor) {
67535c4bbdfSmrg            g_fCursor = TRUE;
67635c4bbdfSmrg            ShowCursor(TRUE);
67735c4bbdfSmrg        }
67835c4bbdfSmrg
67935c4bbdfSmrg        winStartMousePolling(s_pScreenPriv);
68035c4bbdfSmrg
68135c4bbdfSmrg        break;
68205b261ecSmrg
68305b261ecSmrg    case WM_MOUSELEAVE:
68435c4bbdfSmrg        /* Mouse has left our client area */
68505b261ecSmrg
68635c4bbdfSmrg        /* Flag that we are no longer tracking */
68735c4bbdfSmrg        s_fTracking = FALSE;
68805b261ecSmrg
68935c4bbdfSmrg        /* Show the mouse cursor, if necessary */
69035c4bbdfSmrg        if (g_fSoftwareCursor && !g_fCursor) {
69135c4bbdfSmrg            g_fCursor = TRUE;
69235c4bbdfSmrg            ShowCursor(TRUE);
69335c4bbdfSmrg        }
69405b261ecSmrg
69535c4bbdfSmrg        winStartMousePolling(s_pScreenPriv);
6966747b715Smrg
69735c4bbdfSmrg        return 0;
69805b261ecSmrg
69905b261ecSmrg    case WM_LBUTTONDBLCLK:
70005b261ecSmrg    case WM_LBUTTONDOWN:
70135c4bbdfSmrg        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
70235c4bbdfSmrg            break;
70335c4bbdfSmrg        g_fButton[0] = TRUE;
70435c4bbdfSmrg        SetCapture(hwnd);
70535c4bbdfSmrg        return winMouseButtonsHandle(s_pScreen, ButtonPress, Button1, wParam);
7066747b715Smrg
70705b261ecSmrg    case WM_LBUTTONUP:
70835c4bbdfSmrg        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
70935c4bbdfSmrg            break;
71035c4bbdfSmrg        g_fButton[0] = FALSE;
71135c4bbdfSmrg        ReleaseCapture();
71235c4bbdfSmrg        winStartMousePolling(s_pScreenPriv);
71335c4bbdfSmrg        return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button1, wParam);
71405b261ecSmrg
71505b261ecSmrg    case WM_MBUTTONDBLCLK:
71605b261ecSmrg    case WM_MBUTTONDOWN:
71735c4bbdfSmrg        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
71835c4bbdfSmrg            break;
71935c4bbdfSmrg        g_fButton[1] = TRUE;
72035c4bbdfSmrg        SetCapture(hwnd);
72135c4bbdfSmrg        return winMouseButtonsHandle(s_pScreen, ButtonPress, Button2, wParam);
7226747b715Smrg
72305b261ecSmrg    case WM_MBUTTONUP:
72435c4bbdfSmrg        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
72535c4bbdfSmrg            break;
72635c4bbdfSmrg        g_fButton[1] = FALSE;
72735c4bbdfSmrg        ReleaseCapture();
72835c4bbdfSmrg        winStartMousePolling(s_pScreenPriv);
72935c4bbdfSmrg        return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button2, wParam);
7306747b715Smrg
73105b261ecSmrg    case WM_RBUTTONDBLCLK:
73205b261ecSmrg    case WM_RBUTTONDOWN:
73335c4bbdfSmrg        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
73435c4bbdfSmrg            break;
73535c4bbdfSmrg        g_fButton[2] = TRUE;
73635c4bbdfSmrg        SetCapture(hwnd);
73735c4bbdfSmrg        return winMouseButtonsHandle(s_pScreen, ButtonPress, Button3, wParam);
7386747b715Smrg
73905b261ecSmrg    case WM_RBUTTONUP:
74035c4bbdfSmrg        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
74135c4bbdfSmrg            break;
74235c4bbdfSmrg        g_fButton[2] = FALSE;
74335c4bbdfSmrg        ReleaseCapture();
74435c4bbdfSmrg        winStartMousePolling(s_pScreenPriv);
74535c4bbdfSmrg        return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button3, wParam);
74605b261ecSmrg
74705b261ecSmrg    case WM_XBUTTONDBLCLK:
74805b261ecSmrg    case WM_XBUTTONDOWN:
74935c4bbdfSmrg        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
75035c4bbdfSmrg            break;
75135c4bbdfSmrg        SetCapture(hwnd);
75235c4bbdfSmrg        return winMouseButtonsHandle(s_pScreen, ButtonPress, HIWORD(wParam) + 7,
75335c4bbdfSmrg                                     wParam);
7546747b715Smrg
75505b261ecSmrg    case WM_XBUTTONUP:
75635c4bbdfSmrg        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
75735c4bbdfSmrg            break;
75835c4bbdfSmrg        ReleaseCapture();
75935c4bbdfSmrg        winStartMousePolling(s_pScreenPriv);
76035c4bbdfSmrg        return winMouseButtonsHandle(s_pScreen, ButtonRelease,
76135c4bbdfSmrg                                     HIWORD(wParam) + 7, wParam);
76205b261ecSmrg
76305b261ecSmrg    case WM_MOUSEWHEEL:
76435c4bbdfSmrg        if (SendMessage
76535c4bbdfSmrg            (hwnd, WM_NCHITTEST, 0,
76635c4bbdfSmrg             MAKELONG(GET_X_LPARAM(lParam),
76735c4bbdfSmrg                      GET_Y_LPARAM(lParam))) == HTCLIENT) {
76835c4bbdfSmrg            /* Pass the message to the root window */
76935c4bbdfSmrg            SendMessage(hwndScreen, message, wParam, lParam);
77035c4bbdfSmrg            return 0;
77135c4bbdfSmrg        }
77235c4bbdfSmrg        else
77335c4bbdfSmrg            break;
77435c4bbdfSmrg
77535c4bbdfSmrg    case WM_MOUSEHWHEEL:
77635c4bbdfSmrg        if (SendMessage
77735c4bbdfSmrg            (hwnd, WM_NCHITTEST, 0,
77835c4bbdfSmrg             MAKELONG(GET_X_LPARAM(lParam),
77935c4bbdfSmrg                      GET_Y_LPARAM(lParam))) == HTCLIENT) {
78035c4bbdfSmrg            /* Pass the message to the root window */
78135c4bbdfSmrg            SendMessage(hwndScreen, message, wParam, lParam);
78235c4bbdfSmrg            return 0;
78335c4bbdfSmrg        }
78435c4bbdfSmrg        else
78535c4bbdfSmrg            break;
78605b261ecSmrg
78705b261ecSmrg    case WM_SETFOCUS:
78835c4bbdfSmrg        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
78935c4bbdfSmrg            break;
79035c4bbdfSmrg
79135c4bbdfSmrg        {
79235c4bbdfSmrg            /* Get the parent window for transient handling */
79335c4bbdfSmrg            HWND hParent = GetParent(hwnd);
79435c4bbdfSmrg
79535c4bbdfSmrg            if (hParent && IsIconic(hParent))
79635c4bbdfSmrg                ShowWindow(hParent, SW_RESTORE);
79735c4bbdfSmrg        }
79835c4bbdfSmrg
79935c4bbdfSmrg        winRestoreModeKeyStates();
80035c4bbdfSmrg
80135c4bbdfSmrg        /* Add the keyboard hook if possible */
80235c4bbdfSmrg        if (g_fKeyboardHookLL)
80335c4bbdfSmrg            g_fKeyboardHookLL = winInstallKeyboardHookLL();
80435c4bbdfSmrg        return 0;
80535c4bbdfSmrg
80605b261ecSmrg    case WM_KILLFOCUS:
80735c4bbdfSmrg        /* Pop any pressed keys since we are losing keyboard focus */
80835c4bbdfSmrg        winKeybdReleaseKeys();
80935c4bbdfSmrg
81035c4bbdfSmrg        /* Remove our keyboard hook if it is installed */
81135c4bbdfSmrg        winRemoveKeyboardHookLL();
81235c4bbdfSmrg
81335c4bbdfSmrg        /* Revert the X focus as well, but only if the Windows focus is going to another window */
81435c4bbdfSmrg        if (!wParam && pWin)
81535c4bbdfSmrg            DeleteWindowFromAnyEvents(pWin, FALSE);
81605b261ecSmrg
81735c4bbdfSmrg        return 0;
81805b261ecSmrg
81935c4bbdfSmrg    case WM_SYSDEADCHAR:
82005b261ecSmrg    case WM_DEADCHAR:
82135c4bbdfSmrg        /*
82235c4bbdfSmrg         * NOTE: We do nothing with WM_*CHAR messages,
82335c4bbdfSmrg         * nor does the root window, so we can just toss these messages.
82435c4bbdfSmrg         */
82535c4bbdfSmrg        return 0;
82605b261ecSmrg
82705b261ecSmrg    case WM_SYSKEYDOWN:
82805b261ecSmrg    case WM_KEYDOWN:
82905b261ecSmrg
83035c4bbdfSmrg        /*
83135c4bbdfSmrg         * Don't pass Alt-F4 key combo to root window,
83235c4bbdfSmrg         * let Windows translate to WM_CLOSE and close this top-level window.
83335c4bbdfSmrg         *
83435c4bbdfSmrg         * NOTE: We purposely don't check the fUseWinKillKey setting because
83535c4bbdfSmrg         * it should only apply to the key handling for the root window,
83635c4bbdfSmrg         * not for top-level window-manager windows.
83735c4bbdfSmrg         *
83835c4bbdfSmrg         * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window
83935c4bbdfSmrg         * because that is a key combo that no X app should be expecting to
84035c4bbdfSmrg         * receive, since it has historically been used to shutdown the X server.
84135c4bbdfSmrg         * Passing Ctrl-Alt-Backspace to the root window preserves that
84235c4bbdfSmrg         * behavior, assuming that -unixkill has been passed as a parameter.
84335c4bbdfSmrg         */
84435c4bbdfSmrg        if (wParam == VK_F4 && (GetKeyState(VK_MENU) & 0x8000))
84535c4bbdfSmrg            break;
84605b261ecSmrg
84705b261ecSmrg#if CYGWINDOWING_DEBUG
84835c4bbdfSmrg        if (wParam == VK_ESCAPE) {
84935c4bbdfSmrg            /* Place for debug: put any tests and dumps here */
85035c4bbdfSmrg            WINDOWPLACEMENT windPlace;
85135c4bbdfSmrg            RECT rc;
85235c4bbdfSmrg            LPRECT pRect;
85335c4bbdfSmrg
85435c4bbdfSmrg            windPlace.length = sizeof(WINDOWPLACEMENT);
85535c4bbdfSmrg            GetWindowPlacement(hwnd, &windPlace);
85635c4bbdfSmrg            pRect = &windPlace.rcNormalPosition;
85735c4bbdfSmrg            ErrorF("\nCYGWINDOWING Dump:\n"
85835c4bbdfSmrg                   "\tdrawable: (%hd, %hd) - %hdx%hd\n", pDraw->x,
85935c4bbdfSmrg                   pDraw->y, pDraw->width, pDraw->height);
86035c4bbdfSmrg            ErrorF("\twindPlace: (%d, %d) - %dx%d\n", (int)pRect->left,
86135c4bbdfSmrg                   (int)pRect->top, (int)(pRect->right - pRect->left),
86235c4bbdfSmrg                   (int)(pRect->bottom - pRect->top));
86335c4bbdfSmrg            if (GetClientRect(hwnd, &rc)) {
86435c4bbdfSmrg                pRect = &rc;
86535c4bbdfSmrg                ErrorF("\tClientRect: (%d, %d) - %dx%d\n", (int)pRect->left,
86635c4bbdfSmrg                       (int)pRect->top, (int)(pRect->right - pRect->left),
86735c4bbdfSmrg                       (int)(pRect->bottom - pRect->top));
86835c4bbdfSmrg            }
86935c4bbdfSmrg            if (GetWindowRect(hwnd, &rc)) {
87035c4bbdfSmrg                pRect = &rc;
87135c4bbdfSmrg                ErrorF("\tWindowRect: (%d, %d) - %dx%d\n", (int)pRect->left,
87235c4bbdfSmrg                       (int)pRect->top, (int)(pRect->right - pRect->left),
87335c4bbdfSmrg                       (int)(pRect->bottom - pRect->top));
87435c4bbdfSmrg            }
87535c4bbdfSmrg            ErrorF("\n");
87635c4bbdfSmrg        }
87705b261ecSmrg#endif
87835c4bbdfSmrg
87935c4bbdfSmrg        /* Pass the message to the root window */
88035c4bbdfSmrg        return winWindowProc(hwndScreen, message, wParam, lParam);
88105b261ecSmrg
88205b261ecSmrg    case WM_SYSKEYUP:
88305b261ecSmrg    case WM_KEYUP:
88405b261ecSmrg
88535c4bbdfSmrg        /* Pass the message to the root window */
88635c4bbdfSmrg        return winWindowProc(hwndScreen, message, wParam, lParam);
88705b261ecSmrg
88805b261ecSmrg    case WM_HOTKEY:
88905b261ecSmrg
89035c4bbdfSmrg        /* Pass the message to the root window */
89135c4bbdfSmrg        SendMessage(hwndScreen, message, wParam, lParam);
89235c4bbdfSmrg        return 0;
89305b261ecSmrg
89405b261ecSmrg    case WM_ACTIVATE:
89505b261ecSmrg
89635c4bbdfSmrg        /* Pass the message to the root window */
89735c4bbdfSmrg        SendMessage(hwndScreen, message, wParam, lParam);
89835c4bbdfSmrg
89935c4bbdfSmrg        if (LOWORD(wParam) != WA_INACTIVE) {
90035c4bbdfSmrg            /* Raise the window to the top in Z order */
90135c4bbdfSmrg            /* ago: Activate does not mean putting it to front! */
90235c4bbdfSmrg            /*
90335c4bbdfSmrg               wmMsg.msg = WM_WM_RAISE;
90435c4bbdfSmrg               if (fWMMsgInitialized)
90535c4bbdfSmrg               winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
90635c4bbdfSmrg             */
90735c4bbdfSmrg
90835c4bbdfSmrg            /* Tell our Window Manager thread to activate the window */
90935c4bbdfSmrg            wmMsg.msg = WM_WM_ACTIVATE;
91035c4bbdfSmrg            if (fWMMsgInitialized)
91135c4bbdfSmrg                if (!pWin || !pWin->overrideRedirect)   /* for OOo menus */
91235c4bbdfSmrg                    winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg);
91335c4bbdfSmrg        }
91435c4bbdfSmrg        /* Prevent the mouse wheel from stalling when another window is minimized */
91535c4bbdfSmrg        if (HIWORD(wParam) == 0 && LOWORD(wParam) == WA_ACTIVE &&
91635c4bbdfSmrg            (HWND) lParam != NULL && (HWND) lParam != GetParent(hwnd))
91735c4bbdfSmrg            SetFocus(hwnd);
91835c4bbdfSmrg        return 0;
91905b261ecSmrg
92005b261ecSmrg    case WM_ACTIVATEAPP:
92135c4bbdfSmrg        /*
92235c4bbdfSmrg         * This message is also sent to the root window
92335c4bbdfSmrg         * so we do nothing for individual multiwindow windows
92435c4bbdfSmrg         */
92535c4bbdfSmrg        break;
92605b261ecSmrg
92705b261ecSmrg    case WM_CLOSE:
92835c4bbdfSmrg        /* Remove AppUserModelID property */
92935c4bbdfSmrg        winSetAppUserModelID(hwnd, NULL);
93035c4bbdfSmrg        /* Branch on if the window was killed in X already */
93135c4bbdfSmrg        if (pWinPriv->fXKilled) {
93235c4bbdfSmrg            /* Window was killed, go ahead and destroy the window */
93335c4bbdfSmrg            DestroyWindow(hwnd);
93435c4bbdfSmrg        }
93535c4bbdfSmrg        else {
93635c4bbdfSmrg            /* Tell our Window Manager thread to kill the window */
93735c4bbdfSmrg            wmMsg.msg = WM_WM_KILL;
93835c4bbdfSmrg            if (fWMMsgInitialized)
93935c4bbdfSmrg                winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg);
94035c4bbdfSmrg        }
94135c4bbdfSmrg        return 0;
94205b261ecSmrg
94305b261ecSmrg    case WM_DESTROY:
94405b261ecSmrg
94535c4bbdfSmrg        /* Branch on if the window was killed in X already */
94635c4bbdfSmrg        if (pWinPriv && !pWinPriv->fXKilled) {
94735c4bbdfSmrg            ErrorF("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n");
94805b261ecSmrg
94935c4bbdfSmrg            /* Tell our Window Manager thread to kill the window */
95035c4bbdfSmrg            wmMsg.msg = WM_WM_KILL;
95135c4bbdfSmrg            if (fWMMsgInitialized)
95235c4bbdfSmrg                winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg);
95335c4bbdfSmrg        }
95435c4bbdfSmrg
95535c4bbdfSmrg        RemoveProp(hwnd, WIN_WINDOW_PROP);
95635c4bbdfSmrg        RemoveProp(hwnd, WIN_WID_PROP);
95735c4bbdfSmrg        RemoveProp(hwnd, WIN_NEEDMANAGE_PROP);
95805b261ecSmrg
95935c4bbdfSmrg        break;
96005b261ecSmrg
96105b261ecSmrg    case WM_MOVE:
96235c4bbdfSmrg        /* Adjust the X Window to the moved Windows window */
96335c4bbdfSmrg        if (!hasEnteredSizeMove)
96435c4bbdfSmrg            winAdjustXWindow(pWin, hwnd);
96535c4bbdfSmrg        /* else: Wait for WM_EXITSIZEMOVE */
96635c4bbdfSmrg        return 0;
96705b261ecSmrg
96805b261ecSmrg    case WM_SHOWWINDOW:
96935c4bbdfSmrg        /* Bail out if the window is being hidden */
97035c4bbdfSmrg        if (!wParam)
97135c4bbdfSmrg            return 0;
97235c4bbdfSmrg
97335c4bbdfSmrg        /* */
97435c4bbdfSmrg        if (!pWin->overrideRedirect) {
97535c4bbdfSmrg            HWND zstyle = HWND_NOTOPMOST;
97635c4bbdfSmrg
97735c4bbdfSmrg            /* Flag that this window needs to be made active when clicked */
97835c4bbdfSmrg            SetProp(hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1);
97935c4bbdfSmrg
98035c4bbdfSmrg            /* Set the transient style flags */
98135c4bbdfSmrg            if (GetParent(hwnd))
98235c4bbdfSmrg                SetWindowLongPtr(hwnd, GWL_STYLE,
98335c4bbdfSmrg                                 WS_POPUP | WS_OVERLAPPED | WS_SYSMENU |
98435c4bbdfSmrg                                 WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
98535c4bbdfSmrg            /* Set the window standard style flags */
98635c4bbdfSmrg            else
98735c4bbdfSmrg                SetWindowLongPtr(hwnd, GWL_STYLE,
98835c4bbdfSmrg                                 (WS_POPUP | WS_OVERLAPPEDWINDOW |
98935c4bbdfSmrg                                  WS_CLIPCHILDREN | WS_CLIPSIBLINGS)
99035c4bbdfSmrg                                 & ~WS_CAPTION & ~WS_SIZEBOX);
99135c4bbdfSmrg
99235c4bbdfSmrg            winUpdateWindowPosition(hwnd, &zstyle);
99335c4bbdfSmrg
99435c4bbdfSmrg            {
99535c4bbdfSmrg                WinXWMHints hints;
99635c4bbdfSmrg
99735c4bbdfSmrg                if (winMultiWindowGetWMHints(pWin, &hints)) {
99835c4bbdfSmrg                    /*
99935c4bbdfSmrg                       Give the window focus, unless it has an InputHint
100035c4bbdfSmrg                       which is FALSE (this is used by e.g. glean to
100135c4bbdfSmrg                       avoid every test window grabbing the focus)
100235c4bbdfSmrg                     */
100335c4bbdfSmrg                    if (!((hints.flags & InputHint) && (!hints.input))) {
100435c4bbdfSmrg                        SetForegroundWindow(hwnd);
100535c4bbdfSmrg                    }
100635c4bbdfSmrg                }
100735c4bbdfSmrg            }
1008ed6184dfSmrg            wmMsg.msg = WM_WM_MAP_MANAGED;
100935c4bbdfSmrg        }
101035c4bbdfSmrg        else {                  /* It is an overridden window so make it top of Z stack */
101135c4bbdfSmrg
101235c4bbdfSmrg            HWND forHwnd = GetForegroundWindow();
101335c4bbdfSmrg
101405b261ecSmrg#if CYGWINDOWING_DEBUG
101535c4bbdfSmrg            ErrorF("overridden window is shown\n");
101605b261ecSmrg#endif
101735c4bbdfSmrg            if (forHwnd != NULL) {
101835c4bbdfSmrg                if (GetWindowLongPtr(forHwnd, GWLP_USERDATA) & (LONG_PTR)
101935c4bbdfSmrg                    XMING_SIGNATURE) {
102035c4bbdfSmrg                    if (GetWindowLongPtr(forHwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)
102135c4bbdfSmrg                        SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0,
102235c4bbdfSmrg                                     SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
102335c4bbdfSmrg                    else
102435c4bbdfSmrg                        SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
102535c4bbdfSmrg                                     SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
102635c4bbdfSmrg                }
102735c4bbdfSmrg            }
1028ed6184dfSmrg            wmMsg.msg = WM_WM_MAP_UNMANAGED;
102935c4bbdfSmrg        }
103035c4bbdfSmrg
103135c4bbdfSmrg        /* Tell our Window Manager thread to map the window */
103235c4bbdfSmrg        if (fWMMsgInitialized)
103335c4bbdfSmrg            winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg);
103435c4bbdfSmrg
103535c4bbdfSmrg        winStartMousePolling(s_pScreenPriv);
103635c4bbdfSmrg
103735c4bbdfSmrg        return 0;
103805b261ecSmrg
103905b261ecSmrg    case WM_SIZING:
104035c4bbdfSmrg        /* Need to legalize the size according to WM_NORMAL_HINTS */
104135c4bbdfSmrg        /* for applications like xterm */
104235c4bbdfSmrg        return ValidateSizing(hwnd, pWin, wParam, lParam);
104305b261ecSmrg
104405b261ecSmrg    case WM_WINDOWPOSCHANGED:
104535c4bbdfSmrg    {
104635c4bbdfSmrg        LPWINDOWPOS pWinPos = (LPWINDOWPOS) lParam;
104705b261ecSmrg
104835c4bbdfSmrg        if (!(pWinPos->flags & SWP_NOZORDER)) {
104905b261ecSmrg#if CYGWINDOWING_DEBUG
105035c4bbdfSmrg            winDebug("\twindow z order was changed\n");
105105b261ecSmrg#endif
105235c4bbdfSmrg            if (pWinPos->hwndInsertAfter == HWND_TOP
105335c4bbdfSmrg                || pWinPos->hwndInsertAfter == HWND_TOPMOST
105435c4bbdfSmrg                || pWinPos->hwndInsertAfter == HWND_NOTOPMOST) {
105505b261ecSmrg#if CYGWINDOWING_DEBUG
105635c4bbdfSmrg                winDebug("\traise to top\n");
105705b261ecSmrg#endif
105835c4bbdfSmrg                /* Raise the window to the top in Z order */
105935c4bbdfSmrg                winRaiseWindow(pWin);
106035c4bbdfSmrg            }
106135c4bbdfSmrg            else if (pWinPos->hwndInsertAfter == HWND_BOTTOM) {
106235c4bbdfSmrg            }
106335c4bbdfSmrg            else {
106435c4bbdfSmrg                /* Check if this window is top of X windows. */
106535c4bbdfSmrg                HWND hWndAbove = NULL;
106635c4bbdfSmrg                DWORD dwCurrentProcessID = GetCurrentProcessId();
106735c4bbdfSmrg                DWORD dwWindowProcessID = 0;
106835c4bbdfSmrg
106935c4bbdfSmrg                for (hWndAbove = pWinPos->hwndInsertAfter;
107035c4bbdfSmrg                     hWndAbove != NULL;
107135c4bbdfSmrg                     hWndAbove = GetNextWindow(hWndAbove, GW_HWNDPREV)) {
107235c4bbdfSmrg                    /* Ignore other XWin process's window */
107335c4bbdfSmrg                    GetWindowThreadProcessId(hWndAbove, &dwWindowProcessID);
107435c4bbdfSmrg
107535c4bbdfSmrg                    if ((dwWindowProcessID == dwCurrentProcessID)
107635c4bbdfSmrg                        && GetProp(hWndAbove, WIN_WINDOW_PROP)
107735c4bbdfSmrg                        && !IsWindowVisible(hWndAbove)
107835c4bbdfSmrg                        && !IsIconic(hWndAbove))        /* ignore minimized windows */
107935c4bbdfSmrg                        break;
108035c4bbdfSmrg                }
108135c4bbdfSmrg                /* If this is top of X windows in Windows stack,
108235c4bbdfSmrg                   raise it in X stack. */
108335c4bbdfSmrg                if (hWndAbove == NULL) {
108405b261ecSmrg#if CYGWINDOWING_DEBUG
108535c4bbdfSmrg                    winDebug("\traise to top\n");
108605b261ecSmrg#endif
108735c4bbdfSmrg                    winRaiseWindow(pWin);
108835c4bbdfSmrg                }
108935c4bbdfSmrg            }
109035c4bbdfSmrg        }
109135c4bbdfSmrg    }
109235c4bbdfSmrg        /*
109335c4bbdfSmrg         * Pass the message to DefWindowProc to let the function
109435c4bbdfSmrg         * break down WM_WINDOWPOSCHANGED to WM_MOVE and WM_SIZE.
109535c4bbdfSmrg         */
109635c4bbdfSmrg        break;
109735c4bbdfSmrg
109835c4bbdfSmrg    case WM_ENTERSIZEMOVE:
109935c4bbdfSmrg        hasEnteredSizeMove = TRUE;
110035c4bbdfSmrg        return 0;
110135c4bbdfSmrg
110235c4bbdfSmrg    case WM_EXITSIZEMOVE:
110335c4bbdfSmrg        /* Adjust the X Window to the moved Windows window */
110435c4bbdfSmrg        hasEnteredSizeMove = FALSE;
110535c4bbdfSmrg        winAdjustXWindow(pWin, hwnd);
110635c4bbdfSmrg        return 0;
110705b261ecSmrg
110805b261ecSmrg    case WM_SIZE:
110935c4bbdfSmrg        /* see dix/window.c */
111005b261ecSmrg#if CYGWINDOWING_DEBUG
111135c4bbdfSmrg    {
111235c4bbdfSmrg        char buf[64];
111335c4bbdfSmrg
111435c4bbdfSmrg        switch (wParam) {
111535c4bbdfSmrg        case SIZE_MINIMIZED:
111635c4bbdfSmrg            strcpy(buf, "SIZE_MINIMIZED");
111735c4bbdfSmrg            break;
111835c4bbdfSmrg        case SIZE_MAXIMIZED:
111935c4bbdfSmrg            strcpy(buf, "SIZE_MAXIMIZED");
112035c4bbdfSmrg            break;
112135c4bbdfSmrg        case SIZE_RESTORED:
112235c4bbdfSmrg            strcpy(buf, "SIZE_RESTORED");
112335c4bbdfSmrg            break;
112435c4bbdfSmrg        default:
112535c4bbdfSmrg            strcpy(buf, "UNKNOWN_FLAG");
112635c4bbdfSmrg        }
112735c4bbdfSmrg        ErrorF("winTopLevelWindowProc - WM_SIZE to %dx%d (%s)\n",
112835c4bbdfSmrg               (int) LOWORD(lParam), (int) HIWORD(lParam), buf);
112935c4bbdfSmrg    }
113005b261ecSmrg#endif
113135c4bbdfSmrg        if (!hasEnteredSizeMove) {
113235c4bbdfSmrg            /* Adjust the X Window to the moved Windows window */
113335c4bbdfSmrg            winAdjustXWindow(pWin, hwnd);
113435c4bbdfSmrg        }
113535c4bbdfSmrg        /* else: wait for WM_EXITSIZEMOVE */
113635c4bbdfSmrg        return 0;               /* end of WM_SIZE handler */
113735c4bbdfSmrg
113835c4bbdfSmrg    case WM_STYLECHANGING:
113935c4bbdfSmrg        /*
114035c4bbdfSmrg           When the style changes, adjust the Windows window size so the client area remains the same size,
114135c4bbdfSmrg           and adjust the Windows window position so that the client area remains in the same place.
114235c4bbdfSmrg         */
114335c4bbdfSmrg    {
114435c4bbdfSmrg        RECT newWinRect;
114535c4bbdfSmrg        DWORD dwExStyle;
114635c4bbdfSmrg        DWORD dwStyle;
114735c4bbdfSmrg        DWORD newStyle = ((STYLESTRUCT *) lParam)->styleNew;
114835c4bbdfSmrg        WINDOWINFO wi;
114935c4bbdfSmrg
115035c4bbdfSmrg        dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
115135c4bbdfSmrg        dwStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
115235c4bbdfSmrg
115335c4bbdfSmrg        winDebug("winTopLevelWindowProc - WM_STYLECHANGING from %08x %08x\n",
115435c4bbdfSmrg                 (unsigned int)dwStyle, (unsigned int)dwExStyle);
115535c4bbdfSmrg
115635c4bbdfSmrg        if (wParam == GWL_EXSTYLE)
115735c4bbdfSmrg            dwExStyle = newStyle;
115835c4bbdfSmrg
115935c4bbdfSmrg        if (wParam == GWL_STYLE)
116035c4bbdfSmrg            dwStyle = newStyle;
116135c4bbdfSmrg
116235c4bbdfSmrg        winDebug("winTopLevelWindowProc - WM_STYLECHANGING to %08x %08x\n",
116335c4bbdfSmrg                 (unsigned int)dwStyle, (unsigned int)dwExStyle);
116435c4bbdfSmrg
116535c4bbdfSmrg        /* Get client rect in screen coordinates */
116635c4bbdfSmrg        wi.cbSize = sizeof(WINDOWINFO);
116735c4bbdfSmrg        GetWindowInfo(hwnd, &wi);
116835c4bbdfSmrg
116935c4bbdfSmrg        winDebug
117035c4bbdfSmrg            ("winTopLevelWindowProc - WM_STYLECHANGING client area {%d, %d, %d, %d}, {%d x %d}\n",
117135c4bbdfSmrg             (int)wi.rcClient.left, (int)wi.rcClient.top, (int)wi.rcClient.right,
117235c4bbdfSmrg             (int)wi.rcClient.bottom, (int)(wi.rcClient.right - wi.rcClient.left),
117335c4bbdfSmrg             (int)(wi.rcClient.bottom - wi.rcClient.top));
117435c4bbdfSmrg
117535c4bbdfSmrg        newWinRect = wi.rcClient;
117635c4bbdfSmrg        if (!AdjustWindowRectEx(&newWinRect, dwStyle, FALSE, dwExStyle))
117735c4bbdfSmrg            winDebug
117835c4bbdfSmrg                ("winTopLevelWindowProc - WM_STYLECHANGING AdjustWindowRectEx failed\n");
117935c4bbdfSmrg
118035c4bbdfSmrg        winDebug
118135c4bbdfSmrg            ("winTopLevelWindowProc - WM_STYLECHANGING window area should be {%d, %d, %d, %d}, {%d x %d}\n",
118235c4bbdfSmrg             (int)newWinRect.left, (int)newWinRect.top, (int)newWinRect.right,
118335c4bbdfSmrg             (int)newWinRect.bottom, (int)(newWinRect.right - newWinRect.left),
118435c4bbdfSmrg             (int)(newWinRect.bottom - newWinRect.top));
118535c4bbdfSmrg
118635c4bbdfSmrg        /*
118735c4bbdfSmrg           Style change hasn't happened yet, so we can't adjust the window size yet, as the winAdjustXWindow()
118835c4bbdfSmrg           which WM_SIZE does will use the current (unchanged) style.  Instead make a note to change it when
118935c4bbdfSmrg           WM_STYLECHANGED is received...
119035c4bbdfSmrg         */
119135c4bbdfSmrg        pWinPriv->hDwp = BeginDeferWindowPos(1);
119235c4bbdfSmrg        pWinPriv->hDwp =
119335c4bbdfSmrg            DeferWindowPos(pWinPriv->hDwp, hwnd, NULL, newWinRect.left,
119435c4bbdfSmrg                           newWinRect.top, newWinRect.right - newWinRect.left,
119535c4bbdfSmrg                           newWinRect.bottom - newWinRect.top,
119635c4bbdfSmrg                           SWP_NOACTIVATE | SWP_NOZORDER);
119735c4bbdfSmrg    }
119835c4bbdfSmrg        return 0;
119935c4bbdfSmrg
120035c4bbdfSmrg    case WM_STYLECHANGED:
120135c4bbdfSmrg    {
120235c4bbdfSmrg        if (pWinPriv->hDwp) {
120335c4bbdfSmrg            EndDeferWindowPos(pWinPriv->hDwp);
120435c4bbdfSmrg            pWinPriv->hDwp = NULL;
120535c4bbdfSmrg        }
120635c4bbdfSmrg        winDebug("winTopLevelWindowProc - WM_STYLECHANGED done\n");
120735c4bbdfSmrg    }
120835c4bbdfSmrg        return 0;
120905b261ecSmrg
121005b261ecSmrg    case WM_MOUSEACTIVATE:
121105b261ecSmrg
121235c4bbdfSmrg        /* Check if this window needs to be made active when clicked */
121335c4bbdfSmrg        if (!GetProp(pWinPriv->hWnd, WIN_NEEDMANAGE_PROP)) {
121405b261ecSmrg#if CYGMULTIWINDOW_DEBUG
121535c4bbdfSmrg            ErrorF("winTopLevelWindowProc - WM_MOUSEACTIVATE - "
121635c4bbdfSmrg                   "MA_NOACTIVATE\n");
121705b261ecSmrg#endif
121805b261ecSmrg
121935c4bbdfSmrg            /* */
122035c4bbdfSmrg            return MA_NOACTIVATE;
122135c4bbdfSmrg        }
122235c4bbdfSmrg        break;
122305b261ecSmrg
122405b261ecSmrg    case WM_SETCURSOR:
122535c4bbdfSmrg        if (LOWORD(lParam) == HTCLIENT) {
122635c4bbdfSmrg            if (!g_fSoftwareCursor)
122735c4bbdfSmrg                SetCursor(s_pScreenPriv->cursor.handle);
122835c4bbdfSmrg            return TRUE;
122935c4bbdfSmrg        }
123035c4bbdfSmrg        break;
123105b261ecSmrg
1232ed6184dfSmrg
1233ed6184dfSmrg    case WM_DWMCOMPOSITIONCHANGED:
1234ed6184dfSmrg        /* This message is only sent on Vista/W7 */
1235ed6184dfSmrg        CheckForAlpha(hwnd, pWin, s_pScreenInfo);
1236ed6184dfSmrg
1237ed6184dfSmrg        return 0;
123805b261ecSmrg    default:
123935c4bbdfSmrg        break;
124005b261ecSmrg    }
124105b261ecSmrg
124235c4bbdfSmrg    ret = DefWindowProc(hwnd, message, wParam, lParam);
124335c4bbdfSmrg    /*
124435c4bbdfSmrg     * If the window was minized we get the stack change before the window is restored
124535c4bbdfSmrg     * and so it gets lost. Ensure there stacking order is correct.
124635c4bbdfSmrg     */
124735c4bbdfSmrg    if (needRestack)
124835c4bbdfSmrg        winReorderWindowsMultiWindow();
124935c4bbdfSmrg    return ret;
125005b261ecSmrg}
1251