winmultiwindowwndproc.c revision 35c4bbdf
105b261ecSmrg/* 205b261ecSmrg *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 36747b715Smrg *Copyright (C) Colin Harrison 2005-2008 405b261ecSmrg * 505b261ecSmrg *Permission is hereby granted, free of charge, to any person obtaining 605b261ecSmrg * a copy of this software and associated documentation files (the 705b261ecSmrg *"Software"), to deal in the Software without restriction, including 805b261ecSmrg *without limitation the rights to use, copy, modify, merge, publish, 905b261ecSmrg *distribute, sublicense, and/or sell copies of the Software, and to 1005b261ecSmrg *permit persons to whom the Software is furnished to do so, subject to 1105b261ecSmrg *the following conditions: 1205b261ecSmrg * 1305b261ecSmrg *The above copyright notice and this permission notice shall be 1405b261ecSmrg *included in all copies or substantial portions of the Software. 1505b261ecSmrg * 1605b261ecSmrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1705b261ecSmrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1805b261ecSmrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1905b261ecSmrg *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR 2005b261ecSmrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 2105b261ecSmrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 2205b261ecSmrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2305b261ecSmrg * 2405b261ecSmrg *Except as contained in this notice, the name of the XFree86 Project 2505b261ecSmrg *shall not be used in advertising or otherwise to promote the sale, use 2605b261ecSmrg *or other dealings in this Software without prior written authorization 2705b261ecSmrg *from the XFree86 Project. 2805b261ecSmrg * 2905b261ecSmrg * Authors: Kensuke Matsuzaki 3005b261ecSmrg * Earle F. Philhower, III 3105b261ecSmrg * Harold L Hunt II 326747b715Smrg * Colin Harrison 3305b261ecSmrg */ 3405b261ecSmrg 3505b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H 3605b261ecSmrg#include <xwin-config.h> 3705b261ecSmrg#endif 3805b261ecSmrg#include "win.h" 3905b261ecSmrg#include "dixevents.h" 4005b261ecSmrg#include "winmultiwindowclass.h" 4105b261ecSmrg#include "winprefs.h" 4205b261ecSmrg#include "winmsg.h" 4305b261ecSmrg#include "inputstr.h" 4405b261ecSmrg 4535c4bbdfSmrgextern void winUpdateWindowPosition(HWND hWnd, HWND * zstyle); 4605b261ecSmrg 4705b261ecSmrg/* 4805b261ecSmrg * Local globals 4905b261ecSmrg */ 5005b261ecSmrg 5135c4bbdfSmrgstatic UINT_PTR g_uipMousePollingTimerID = 0; 5205b261ecSmrg 5305b261ecSmrg/* 5405b261ecSmrg * Constant defines 5505b261ecSmrg */ 5605b261ecSmrg 5705b261ecSmrg#define WIN_MULTIWINDOW_SHAPE YES 5805b261ecSmrg 5905b261ecSmrg/* 6005b261ecSmrg * ConstrainSize - Taken from TWM sources - Respects hints for sizing 6105b261ecSmrg */ 6205b261ecSmrg#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) ) 6305b261ecSmrgstatic void 6435c4bbdfSmrgConstrainSize(WinXSizeHints hints, int *widthp, int *heightp) 6505b261ecSmrg{ 6635c4bbdfSmrg int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta; 6735c4bbdfSmrg int baseWidth, baseHeight; 6835c4bbdfSmrg int dwidth = *widthp, dheight = *heightp; 6935c4bbdfSmrg 7035c4bbdfSmrg if (hints.flags & PMinSize) { 7135c4bbdfSmrg minWidth = hints.min_width; 7235c4bbdfSmrg minHeight = hints.min_height; 7305b261ecSmrg } 7435c4bbdfSmrg else if (hints.flags & PBaseSize) { 7535c4bbdfSmrg minWidth = hints.base_width; 7635c4bbdfSmrg minHeight = hints.base_height; 7705b261ecSmrg } 7835c4bbdfSmrg else 7935c4bbdfSmrg minWidth = minHeight = 1; 8035c4bbdfSmrg 8135c4bbdfSmrg if (hints.flags & PBaseSize) { 8235c4bbdfSmrg baseWidth = hints.base_width; 8335c4bbdfSmrg baseHeight = hints.base_height; 8405b261ecSmrg } 8535c4bbdfSmrg else if (hints.flags & PMinSize) { 8635c4bbdfSmrg baseWidth = hints.min_width; 8735c4bbdfSmrg baseHeight = hints.min_height; 8835c4bbdfSmrg } 8935c4bbdfSmrg else 9035c4bbdfSmrg baseWidth = baseHeight = 0; 9105b261ecSmrg 9235c4bbdfSmrg if (hints.flags & PMaxSize) { 9335c4bbdfSmrg maxWidth = hints.max_width; 9435c4bbdfSmrg maxHeight = hints.max_height; 9505b261ecSmrg } 9635c4bbdfSmrg else { 9735c4bbdfSmrg maxWidth = MAXINT; 9835c4bbdfSmrg maxHeight = MAXINT; 9905b261ecSmrg } 10005b261ecSmrg 10135c4bbdfSmrg if (hints.flags & PResizeInc) { 10235c4bbdfSmrg xinc = hints.width_inc; 10335c4bbdfSmrg yinc = hints.height_inc; 10405b261ecSmrg } 10535c4bbdfSmrg else 10635c4bbdfSmrg xinc = yinc = 1; 10735c4bbdfSmrg 10835c4bbdfSmrg /* 10935c4bbdfSmrg * First, clamp to min and max values 11035c4bbdfSmrg */ 11135c4bbdfSmrg if (dwidth < minWidth) 11235c4bbdfSmrg dwidth = minWidth; 11335c4bbdfSmrg if (dheight < minHeight) 11435c4bbdfSmrg dheight = minHeight; 11535c4bbdfSmrg 11635c4bbdfSmrg if (dwidth > maxWidth) 11735c4bbdfSmrg dwidth = maxWidth; 11835c4bbdfSmrg if (dheight > maxHeight) 11935c4bbdfSmrg dheight = maxHeight; 12035c4bbdfSmrg 12135c4bbdfSmrg /* 12235c4bbdfSmrg * Second, fit to base + N * inc 12335c4bbdfSmrg */ 12435c4bbdfSmrg dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth; 12535c4bbdfSmrg dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight; 12635c4bbdfSmrg 12735c4bbdfSmrg /* 12835c4bbdfSmrg * Third, adjust for aspect ratio 12935c4bbdfSmrg */ 13035c4bbdfSmrg 13135c4bbdfSmrg /* 13235c4bbdfSmrg * The math looks like this: 13335c4bbdfSmrg * 13435c4bbdfSmrg * minAspectX dwidth maxAspectX 13535c4bbdfSmrg * ---------- <= ------- <= ---------- 13635c4bbdfSmrg * minAspectY dheight maxAspectY 13735c4bbdfSmrg * 13835c4bbdfSmrg * If that is multiplied out, then the width and height are 13935c4bbdfSmrg * invalid in the following situations: 14035c4bbdfSmrg * 14135c4bbdfSmrg * minAspectX * dheight > minAspectY * dwidth 14235c4bbdfSmrg * maxAspectX * dheight < maxAspectY * dwidth 14335c4bbdfSmrg * 14435c4bbdfSmrg */ 14535c4bbdfSmrg 14635c4bbdfSmrg if (hints.flags & PAspect) { 14735c4bbdfSmrg if (hints.min_aspect.x * dheight > hints.min_aspect.y * dwidth) { 14835c4bbdfSmrg delta = 14935c4bbdfSmrg makemult(hints.min_aspect.x * dheight / hints.min_aspect.y - 15035c4bbdfSmrg dwidth, xinc); 15135c4bbdfSmrg if (dwidth + delta <= maxWidth) 15235c4bbdfSmrg dwidth += delta; 15335c4bbdfSmrg else { 15435c4bbdfSmrg delta = 15535c4bbdfSmrg makemult(dheight - 15635c4bbdfSmrg dwidth * hints.min_aspect.y / hints.min_aspect.x, 15735c4bbdfSmrg yinc); 15835c4bbdfSmrg if (dheight - delta >= minHeight) 15935c4bbdfSmrg dheight -= delta; 16005b261ecSmrg } 16105b261ecSmrg } 16235c4bbdfSmrg 16335c4bbdfSmrg if (hints.max_aspect.x * dheight < hints.max_aspect.y * dwidth) { 16435c4bbdfSmrg delta = 16535c4bbdfSmrg makemult(dwidth * hints.max_aspect.y / hints.max_aspect.x - 16635c4bbdfSmrg dheight, yinc); 16735c4bbdfSmrg if (dheight + delta <= maxHeight) 16835c4bbdfSmrg dheight += delta; 16935c4bbdfSmrg else { 17035c4bbdfSmrg delta = 17135c4bbdfSmrg makemult(dwidth - 17235c4bbdfSmrg hints.max_aspect.x * dheight / hints.max_aspect.y, 17335c4bbdfSmrg xinc); 17435c4bbdfSmrg if (dwidth - delta >= minWidth) 17535c4bbdfSmrg dwidth -= delta; 17605b261ecSmrg } 17705b261ecSmrg } 17805b261ecSmrg } 17905b261ecSmrg 18035c4bbdfSmrg /* Return computed values */ 18135c4bbdfSmrg *widthp = dwidth; 18235c4bbdfSmrg *heightp = dheight; 18335c4bbdfSmrg} 18405b261ecSmrg 18535c4bbdfSmrg#undef makemult 18605b261ecSmrg 18705b261ecSmrg/* 18805b261ecSmrg * ValidateSizing - Ensures size request respects hints 18905b261ecSmrg */ 19005b261ecSmrgstatic int 19135c4bbdfSmrgValidateSizing(HWND hwnd, WindowPtr pWin, WPARAM wParam, LPARAM lParam) 19205b261ecSmrg{ 19335c4bbdfSmrg WinXSizeHints sizeHints; 19435c4bbdfSmrg RECT *rect; 19535c4bbdfSmrg int iWidth, iHeight; 19635c4bbdfSmrg RECT rcClient, rcWindow; 19735c4bbdfSmrg int iBorderWidthX, iBorderWidthY; 19835c4bbdfSmrg 19935c4bbdfSmrg /* Invalid input checking */ 20035c4bbdfSmrg if (pWin == NULL || lParam == 0) 20135c4bbdfSmrg return FALSE; 20235c4bbdfSmrg 20335c4bbdfSmrg /* No size hints, no checking */ 20435c4bbdfSmrg if (!winMultiWindowGetWMNormalHints(pWin, &sizeHints)) 20535c4bbdfSmrg return FALSE; 20635c4bbdfSmrg 20735c4bbdfSmrg /* Avoid divide-by-zero */ 20835c4bbdfSmrg if (sizeHints.flags & PResizeInc) { 20935c4bbdfSmrg if (sizeHints.width_inc == 0) 21035c4bbdfSmrg sizeHints.width_inc = 1; 21135c4bbdfSmrg if (sizeHints.height_inc == 0) 21235c4bbdfSmrg sizeHints.height_inc = 1; 21305b261ecSmrg } 21435c4bbdfSmrg 21535c4bbdfSmrg rect = (RECT *) lParam; 21635c4bbdfSmrg 21735c4bbdfSmrg iWidth = rect->right - rect->left; 21835c4bbdfSmrg iHeight = rect->bottom - rect->top; 21935c4bbdfSmrg 22035c4bbdfSmrg /* Now remove size of any borders and title bar */ 22135c4bbdfSmrg GetClientRect(hwnd, &rcClient); 22235c4bbdfSmrg GetWindowRect(hwnd, &rcWindow); 22335c4bbdfSmrg iBorderWidthX = 22435c4bbdfSmrg (rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left); 22535c4bbdfSmrg iBorderWidthY = 22635c4bbdfSmrg (rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top); 22735c4bbdfSmrg iWidth -= iBorderWidthX; 22835c4bbdfSmrg iHeight -= iBorderWidthY; 22935c4bbdfSmrg 23035c4bbdfSmrg /* Constrain the size to legal values */ 23135c4bbdfSmrg ConstrainSize(sizeHints, &iWidth, &iHeight); 23235c4bbdfSmrg 23335c4bbdfSmrg /* Add back the size of borders and title bar */ 23435c4bbdfSmrg iWidth += iBorderWidthX; 23535c4bbdfSmrg iHeight += iBorderWidthY; 23635c4bbdfSmrg 23735c4bbdfSmrg /* Adjust size according to where we're dragging from */ 23835c4bbdfSmrg switch (wParam) { 23935c4bbdfSmrg case WMSZ_TOP: 24035c4bbdfSmrg case WMSZ_TOPRIGHT: 24135c4bbdfSmrg case WMSZ_BOTTOM: 24235c4bbdfSmrg case WMSZ_BOTTOMRIGHT: 24335c4bbdfSmrg case WMSZ_RIGHT: 24435c4bbdfSmrg rect->right = rect->left + iWidth; 24535c4bbdfSmrg break; 24635c4bbdfSmrg default: 24735c4bbdfSmrg rect->left = rect->right - iWidth; 24835c4bbdfSmrg break; 24935c4bbdfSmrg } 25035c4bbdfSmrg switch (wParam) { 25135c4bbdfSmrg case WMSZ_BOTTOM: 25235c4bbdfSmrg case WMSZ_BOTTOMRIGHT: 25335c4bbdfSmrg case WMSZ_BOTTOMLEFT: 25435c4bbdfSmrg case WMSZ_RIGHT: 25535c4bbdfSmrg case WMSZ_LEFT: 25635c4bbdfSmrg rect->bottom = rect->top + iHeight; 25735c4bbdfSmrg break; 25835c4bbdfSmrg default: 25935c4bbdfSmrg rect->top = rect->bottom - iHeight; 26035c4bbdfSmrg break; 26135c4bbdfSmrg } 26235c4bbdfSmrg return TRUE; 26305b261ecSmrg} 26405b261ecSmrg 26505b261ecSmrgextern Bool winInDestroyWindowsWindow; 26605b261ecSmrgstatic Bool winInRaiseWindow = FALSE; 26735c4bbdfSmrgstatic void 26835c4bbdfSmrgwinRaiseWindow(WindowPtr pWin) 26905b261ecSmrg{ 27035c4bbdfSmrg if (!winInDestroyWindowsWindow && !winInRaiseWindow) { 27135c4bbdfSmrg BOOL oldstate = winInRaiseWindow; 27235c4bbdfSmrg XID vlist[1] = { 0 }; 27335c4bbdfSmrg winInRaiseWindow = TRUE; 27435c4bbdfSmrg /* Call configure window directly to make sure it gets processed 27535c4bbdfSmrg * in time 27635c4bbdfSmrg */ 27735c4bbdfSmrg ConfigureWindow(pWin, CWStackMode, vlist, serverClient); 27835c4bbdfSmrg winInRaiseWindow = oldstate; 27935c4bbdfSmrg } 28005b261ecSmrg} 28105b261ecSmrg 2826747b715Smrgstatic 28335c4bbdfSmrg void 28435c4bbdfSmrgwinStartMousePolling(winPrivScreenPtr s_pScreenPriv) 2856747b715Smrg{ 28635c4bbdfSmrg /* 28735c4bbdfSmrg * Timer to poll mouse position. This is needed to make 28835c4bbdfSmrg * programs like xeyes follow the mouse properly when the 28935c4bbdfSmrg * mouse pointer is outside of any X window. 29035c4bbdfSmrg */ 29135c4bbdfSmrg if (g_uipMousePollingTimerID == 0) 29235c4bbdfSmrg g_uipMousePollingTimerID = SetTimer(s_pScreenPriv->hwndScreen, 29335c4bbdfSmrg WIN_POLLING_MOUSE_TIMER_ID, 29435c4bbdfSmrg MOUSE_POLLING_INTERVAL, NULL); 2956747b715Smrg} 29605b261ecSmrg 29705b261ecSmrg/* 29805b261ecSmrg * winTopLevelWindowProc - Window procedure for all top-level Windows windows. 29905b261ecSmrg */ 30005b261ecSmrg 30105b261ecSmrgLRESULT CALLBACK 30235c4bbdfSmrgwinTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 30305b261ecSmrg{ 30435c4bbdfSmrg POINT ptMouse; 30535c4bbdfSmrg HDC hdcUpdate; 30635c4bbdfSmrg PAINTSTRUCT ps; 30735c4bbdfSmrg WindowPtr pWin = NULL; 30835c4bbdfSmrg winPrivWinPtr pWinPriv = NULL; 30935c4bbdfSmrg ScreenPtr s_pScreen = NULL; 31035c4bbdfSmrg winPrivScreenPtr s_pScreenPriv = NULL; 31135c4bbdfSmrg winScreenInfo *s_pScreenInfo = NULL; 31235c4bbdfSmrg HWND hwndScreen = NULL; 31335c4bbdfSmrg DrawablePtr pDraw = NULL; 31435c4bbdfSmrg winWMMessageRec wmMsg; 31535c4bbdfSmrg Bool fWMMsgInitialized = FALSE; 31635c4bbdfSmrg static Bool s_fTracking = FALSE; 31735c4bbdfSmrg Bool needRestack = FALSE; 31835c4bbdfSmrg LRESULT ret; 31935c4bbdfSmrg static Bool hasEnteredSizeMove = FALSE; 32005b261ecSmrg 32105b261ecSmrg#if CYGDEBUG 32235c4bbdfSmrg winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam, 32335c4bbdfSmrg lParam); 32405b261ecSmrg#endif 32505b261ecSmrg 32635c4bbdfSmrg /* Check if the Windows window property for our X window pointer is valid */ 32735c4bbdfSmrg if ((pWin = GetProp(hwnd, WIN_WINDOW_PROP)) != NULL) { 32835c4bbdfSmrg /* Our X window pointer is valid */ 32935c4bbdfSmrg 33035c4bbdfSmrg /* Get pointers to the drawable and the screen */ 33135c4bbdfSmrg pDraw = &pWin->drawable; 33235c4bbdfSmrg s_pScreen = pWin->drawable.pScreen; 33305b261ecSmrg 33435c4bbdfSmrg /* Get a pointer to our window privates */ 33535c4bbdfSmrg pWinPriv = winGetWindowPriv(pWin); 33605b261ecSmrg 33735c4bbdfSmrg /* Get pointers to our screen privates and screen info */ 33835c4bbdfSmrg s_pScreenPriv = pWinPriv->pScreenPriv; 33935c4bbdfSmrg s_pScreenInfo = s_pScreenPriv->pScreenInfo; 34005b261ecSmrg 34135c4bbdfSmrg /* Get the handle for our screen-sized window */ 34235c4bbdfSmrg hwndScreen = s_pScreenPriv->hwndScreen; 34305b261ecSmrg 34435c4bbdfSmrg /* */ 34535c4bbdfSmrg wmMsg.msg = 0; 34635c4bbdfSmrg wmMsg.hwndWindow = hwnd; 34735c4bbdfSmrg wmMsg.iWindow = (Window) (INT_PTR) GetProp(hwnd, WIN_WID_PROP); 34805b261ecSmrg 34935c4bbdfSmrg wmMsg.iX = pDraw->x; 35035c4bbdfSmrg wmMsg.iY = pDraw->y; 35135c4bbdfSmrg wmMsg.iWidth = pDraw->width; 35235c4bbdfSmrg wmMsg.iHeight = pDraw->height; 35305b261ecSmrg 35435c4bbdfSmrg fWMMsgInitialized = TRUE; 35505b261ecSmrg 35605b261ecSmrg#if 0 35735c4bbdfSmrg /* 35835c4bbdfSmrg * Print some debugging information 35935c4bbdfSmrg */ 36035c4bbdfSmrg 36135c4bbdfSmrg ErrorF("hWnd %08X\n", hwnd); 36235c4bbdfSmrg ErrorF("pWin %08X\n", pWin); 36335c4bbdfSmrg ErrorF("pDraw %08X\n", pDraw); 36435c4bbdfSmrg ErrorF("\ttype %08X\n", pWin->drawable.type); 36535c4bbdfSmrg ErrorF("\tclass %08X\n", pWin->drawable.class); 36635c4bbdfSmrg ErrorF("\tdepth %08X\n", pWin->drawable.depth); 36735c4bbdfSmrg ErrorF("\tbitsPerPixel %08X\n", pWin->drawable.bitsPerPixel); 36835c4bbdfSmrg ErrorF("\tid %08X\n", pWin->drawable.id); 36935c4bbdfSmrg ErrorF("\tx %08X\n", pWin->drawable.x); 37035c4bbdfSmrg ErrorF("\ty %08X\n", pWin->drawable.y); 37135c4bbdfSmrg ErrorF("\twidth %08X\n", pWin->drawable.width); 37235c4bbdfSmrg ErrorF("\thenght %08X\n", pWin->drawable.height); 37335c4bbdfSmrg ErrorF("\tpScreen %08X\n", pWin->drawable.pScreen); 37435c4bbdfSmrg ErrorF("\tserialNumber %08X\n", pWin->drawable.serialNumber); 37535c4bbdfSmrg ErrorF("g_iWindowPrivateKey %p\n", g_iWindowPrivateKey); 37635c4bbdfSmrg ErrorF("pWinPriv %08X\n", pWinPriv); 37735c4bbdfSmrg ErrorF("s_pScreenPriv %08X\n", s_pScreenPriv); 37835c4bbdfSmrg ErrorF("s_pScreenInfo %08X\n", s_pScreenInfo); 37935c4bbdfSmrg ErrorF("hwndScreen %08X\n", hwndScreen); 38005b261ecSmrg#endif 38105b261ecSmrg } 38205b261ecSmrg 38335c4bbdfSmrg /* Branch on message type */ 38435c4bbdfSmrg switch (message) { 38505b261ecSmrg case WM_CREATE: 38605b261ecSmrg 38735c4bbdfSmrg /* */ 38835c4bbdfSmrg SetProp(hwnd, 38935c4bbdfSmrg WIN_WINDOW_PROP, 39035c4bbdfSmrg (HANDLE) ((LPCREATESTRUCT) lParam)->lpCreateParams); 39135c4bbdfSmrg 39235c4bbdfSmrg /* */ 39335c4bbdfSmrg SetProp(hwnd, 39435c4bbdfSmrg WIN_WID_PROP, 39535c4bbdfSmrg (HANDLE) (INT_PTR) winGetWindowID(((LPCREATESTRUCT) lParam)-> 39635c4bbdfSmrg lpCreateParams)); 39735c4bbdfSmrg 39835c4bbdfSmrg /* 39935c4bbdfSmrg * Make X windows' Z orders sync with Windows windows because 40035c4bbdfSmrg * there can be AlwaysOnTop windows overlapped on the window 40135c4bbdfSmrg * currently being created. 40235c4bbdfSmrg */ 40335c4bbdfSmrg winReorderWindowsMultiWindow(); 40435c4bbdfSmrg 40535c4bbdfSmrg /* Fix a 'round title bar corner background should be transparent not black' problem when first painted */ 40635c4bbdfSmrg { 40735c4bbdfSmrg RECT rWindow; 40835c4bbdfSmrg HRGN hRgnWindow; 40935c4bbdfSmrg 41035c4bbdfSmrg GetWindowRect(hwnd, &rWindow); 41135c4bbdfSmrg hRgnWindow = CreateRectRgnIndirect(&rWindow); 41235c4bbdfSmrg SetWindowRgn(hwnd, hRgnWindow, TRUE); 41335c4bbdfSmrg DeleteObject(hRgnWindow); 41435c4bbdfSmrg } 41535c4bbdfSmrg 41635c4bbdfSmrg SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) XMING_SIGNATURE); 41735c4bbdfSmrg 41835c4bbdfSmrg return 0; 41905b261ecSmrg 42005b261ecSmrg case WM_INIT_SYS_MENU: 42135c4bbdfSmrg /* 42235c4bbdfSmrg * Add whatever the setup file wants to for this window 42335c4bbdfSmrg */ 42435c4bbdfSmrg SetupSysMenu(hwnd); 42535c4bbdfSmrg return 0; 42605b261ecSmrg 42705b261ecSmrg case WM_SYSCOMMAND: 42835c4bbdfSmrg /* 42935c4bbdfSmrg * Any window menu items go through here 43035c4bbdfSmrg */ 43135c4bbdfSmrg if (HandleCustomWM_COMMAND(hwnd, LOWORD(wParam))) { 43235c4bbdfSmrg /* Don't pass customized menus to DefWindowProc */ 43335c4bbdfSmrg return 0; 43435c4bbdfSmrg } 43535c4bbdfSmrg if (wParam == SC_RESTORE || wParam == SC_MAXIMIZE) { 43635c4bbdfSmrg WINDOWPLACEMENT wndpl; 43735c4bbdfSmrg 43835c4bbdfSmrg wndpl.length = sizeof(wndpl); 43935c4bbdfSmrg if (GetWindowPlacement(hwnd, &wndpl) && 44035c4bbdfSmrg wndpl.showCmd == SW_SHOWMINIMIZED) 44135c4bbdfSmrg needRestack = TRUE; 44235c4bbdfSmrg } 44335c4bbdfSmrg break; 44405b261ecSmrg 44505b261ecSmrg case WM_INITMENU: 44635c4bbdfSmrg /* Checks/Unchecks any menu items before they are displayed */ 44735c4bbdfSmrg HandleCustomWM_INITMENU(hwnd, (HMENU)wParam); 44835c4bbdfSmrg break; 44905b261ecSmrg 4506747b715Smrg case WM_ERASEBKGND: 45135c4bbdfSmrg /* 45235c4bbdfSmrg * Pretend that we did erase the background but we don't care, 45335c4bbdfSmrg * since we repaint the entire region anyhow 45435c4bbdfSmrg * This avoids some flickering when resizing. 45535c4bbdfSmrg */ 45635c4bbdfSmrg return TRUE; 4576747b715Smrg 45805b261ecSmrg case WM_PAINT: 45935c4bbdfSmrg /* Only paint if our window handle is valid */ 46035c4bbdfSmrg if (hwndScreen == NULL) 46135c4bbdfSmrg break; 46235c4bbdfSmrg 46335c4bbdfSmrg /* BeginPaint gives us an hdc that clips to the invalidated region */ 46435c4bbdfSmrg hdcUpdate = BeginPaint(hwnd, &ps); 46535c4bbdfSmrg /* Avoid the BitBlt's if the PAINTSTRUCT is bogus */ 46635c4bbdfSmrg if (ps.rcPaint.right == 0 && ps.rcPaint.bottom == 0 && 46735c4bbdfSmrg ps.rcPaint.left == 0 && ps.rcPaint.top == 0) { 46835c4bbdfSmrg EndPaint(hwnd, &ps); 46935c4bbdfSmrg return 0; 47035c4bbdfSmrg } 47135c4bbdfSmrg 47235c4bbdfSmrg#ifdef XWIN_GLX_WINDOWS 47335c4bbdfSmrg if (pWinPriv->fWglUsed) { 47435c4bbdfSmrg /* 47535c4bbdfSmrg For regions which are being drawn by GL, the shadow framebuffer doesn't have the 47635c4bbdfSmrg correct bits, so don't bitblt from the shadow framebuffer 47735c4bbdfSmrg 47835c4bbdfSmrg XXX: For now, just leave it alone, but ideally we want to send an expose event to 47935c4bbdfSmrg the window so it really redraws the affected region... 48035c4bbdfSmrg */ 48135c4bbdfSmrg ValidateRect(hwnd, &(ps.rcPaint)); 48235c4bbdfSmrg } 48335c4bbdfSmrg else 48435c4bbdfSmrg#endif 48535c4bbdfSmrg /* Try to copy from the shadow buffer */ 48635c4bbdfSmrg if (!BitBlt(hdcUpdate, 48735c4bbdfSmrg ps.rcPaint.left, ps.rcPaint.top, 48835c4bbdfSmrg ps.rcPaint.right - ps.rcPaint.left, 48935c4bbdfSmrg ps.rcPaint.bottom - ps.rcPaint.top, 49035c4bbdfSmrg s_pScreenPriv->hdcShadow, 49135c4bbdfSmrg ps.rcPaint.left + pWin->drawable.x, 49235c4bbdfSmrg ps.rcPaint.top + pWin->drawable.y, SRCCOPY)) { 49335c4bbdfSmrg LPVOID lpMsgBuf; 49435c4bbdfSmrg 49535c4bbdfSmrg /* Display a fancy error message */ 49635c4bbdfSmrg FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 49735c4bbdfSmrg FORMAT_MESSAGE_FROM_SYSTEM | 49835c4bbdfSmrg FORMAT_MESSAGE_IGNORE_INSERTS, 49935c4bbdfSmrg NULL, 50035c4bbdfSmrg GetLastError(), 50135c4bbdfSmrg MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 50235c4bbdfSmrg (LPTSTR) &lpMsgBuf, 0, NULL); 50335c4bbdfSmrg 50435c4bbdfSmrg ErrorF("winTopLevelWindowProc - BitBlt failed: %s\n", 50535c4bbdfSmrg (LPSTR) lpMsgBuf); 50635c4bbdfSmrg LocalFree(lpMsgBuf); 50735c4bbdfSmrg } 50835c4bbdfSmrg 50935c4bbdfSmrg /* EndPaint frees the DC */ 51035c4bbdfSmrg EndPaint(hwnd, &ps); 51135c4bbdfSmrg return 0; 51205b261ecSmrg 51305b261ecSmrg case WM_MOUSEMOVE: 51435c4bbdfSmrg /* Unpack the client area mouse coordinates */ 51535c4bbdfSmrg ptMouse.x = GET_X_LPARAM(lParam); 51635c4bbdfSmrg ptMouse.y = GET_Y_LPARAM(lParam); 51735c4bbdfSmrg 51835c4bbdfSmrg /* Translate the client area mouse coordinates to screen coordinates */ 51935c4bbdfSmrg ClientToScreen(hwnd, &ptMouse); 52035c4bbdfSmrg 52135c4bbdfSmrg /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */ 52235c4bbdfSmrg ptMouse.x -= GetSystemMetrics(SM_XVIRTUALSCREEN); 52335c4bbdfSmrg ptMouse.y -= GetSystemMetrics(SM_YVIRTUALSCREEN); 52435c4bbdfSmrg 52535c4bbdfSmrg /* We can't do anything without privates */ 52635c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 52735c4bbdfSmrg break; 52835c4bbdfSmrg 52935c4bbdfSmrg /* Has the mouse pointer crossed screens? */ 53035c4bbdfSmrg if (s_pScreen != miPointerGetScreen(g_pwinPointer)) 53135c4bbdfSmrg miPointerSetScreen(g_pwinPointer, s_pScreenInfo->dwScreen, 53235c4bbdfSmrg ptMouse.x - s_pScreenInfo->dwXOffset, 53335c4bbdfSmrg ptMouse.y - s_pScreenInfo->dwYOffset); 53435c4bbdfSmrg 53535c4bbdfSmrg /* Are we tracking yet? */ 53635c4bbdfSmrg if (!s_fTracking) { 53735c4bbdfSmrg TRACKMOUSEEVENT tme; 53835c4bbdfSmrg 53935c4bbdfSmrg /* Setup data structure */ 54035c4bbdfSmrg ZeroMemory(&tme, sizeof(tme)); 54135c4bbdfSmrg tme.cbSize = sizeof(tme); 54235c4bbdfSmrg tme.dwFlags = TME_LEAVE; 54335c4bbdfSmrg tme.hwndTrack = hwnd; 54435c4bbdfSmrg 54535c4bbdfSmrg /* Call the tracking function */ 54635c4bbdfSmrg if (!TrackMouseEvent(&tme)) 54735c4bbdfSmrg ErrorF("winTopLevelWindowProc - TrackMouseEvent failed\n"); 54835c4bbdfSmrg 54935c4bbdfSmrg /* Flag that we are tracking now */ 55035c4bbdfSmrg s_fTracking = TRUE; 55135c4bbdfSmrg } 55235c4bbdfSmrg 55335c4bbdfSmrg /* Hide or show the Windows mouse cursor */ 55435c4bbdfSmrg if (g_fSoftwareCursor && g_fCursor) { 55535c4bbdfSmrg /* Hide Windows cursor */ 55635c4bbdfSmrg g_fCursor = FALSE; 55735c4bbdfSmrg ShowCursor(FALSE); 55835c4bbdfSmrg } 55935c4bbdfSmrg 56035c4bbdfSmrg /* Kill the timer used to poll mouse events */ 56135c4bbdfSmrg if (g_uipMousePollingTimerID != 0) { 56235c4bbdfSmrg KillTimer(s_pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID); 56335c4bbdfSmrg g_uipMousePollingTimerID = 0; 56435c4bbdfSmrg } 56535c4bbdfSmrg 56635c4bbdfSmrg /* Deliver absolute cursor position to X Server */ 56735c4bbdfSmrg winEnqueueMotion(ptMouse.x - s_pScreenInfo->dwXOffset, 56835c4bbdfSmrg ptMouse.y - s_pScreenInfo->dwYOffset); 56935c4bbdfSmrg 57035c4bbdfSmrg return 0; 57135c4bbdfSmrg 57205b261ecSmrg case WM_NCMOUSEMOVE: 57335c4bbdfSmrg /* 57435c4bbdfSmrg * We break instead of returning 0 since we need to call 57535c4bbdfSmrg * DefWindowProc to get the mouse cursor changes 57635c4bbdfSmrg * and min/max/close button highlighting in Windows XP. 57735c4bbdfSmrg * The Platform SDK says that you should return 0 if you 57835c4bbdfSmrg * process this message, but it fails to mention that you 57935c4bbdfSmrg * will give up any default functionality if you do return 0. 58035c4bbdfSmrg */ 58135c4bbdfSmrg 58235c4bbdfSmrg /* We can't do anything without privates */ 58335c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 58435c4bbdfSmrg break; 58535c4bbdfSmrg 58635c4bbdfSmrg /* Non-client mouse movement, show Windows cursor */ 58735c4bbdfSmrg if (g_fSoftwareCursor && !g_fCursor) { 58835c4bbdfSmrg g_fCursor = TRUE; 58935c4bbdfSmrg ShowCursor(TRUE); 59035c4bbdfSmrg } 59135c4bbdfSmrg 59235c4bbdfSmrg winStartMousePolling(s_pScreenPriv); 59335c4bbdfSmrg 59435c4bbdfSmrg break; 59505b261ecSmrg 59605b261ecSmrg case WM_MOUSELEAVE: 59735c4bbdfSmrg /* Mouse has left our client area */ 59805b261ecSmrg 59935c4bbdfSmrg /* Flag that we are no longer tracking */ 60035c4bbdfSmrg s_fTracking = FALSE; 60105b261ecSmrg 60235c4bbdfSmrg /* Show the mouse cursor, if necessary */ 60335c4bbdfSmrg if (g_fSoftwareCursor && !g_fCursor) { 60435c4bbdfSmrg g_fCursor = TRUE; 60535c4bbdfSmrg ShowCursor(TRUE); 60635c4bbdfSmrg } 60705b261ecSmrg 60835c4bbdfSmrg winStartMousePolling(s_pScreenPriv); 6096747b715Smrg 61035c4bbdfSmrg return 0; 61105b261ecSmrg 61205b261ecSmrg case WM_LBUTTONDBLCLK: 61305b261ecSmrg case WM_LBUTTONDOWN: 61435c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 61535c4bbdfSmrg break; 61635c4bbdfSmrg g_fButton[0] = TRUE; 61735c4bbdfSmrg SetCapture(hwnd); 61835c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonPress, Button1, wParam); 6196747b715Smrg 62005b261ecSmrg case WM_LBUTTONUP: 62135c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 62235c4bbdfSmrg break; 62335c4bbdfSmrg g_fButton[0] = FALSE; 62435c4bbdfSmrg ReleaseCapture(); 62535c4bbdfSmrg winStartMousePolling(s_pScreenPriv); 62635c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button1, wParam); 62705b261ecSmrg 62805b261ecSmrg case WM_MBUTTONDBLCLK: 62905b261ecSmrg case WM_MBUTTONDOWN: 63035c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 63135c4bbdfSmrg break; 63235c4bbdfSmrg g_fButton[1] = TRUE; 63335c4bbdfSmrg SetCapture(hwnd); 63435c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonPress, Button2, wParam); 6356747b715Smrg 63605b261ecSmrg case WM_MBUTTONUP: 63735c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 63835c4bbdfSmrg break; 63935c4bbdfSmrg g_fButton[1] = FALSE; 64035c4bbdfSmrg ReleaseCapture(); 64135c4bbdfSmrg winStartMousePolling(s_pScreenPriv); 64235c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button2, wParam); 6436747b715Smrg 64405b261ecSmrg case WM_RBUTTONDBLCLK: 64505b261ecSmrg case WM_RBUTTONDOWN: 64635c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 64735c4bbdfSmrg break; 64835c4bbdfSmrg g_fButton[2] = TRUE; 64935c4bbdfSmrg SetCapture(hwnd); 65035c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonPress, Button3, wParam); 6516747b715Smrg 65205b261ecSmrg case WM_RBUTTONUP: 65335c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 65435c4bbdfSmrg break; 65535c4bbdfSmrg g_fButton[2] = FALSE; 65635c4bbdfSmrg ReleaseCapture(); 65735c4bbdfSmrg winStartMousePolling(s_pScreenPriv); 65835c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button3, wParam); 65905b261ecSmrg 66005b261ecSmrg case WM_XBUTTONDBLCLK: 66105b261ecSmrg case WM_XBUTTONDOWN: 66235c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 66335c4bbdfSmrg break; 66435c4bbdfSmrg SetCapture(hwnd); 66535c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonPress, HIWORD(wParam) + 7, 66635c4bbdfSmrg wParam); 6676747b715Smrg 66805b261ecSmrg case WM_XBUTTONUP: 66935c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 67035c4bbdfSmrg break; 67135c4bbdfSmrg ReleaseCapture(); 67235c4bbdfSmrg winStartMousePolling(s_pScreenPriv); 67335c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonRelease, 67435c4bbdfSmrg HIWORD(wParam) + 7, wParam); 67505b261ecSmrg 67605b261ecSmrg case WM_MOUSEWHEEL: 67735c4bbdfSmrg if (SendMessage 67835c4bbdfSmrg (hwnd, WM_NCHITTEST, 0, 67935c4bbdfSmrg MAKELONG(GET_X_LPARAM(lParam), 68035c4bbdfSmrg GET_Y_LPARAM(lParam))) == HTCLIENT) { 68135c4bbdfSmrg /* Pass the message to the root window */ 68235c4bbdfSmrg SendMessage(hwndScreen, message, wParam, lParam); 68335c4bbdfSmrg return 0; 68435c4bbdfSmrg } 68535c4bbdfSmrg else 68635c4bbdfSmrg break; 68735c4bbdfSmrg 68835c4bbdfSmrg case WM_MOUSEHWHEEL: 68935c4bbdfSmrg if (SendMessage 69035c4bbdfSmrg (hwnd, WM_NCHITTEST, 0, 69135c4bbdfSmrg MAKELONG(GET_X_LPARAM(lParam), 69235c4bbdfSmrg GET_Y_LPARAM(lParam))) == HTCLIENT) { 69335c4bbdfSmrg /* Pass the message to the root window */ 69435c4bbdfSmrg SendMessage(hwndScreen, message, wParam, lParam); 69535c4bbdfSmrg return 0; 69635c4bbdfSmrg } 69735c4bbdfSmrg else 69835c4bbdfSmrg break; 69905b261ecSmrg 70005b261ecSmrg case WM_SETFOCUS: 70135c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 70235c4bbdfSmrg break; 70335c4bbdfSmrg 70435c4bbdfSmrg { 70535c4bbdfSmrg /* Get the parent window for transient handling */ 70635c4bbdfSmrg HWND hParent = GetParent(hwnd); 70735c4bbdfSmrg 70835c4bbdfSmrg if (hParent && IsIconic(hParent)) 70935c4bbdfSmrg ShowWindow(hParent, SW_RESTORE); 71035c4bbdfSmrg } 71135c4bbdfSmrg 71235c4bbdfSmrg winRestoreModeKeyStates(); 71335c4bbdfSmrg 71435c4bbdfSmrg /* Add the keyboard hook if possible */ 71535c4bbdfSmrg if (g_fKeyboardHookLL) 71635c4bbdfSmrg g_fKeyboardHookLL = winInstallKeyboardHookLL(); 71735c4bbdfSmrg return 0; 71835c4bbdfSmrg 71905b261ecSmrg case WM_KILLFOCUS: 72035c4bbdfSmrg /* Pop any pressed keys since we are losing keyboard focus */ 72135c4bbdfSmrg winKeybdReleaseKeys(); 72235c4bbdfSmrg 72335c4bbdfSmrg /* Remove our keyboard hook if it is installed */ 72435c4bbdfSmrg winRemoveKeyboardHookLL(); 72535c4bbdfSmrg 72635c4bbdfSmrg /* Revert the X focus as well, but only if the Windows focus is going to another window */ 72735c4bbdfSmrg if (!wParam && pWin) 72835c4bbdfSmrg DeleteWindowFromAnyEvents(pWin, FALSE); 72905b261ecSmrg 73035c4bbdfSmrg return 0; 73105b261ecSmrg 73235c4bbdfSmrg case WM_SYSDEADCHAR: 73305b261ecSmrg case WM_DEADCHAR: 73435c4bbdfSmrg /* 73535c4bbdfSmrg * NOTE: We do nothing with WM_*CHAR messages, 73635c4bbdfSmrg * nor does the root window, so we can just toss these messages. 73735c4bbdfSmrg */ 73835c4bbdfSmrg return 0; 73905b261ecSmrg 74005b261ecSmrg case WM_SYSKEYDOWN: 74105b261ecSmrg case WM_KEYDOWN: 74205b261ecSmrg 74335c4bbdfSmrg /* 74435c4bbdfSmrg * Don't pass Alt-F4 key combo to root window, 74535c4bbdfSmrg * let Windows translate to WM_CLOSE and close this top-level window. 74635c4bbdfSmrg * 74735c4bbdfSmrg * NOTE: We purposely don't check the fUseWinKillKey setting because 74835c4bbdfSmrg * it should only apply to the key handling for the root window, 74935c4bbdfSmrg * not for top-level window-manager windows. 75035c4bbdfSmrg * 75135c4bbdfSmrg * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window 75235c4bbdfSmrg * because that is a key combo that no X app should be expecting to 75335c4bbdfSmrg * receive, since it has historically been used to shutdown the X server. 75435c4bbdfSmrg * Passing Ctrl-Alt-Backspace to the root window preserves that 75535c4bbdfSmrg * behavior, assuming that -unixkill has been passed as a parameter. 75635c4bbdfSmrg */ 75735c4bbdfSmrg if (wParam == VK_F4 && (GetKeyState(VK_MENU) & 0x8000)) 75835c4bbdfSmrg break; 75905b261ecSmrg 76005b261ecSmrg#if CYGWINDOWING_DEBUG 76135c4bbdfSmrg if (wParam == VK_ESCAPE) { 76235c4bbdfSmrg /* Place for debug: put any tests and dumps here */ 76335c4bbdfSmrg WINDOWPLACEMENT windPlace; 76435c4bbdfSmrg RECT rc; 76535c4bbdfSmrg LPRECT pRect; 76635c4bbdfSmrg 76735c4bbdfSmrg windPlace.length = sizeof(WINDOWPLACEMENT); 76835c4bbdfSmrg GetWindowPlacement(hwnd, &windPlace); 76935c4bbdfSmrg pRect = &windPlace.rcNormalPosition; 77035c4bbdfSmrg ErrorF("\nCYGWINDOWING Dump:\n" 77135c4bbdfSmrg "\tdrawable: (%hd, %hd) - %hdx%hd\n", pDraw->x, 77235c4bbdfSmrg pDraw->y, pDraw->width, pDraw->height); 77335c4bbdfSmrg ErrorF("\twindPlace: (%d, %d) - %dx%d\n", (int)pRect->left, 77435c4bbdfSmrg (int)pRect->top, (int)(pRect->right - pRect->left), 77535c4bbdfSmrg (int)(pRect->bottom - pRect->top)); 77635c4bbdfSmrg if (GetClientRect(hwnd, &rc)) { 77735c4bbdfSmrg pRect = &rc; 77835c4bbdfSmrg ErrorF("\tClientRect: (%d, %d) - %dx%d\n", (int)pRect->left, 77935c4bbdfSmrg (int)pRect->top, (int)(pRect->right - pRect->left), 78035c4bbdfSmrg (int)(pRect->bottom - pRect->top)); 78135c4bbdfSmrg } 78235c4bbdfSmrg if (GetWindowRect(hwnd, &rc)) { 78335c4bbdfSmrg pRect = &rc; 78435c4bbdfSmrg ErrorF("\tWindowRect: (%d, %d) - %dx%d\n", (int)pRect->left, 78535c4bbdfSmrg (int)pRect->top, (int)(pRect->right - pRect->left), 78635c4bbdfSmrg (int)(pRect->bottom - pRect->top)); 78735c4bbdfSmrg } 78835c4bbdfSmrg ErrorF("\n"); 78935c4bbdfSmrg } 79005b261ecSmrg#endif 79135c4bbdfSmrg 79235c4bbdfSmrg /* Pass the message to the root window */ 79335c4bbdfSmrg return winWindowProc(hwndScreen, message, wParam, lParam); 79405b261ecSmrg 79505b261ecSmrg case WM_SYSKEYUP: 79605b261ecSmrg case WM_KEYUP: 79705b261ecSmrg 79835c4bbdfSmrg /* Pass the message to the root window */ 79935c4bbdfSmrg return winWindowProc(hwndScreen, message, wParam, lParam); 80005b261ecSmrg 80105b261ecSmrg case WM_HOTKEY: 80205b261ecSmrg 80335c4bbdfSmrg /* Pass the message to the root window */ 80435c4bbdfSmrg SendMessage(hwndScreen, message, wParam, lParam); 80535c4bbdfSmrg return 0; 80605b261ecSmrg 80705b261ecSmrg case WM_ACTIVATE: 80805b261ecSmrg 80935c4bbdfSmrg /* Pass the message to the root window */ 81035c4bbdfSmrg SendMessage(hwndScreen, message, wParam, lParam); 81135c4bbdfSmrg 81235c4bbdfSmrg if (LOWORD(wParam) != WA_INACTIVE) { 81335c4bbdfSmrg /* Raise the window to the top in Z order */ 81435c4bbdfSmrg /* ago: Activate does not mean putting it to front! */ 81535c4bbdfSmrg /* 81635c4bbdfSmrg wmMsg.msg = WM_WM_RAISE; 81735c4bbdfSmrg if (fWMMsgInitialized) 81835c4bbdfSmrg winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); 81935c4bbdfSmrg */ 82035c4bbdfSmrg 82135c4bbdfSmrg /* Tell our Window Manager thread to activate the window */ 82235c4bbdfSmrg wmMsg.msg = WM_WM_ACTIVATE; 82335c4bbdfSmrg if (fWMMsgInitialized) 82435c4bbdfSmrg if (!pWin || !pWin->overrideRedirect) /* for OOo menus */ 82535c4bbdfSmrg winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg); 82635c4bbdfSmrg } 82735c4bbdfSmrg /* Prevent the mouse wheel from stalling when another window is minimized */ 82835c4bbdfSmrg if (HIWORD(wParam) == 0 && LOWORD(wParam) == WA_ACTIVE && 82935c4bbdfSmrg (HWND) lParam != NULL && (HWND) lParam != GetParent(hwnd)) 83035c4bbdfSmrg SetFocus(hwnd); 83135c4bbdfSmrg return 0; 83205b261ecSmrg 83305b261ecSmrg case WM_ACTIVATEAPP: 83435c4bbdfSmrg /* 83535c4bbdfSmrg * This message is also sent to the root window 83635c4bbdfSmrg * so we do nothing for individual multiwindow windows 83735c4bbdfSmrg */ 83835c4bbdfSmrg break; 83905b261ecSmrg 84005b261ecSmrg case WM_CLOSE: 84135c4bbdfSmrg /* Remove AppUserModelID property */ 84235c4bbdfSmrg winSetAppUserModelID(hwnd, NULL); 84335c4bbdfSmrg /* Branch on if the window was killed in X already */ 84435c4bbdfSmrg if (pWinPriv->fXKilled) { 84535c4bbdfSmrg /* Window was killed, go ahead and destroy the window */ 84635c4bbdfSmrg DestroyWindow(hwnd); 84735c4bbdfSmrg } 84835c4bbdfSmrg else { 84935c4bbdfSmrg /* Tell our Window Manager thread to kill the window */ 85035c4bbdfSmrg wmMsg.msg = WM_WM_KILL; 85135c4bbdfSmrg if (fWMMsgInitialized) 85235c4bbdfSmrg winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg); 85335c4bbdfSmrg } 85435c4bbdfSmrg return 0; 85505b261ecSmrg 85605b261ecSmrg case WM_DESTROY: 85705b261ecSmrg 85835c4bbdfSmrg /* Branch on if the window was killed in X already */ 85935c4bbdfSmrg if (pWinPriv && !pWinPriv->fXKilled) { 86035c4bbdfSmrg ErrorF("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n"); 86105b261ecSmrg 86235c4bbdfSmrg /* Tell our Window Manager thread to kill the window */ 86335c4bbdfSmrg wmMsg.msg = WM_WM_KILL; 86435c4bbdfSmrg if (fWMMsgInitialized) 86535c4bbdfSmrg winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg); 86635c4bbdfSmrg } 86735c4bbdfSmrg 86835c4bbdfSmrg RemoveProp(hwnd, WIN_WINDOW_PROP); 86935c4bbdfSmrg RemoveProp(hwnd, WIN_WID_PROP); 87035c4bbdfSmrg RemoveProp(hwnd, WIN_NEEDMANAGE_PROP); 87105b261ecSmrg 87235c4bbdfSmrg break; 87305b261ecSmrg 87405b261ecSmrg case WM_MOVE: 87535c4bbdfSmrg /* Adjust the X Window to the moved Windows window */ 87635c4bbdfSmrg if (!hasEnteredSizeMove) 87735c4bbdfSmrg winAdjustXWindow(pWin, hwnd); 87835c4bbdfSmrg /* else: Wait for WM_EXITSIZEMOVE */ 87935c4bbdfSmrg return 0; 88005b261ecSmrg 88105b261ecSmrg case WM_SHOWWINDOW: 88235c4bbdfSmrg /* Bail out if the window is being hidden */ 88335c4bbdfSmrg if (!wParam) 88435c4bbdfSmrg return 0; 88535c4bbdfSmrg 88635c4bbdfSmrg /* */ 88735c4bbdfSmrg if (!pWin->overrideRedirect) { 88835c4bbdfSmrg HWND zstyle = HWND_NOTOPMOST; 88935c4bbdfSmrg 89035c4bbdfSmrg /* Flag that this window needs to be made active when clicked */ 89135c4bbdfSmrg SetProp(hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1); 89235c4bbdfSmrg 89335c4bbdfSmrg /* Set the transient style flags */ 89435c4bbdfSmrg if (GetParent(hwnd)) 89535c4bbdfSmrg SetWindowLongPtr(hwnd, GWL_STYLE, 89635c4bbdfSmrg WS_POPUP | WS_OVERLAPPED | WS_SYSMENU | 89735c4bbdfSmrg WS_CLIPCHILDREN | WS_CLIPSIBLINGS); 89835c4bbdfSmrg /* Set the window standard style flags */ 89935c4bbdfSmrg else 90035c4bbdfSmrg SetWindowLongPtr(hwnd, GWL_STYLE, 90135c4bbdfSmrg (WS_POPUP | WS_OVERLAPPEDWINDOW | 90235c4bbdfSmrg WS_CLIPCHILDREN | WS_CLIPSIBLINGS) 90335c4bbdfSmrg & ~WS_CAPTION & ~WS_SIZEBOX); 90435c4bbdfSmrg 90535c4bbdfSmrg winUpdateWindowPosition(hwnd, &zstyle); 90635c4bbdfSmrg 90735c4bbdfSmrg { 90835c4bbdfSmrg WinXWMHints hints; 90935c4bbdfSmrg 91035c4bbdfSmrg if (winMultiWindowGetWMHints(pWin, &hints)) { 91135c4bbdfSmrg /* 91235c4bbdfSmrg Give the window focus, unless it has an InputHint 91335c4bbdfSmrg which is FALSE (this is used by e.g. glean to 91435c4bbdfSmrg avoid every test window grabbing the focus) 91535c4bbdfSmrg */ 91635c4bbdfSmrg if (!((hints.flags & InputHint) && (!hints.input))) { 91735c4bbdfSmrg SetForegroundWindow(hwnd); 91835c4bbdfSmrg } 91935c4bbdfSmrg } 92035c4bbdfSmrg } 92135c4bbdfSmrg wmMsg.msg = WM_WM_MAP3; 92235c4bbdfSmrg } 92335c4bbdfSmrg else { /* It is an overridden window so make it top of Z stack */ 92435c4bbdfSmrg 92535c4bbdfSmrg HWND forHwnd = GetForegroundWindow(); 92635c4bbdfSmrg 92705b261ecSmrg#if CYGWINDOWING_DEBUG 92835c4bbdfSmrg ErrorF("overridden window is shown\n"); 92905b261ecSmrg#endif 93035c4bbdfSmrg if (forHwnd != NULL) { 93135c4bbdfSmrg if (GetWindowLongPtr(forHwnd, GWLP_USERDATA) & (LONG_PTR) 93235c4bbdfSmrg XMING_SIGNATURE) { 93335c4bbdfSmrg if (GetWindowLongPtr(forHwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) 93435c4bbdfSmrg SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, 93535c4bbdfSmrg SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 93635c4bbdfSmrg else 93735c4bbdfSmrg SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, 93835c4bbdfSmrg SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 93935c4bbdfSmrg } 94035c4bbdfSmrg } 94135c4bbdfSmrg wmMsg.msg = WM_WM_MAP2; 94235c4bbdfSmrg } 94335c4bbdfSmrg 94435c4bbdfSmrg /* Tell our Window Manager thread to map the window */ 94535c4bbdfSmrg if (fWMMsgInitialized) 94635c4bbdfSmrg winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg); 94735c4bbdfSmrg 94835c4bbdfSmrg winStartMousePolling(s_pScreenPriv); 94935c4bbdfSmrg 95035c4bbdfSmrg return 0; 95105b261ecSmrg 95205b261ecSmrg case WM_SIZING: 95335c4bbdfSmrg /* Need to legalize the size according to WM_NORMAL_HINTS */ 95435c4bbdfSmrg /* for applications like xterm */ 95535c4bbdfSmrg return ValidateSizing(hwnd, pWin, wParam, lParam); 95605b261ecSmrg 95705b261ecSmrg case WM_WINDOWPOSCHANGED: 95835c4bbdfSmrg { 95935c4bbdfSmrg LPWINDOWPOS pWinPos = (LPWINDOWPOS) lParam; 96005b261ecSmrg 96135c4bbdfSmrg if (!(pWinPos->flags & SWP_NOZORDER)) { 96205b261ecSmrg#if CYGWINDOWING_DEBUG 96335c4bbdfSmrg winDebug("\twindow z order was changed\n"); 96405b261ecSmrg#endif 96535c4bbdfSmrg if (pWinPos->hwndInsertAfter == HWND_TOP 96635c4bbdfSmrg || pWinPos->hwndInsertAfter == HWND_TOPMOST 96735c4bbdfSmrg || pWinPos->hwndInsertAfter == HWND_NOTOPMOST) { 96805b261ecSmrg#if CYGWINDOWING_DEBUG 96935c4bbdfSmrg winDebug("\traise to top\n"); 97005b261ecSmrg#endif 97135c4bbdfSmrg /* Raise the window to the top in Z order */ 97235c4bbdfSmrg winRaiseWindow(pWin); 97335c4bbdfSmrg } 97435c4bbdfSmrg else if (pWinPos->hwndInsertAfter == HWND_BOTTOM) { 97535c4bbdfSmrg } 97635c4bbdfSmrg else { 97735c4bbdfSmrg /* Check if this window is top of X windows. */ 97835c4bbdfSmrg HWND hWndAbove = NULL; 97935c4bbdfSmrg DWORD dwCurrentProcessID = GetCurrentProcessId(); 98035c4bbdfSmrg DWORD dwWindowProcessID = 0; 98135c4bbdfSmrg 98235c4bbdfSmrg for (hWndAbove = pWinPos->hwndInsertAfter; 98335c4bbdfSmrg hWndAbove != NULL; 98435c4bbdfSmrg hWndAbove = GetNextWindow(hWndAbove, GW_HWNDPREV)) { 98535c4bbdfSmrg /* Ignore other XWin process's window */ 98635c4bbdfSmrg GetWindowThreadProcessId(hWndAbove, &dwWindowProcessID); 98735c4bbdfSmrg 98835c4bbdfSmrg if ((dwWindowProcessID == dwCurrentProcessID) 98935c4bbdfSmrg && GetProp(hWndAbove, WIN_WINDOW_PROP) 99035c4bbdfSmrg && !IsWindowVisible(hWndAbove) 99135c4bbdfSmrg && !IsIconic(hWndAbove)) /* ignore minimized windows */ 99235c4bbdfSmrg break; 99335c4bbdfSmrg } 99435c4bbdfSmrg /* If this is top of X windows in Windows stack, 99535c4bbdfSmrg raise it in X stack. */ 99635c4bbdfSmrg if (hWndAbove == NULL) { 99705b261ecSmrg#if CYGWINDOWING_DEBUG 99835c4bbdfSmrg winDebug("\traise to top\n"); 99905b261ecSmrg#endif 100035c4bbdfSmrg winRaiseWindow(pWin); 100135c4bbdfSmrg } 100235c4bbdfSmrg } 100335c4bbdfSmrg } 100435c4bbdfSmrg } 100535c4bbdfSmrg /* 100635c4bbdfSmrg * Pass the message to DefWindowProc to let the function 100735c4bbdfSmrg * break down WM_WINDOWPOSCHANGED to WM_MOVE and WM_SIZE. 100835c4bbdfSmrg */ 100935c4bbdfSmrg break; 101035c4bbdfSmrg 101135c4bbdfSmrg case WM_ENTERSIZEMOVE: 101235c4bbdfSmrg hasEnteredSizeMove = TRUE; 101335c4bbdfSmrg return 0; 101435c4bbdfSmrg 101535c4bbdfSmrg case WM_EXITSIZEMOVE: 101635c4bbdfSmrg /* Adjust the X Window to the moved Windows window */ 101735c4bbdfSmrg hasEnteredSizeMove = FALSE; 101835c4bbdfSmrg winAdjustXWindow(pWin, hwnd); 101935c4bbdfSmrg return 0; 102005b261ecSmrg 102105b261ecSmrg case WM_SIZE: 102235c4bbdfSmrg /* see dix/window.c */ 102305b261ecSmrg#if CYGWINDOWING_DEBUG 102435c4bbdfSmrg { 102535c4bbdfSmrg char buf[64]; 102635c4bbdfSmrg 102735c4bbdfSmrg switch (wParam) { 102835c4bbdfSmrg case SIZE_MINIMIZED: 102935c4bbdfSmrg strcpy(buf, "SIZE_MINIMIZED"); 103035c4bbdfSmrg break; 103135c4bbdfSmrg case SIZE_MAXIMIZED: 103235c4bbdfSmrg strcpy(buf, "SIZE_MAXIMIZED"); 103335c4bbdfSmrg break; 103435c4bbdfSmrg case SIZE_RESTORED: 103535c4bbdfSmrg strcpy(buf, "SIZE_RESTORED"); 103635c4bbdfSmrg break; 103735c4bbdfSmrg default: 103835c4bbdfSmrg strcpy(buf, "UNKNOWN_FLAG"); 103935c4bbdfSmrg } 104035c4bbdfSmrg ErrorF("winTopLevelWindowProc - WM_SIZE to %dx%d (%s)\n", 104135c4bbdfSmrg (int) LOWORD(lParam), (int) HIWORD(lParam), buf); 104235c4bbdfSmrg } 104305b261ecSmrg#endif 104435c4bbdfSmrg if (!hasEnteredSizeMove) { 104535c4bbdfSmrg /* Adjust the X Window to the moved Windows window */ 104635c4bbdfSmrg winAdjustXWindow(pWin, hwnd); 104735c4bbdfSmrg } 104835c4bbdfSmrg /* else: wait for WM_EXITSIZEMOVE */ 104935c4bbdfSmrg return 0; /* end of WM_SIZE handler */ 105035c4bbdfSmrg 105135c4bbdfSmrg case WM_STYLECHANGING: 105235c4bbdfSmrg /* 105335c4bbdfSmrg When the style changes, adjust the Windows window size so the client area remains the same size, 105435c4bbdfSmrg and adjust the Windows window position so that the client area remains in the same place. 105535c4bbdfSmrg */ 105635c4bbdfSmrg { 105735c4bbdfSmrg RECT newWinRect; 105835c4bbdfSmrg DWORD dwExStyle; 105935c4bbdfSmrg DWORD dwStyle; 106035c4bbdfSmrg DWORD newStyle = ((STYLESTRUCT *) lParam)->styleNew; 106135c4bbdfSmrg WINDOWINFO wi; 106235c4bbdfSmrg 106335c4bbdfSmrg dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE); 106435c4bbdfSmrg dwStyle = GetWindowLongPtr(hwnd, GWL_STYLE); 106535c4bbdfSmrg 106635c4bbdfSmrg winDebug("winTopLevelWindowProc - WM_STYLECHANGING from %08x %08x\n", 106735c4bbdfSmrg (unsigned int)dwStyle, (unsigned int)dwExStyle); 106835c4bbdfSmrg 106935c4bbdfSmrg if (wParam == GWL_EXSTYLE) 107035c4bbdfSmrg dwExStyle = newStyle; 107135c4bbdfSmrg 107235c4bbdfSmrg if (wParam == GWL_STYLE) 107335c4bbdfSmrg dwStyle = newStyle; 107435c4bbdfSmrg 107535c4bbdfSmrg winDebug("winTopLevelWindowProc - WM_STYLECHANGING to %08x %08x\n", 107635c4bbdfSmrg (unsigned int)dwStyle, (unsigned int)dwExStyle); 107735c4bbdfSmrg 107835c4bbdfSmrg /* Get client rect in screen coordinates */ 107935c4bbdfSmrg wi.cbSize = sizeof(WINDOWINFO); 108035c4bbdfSmrg GetWindowInfo(hwnd, &wi); 108135c4bbdfSmrg 108235c4bbdfSmrg winDebug 108335c4bbdfSmrg ("winTopLevelWindowProc - WM_STYLECHANGING client area {%d, %d, %d, %d}, {%d x %d}\n", 108435c4bbdfSmrg (int)wi.rcClient.left, (int)wi.rcClient.top, (int)wi.rcClient.right, 108535c4bbdfSmrg (int)wi.rcClient.bottom, (int)(wi.rcClient.right - wi.rcClient.left), 108635c4bbdfSmrg (int)(wi.rcClient.bottom - wi.rcClient.top)); 108735c4bbdfSmrg 108835c4bbdfSmrg newWinRect = wi.rcClient; 108935c4bbdfSmrg if (!AdjustWindowRectEx(&newWinRect, dwStyle, FALSE, dwExStyle)) 109035c4bbdfSmrg winDebug 109135c4bbdfSmrg ("winTopLevelWindowProc - WM_STYLECHANGING AdjustWindowRectEx failed\n"); 109235c4bbdfSmrg 109335c4bbdfSmrg winDebug 109435c4bbdfSmrg ("winTopLevelWindowProc - WM_STYLECHANGING window area should be {%d, %d, %d, %d}, {%d x %d}\n", 109535c4bbdfSmrg (int)newWinRect.left, (int)newWinRect.top, (int)newWinRect.right, 109635c4bbdfSmrg (int)newWinRect.bottom, (int)(newWinRect.right - newWinRect.left), 109735c4bbdfSmrg (int)(newWinRect.bottom - newWinRect.top)); 109835c4bbdfSmrg 109935c4bbdfSmrg /* 110035c4bbdfSmrg Style change hasn't happened yet, so we can't adjust the window size yet, as the winAdjustXWindow() 110135c4bbdfSmrg which WM_SIZE does will use the current (unchanged) style. Instead make a note to change it when 110235c4bbdfSmrg WM_STYLECHANGED is received... 110335c4bbdfSmrg */ 110435c4bbdfSmrg pWinPriv->hDwp = BeginDeferWindowPos(1); 110535c4bbdfSmrg pWinPriv->hDwp = 110635c4bbdfSmrg DeferWindowPos(pWinPriv->hDwp, hwnd, NULL, newWinRect.left, 110735c4bbdfSmrg newWinRect.top, newWinRect.right - newWinRect.left, 110835c4bbdfSmrg newWinRect.bottom - newWinRect.top, 110935c4bbdfSmrg SWP_NOACTIVATE | SWP_NOZORDER); 111035c4bbdfSmrg } 111135c4bbdfSmrg return 0; 111235c4bbdfSmrg 111335c4bbdfSmrg case WM_STYLECHANGED: 111435c4bbdfSmrg { 111535c4bbdfSmrg if (pWinPriv->hDwp) { 111635c4bbdfSmrg EndDeferWindowPos(pWinPriv->hDwp); 111735c4bbdfSmrg pWinPriv->hDwp = NULL; 111835c4bbdfSmrg } 111935c4bbdfSmrg winDebug("winTopLevelWindowProc - WM_STYLECHANGED done\n"); 112035c4bbdfSmrg } 112135c4bbdfSmrg return 0; 112205b261ecSmrg 112305b261ecSmrg case WM_MOUSEACTIVATE: 112405b261ecSmrg 112535c4bbdfSmrg /* Check if this window needs to be made active when clicked */ 112635c4bbdfSmrg if (!GetProp(pWinPriv->hWnd, WIN_NEEDMANAGE_PROP)) { 112705b261ecSmrg#if CYGMULTIWINDOW_DEBUG 112835c4bbdfSmrg ErrorF("winTopLevelWindowProc - WM_MOUSEACTIVATE - " 112935c4bbdfSmrg "MA_NOACTIVATE\n"); 113005b261ecSmrg#endif 113105b261ecSmrg 113235c4bbdfSmrg /* */ 113335c4bbdfSmrg return MA_NOACTIVATE; 113435c4bbdfSmrg } 113535c4bbdfSmrg break; 113605b261ecSmrg 113705b261ecSmrg case WM_SETCURSOR: 113835c4bbdfSmrg if (LOWORD(lParam) == HTCLIENT) { 113935c4bbdfSmrg if (!g_fSoftwareCursor) 114035c4bbdfSmrg SetCursor(s_pScreenPriv->cursor.handle); 114135c4bbdfSmrg return TRUE; 114235c4bbdfSmrg } 114335c4bbdfSmrg break; 114405b261ecSmrg 114505b261ecSmrg default: 114635c4bbdfSmrg break; 114705b261ecSmrg } 114805b261ecSmrg 114935c4bbdfSmrg ret = DefWindowProc(hwnd, message, wParam, lParam); 115035c4bbdfSmrg /* 115135c4bbdfSmrg * If the window was minized we get the stack change before the window is restored 115235c4bbdfSmrg * and so it gets lost. Ensure there stacking order is correct. 115335c4bbdfSmrg */ 115435c4bbdfSmrg if (needRestack) 115535c4bbdfSmrg winReorderWindowsMultiWindow(); 115635c4bbdfSmrg return ret; 115705b261ecSmrg} 1158