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