winmultiwindowwndproc.c revision 05b261ec
105b261ecSmrg/* 205b261ecSmrg *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 305b261ecSmrg * 405b261ecSmrg *Permission is hereby granted, free of charge, to any person obtaining 505b261ecSmrg * a copy of this software and associated documentation files (the 605b261ecSmrg *"Software"), to deal in the Software without restriction, including 705b261ecSmrg *without limitation the rights to use, copy, modify, merge, publish, 805b261ecSmrg *distribute, sublicense, and/or sell copies of the Software, and to 905b261ecSmrg *permit persons to whom the Software is furnished to do so, subject to 1005b261ecSmrg *the following conditions: 1105b261ecSmrg * 1205b261ecSmrg *The above copyright notice and this permission notice shall be 1305b261ecSmrg *included in all copies or substantial portions of the Software. 1405b261ecSmrg * 1505b261ecSmrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1605b261ecSmrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1705b261ecSmrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1805b261ecSmrg *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR 1905b261ecSmrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 2005b261ecSmrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 2105b261ecSmrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2205b261ecSmrg * 2305b261ecSmrg *Except as contained in this notice, the name of the XFree86 Project 2405b261ecSmrg *shall not be used in advertising or otherwise to promote the sale, use 2505b261ecSmrg *or other dealings in this Software without prior written authorization 2605b261ecSmrg *from the XFree86 Project. 2705b261ecSmrg * 2805b261ecSmrg * Authors: Kensuke Matsuzaki 2905b261ecSmrg * Earle F. Philhower, III 3005b261ecSmrg * Harold L Hunt II 3105b261ecSmrg */ 3205b261ecSmrg 3305b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H 3405b261ecSmrg#include <xwin-config.h> 3505b261ecSmrg#endif 3605b261ecSmrg#include "win.h" 3705b261ecSmrg#include "dixevents.h" 3805b261ecSmrg#include "winmultiwindowclass.h" 3905b261ecSmrg#include "winprefs.h" 4005b261ecSmrg#include "winmsg.h" 4105b261ecSmrg#include "inputstr.h" 4205b261ecSmrg 4305b261ecSmrg/* 4405b261ecSmrg * External global variables 4505b261ecSmrg */ 4605b261ecSmrg 4705b261ecSmrgextern Bool g_fCursor; 4805b261ecSmrgextern Bool g_fKeyboardHookLL; 4905b261ecSmrgextern Bool g_fSoftwareCursor; 5005b261ecSmrgextern Bool g_fButton[3]; 5105b261ecSmrg 5205b261ecSmrg 5305b261ecSmrg/* 5405b261ecSmrg * Local globals 5505b261ecSmrg */ 5605b261ecSmrg 5705b261ecSmrgstatic UINT_PTR g_uipMousePollingTimerID = 0; 5805b261ecSmrg 5905b261ecSmrg 6005b261ecSmrg/* 6105b261ecSmrg * Constant defines 6205b261ecSmrg */ 6305b261ecSmrg 6405b261ecSmrg#define MOUSE_POLLING_INTERVAL 500 6505b261ecSmrg#define WIN_MULTIWINDOW_SHAPE YES 6605b261ecSmrg 6705b261ecSmrg 6805b261ecSmrg/* 6905b261ecSmrg * ConstrainSize - Taken from TWM sources - Respects hints for sizing 7005b261ecSmrg */ 7105b261ecSmrg#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) ) 7205b261ecSmrgstatic void 7305b261ecSmrgConstrainSize (WinXSizeHints hints, int *widthp, int *heightp) 7405b261ecSmrg{ 7505b261ecSmrg int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta; 7605b261ecSmrg int baseWidth, baseHeight; 7705b261ecSmrg int dwidth = *widthp, dheight = *heightp; 7805b261ecSmrg 7905b261ecSmrg if (hints.flags & PMinSize) 8005b261ecSmrg { 8105b261ecSmrg minWidth = hints.min_width; 8205b261ecSmrg minHeight = hints.min_height; 8305b261ecSmrg } 8405b261ecSmrg else if (hints.flags & PBaseSize) 8505b261ecSmrg { 8605b261ecSmrg minWidth = hints.base_width; 8705b261ecSmrg minHeight = hints.base_height; 8805b261ecSmrg } 8905b261ecSmrg else 9005b261ecSmrg minWidth = minHeight = 1; 9105b261ecSmrg 9205b261ecSmrg if (hints.flags & PBaseSize) 9305b261ecSmrg { 9405b261ecSmrg baseWidth = hints.base_width; 9505b261ecSmrg baseHeight = hints.base_height; 9605b261ecSmrg } 9705b261ecSmrg else if (hints.flags & PMinSize) 9805b261ecSmrg { 9905b261ecSmrg baseWidth = hints.min_width; 10005b261ecSmrg baseHeight = hints.min_height; 10105b261ecSmrg } 10205b261ecSmrg else 10305b261ecSmrg baseWidth = baseHeight = 0; 10405b261ecSmrg 10505b261ecSmrg if (hints.flags & PMaxSize) 10605b261ecSmrg { 10705b261ecSmrg maxWidth = hints.max_width; 10805b261ecSmrg maxHeight = hints.max_height; 10905b261ecSmrg } 11005b261ecSmrg else 11105b261ecSmrg { 11205b261ecSmrg maxWidth = MAXINT; 11305b261ecSmrg maxHeight = MAXINT; 11405b261ecSmrg } 11505b261ecSmrg 11605b261ecSmrg if (hints.flags & PResizeInc) 11705b261ecSmrg { 11805b261ecSmrg xinc = hints.width_inc; 11905b261ecSmrg yinc = hints.height_inc; 12005b261ecSmrg } 12105b261ecSmrg else 12205b261ecSmrg xinc = yinc = 1; 12305b261ecSmrg 12405b261ecSmrg /* 12505b261ecSmrg * First, clamp to min and max values 12605b261ecSmrg */ 12705b261ecSmrg if (dwidth < minWidth) 12805b261ecSmrg dwidth = minWidth; 12905b261ecSmrg if (dheight < minHeight) 13005b261ecSmrg dheight = minHeight; 13105b261ecSmrg 13205b261ecSmrg if (dwidth > maxWidth) 13305b261ecSmrg dwidth = maxWidth; 13405b261ecSmrg if (dheight > maxHeight) 13505b261ecSmrg dheight = maxHeight; 13605b261ecSmrg 13705b261ecSmrg /* 13805b261ecSmrg * Second, fit to base + N * inc 13905b261ecSmrg */ 14005b261ecSmrg dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth; 14105b261ecSmrg dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight; 14205b261ecSmrg 14305b261ecSmrg /* 14405b261ecSmrg * Third, adjust for aspect ratio 14505b261ecSmrg */ 14605b261ecSmrg 14705b261ecSmrg /* 14805b261ecSmrg * The math looks like this: 14905b261ecSmrg * 15005b261ecSmrg * minAspectX dwidth maxAspectX 15105b261ecSmrg * ---------- <= ------- <= ---------- 15205b261ecSmrg * minAspectY dheight maxAspectY 15305b261ecSmrg * 15405b261ecSmrg * If that is multiplied out, then the width and height are 15505b261ecSmrg * invalid in the following situations: 15605b261ecSmrg * 15705b261ecSmrg * minAspectX * dheight > minAspectY * dwidth 15805b261ecSmrg * maxAspectX * dheight < maxAspectY * dwidth 15905b261ecSmrg * 16005b261ecSmrg */ 16105b261ecSmrg 16205b261ecSmrg if (hints.flags & PAspect) 16305b261ecSmrg { 16405b261ecSmrg if (hints.min_aspect.x * dheight > hints.min_aspect.y * dwidth) 16505b261ecSmrg { 16605b261ecSmrg delta = makemult(hints.min_aspect.x * dheight / hints.min_aspect.y - dwidth, xinc); 16705b261ecSmrg if (dwidth + delta <= maxWidth) 16805b261ecSmrg dwidth += delta; 16905b261ecSmrg else 17005b261ecSmrg { 17105b261ecSmrg delta = makemult(dheight - dwidth*hints.min_aspect.y/hints.min_aspect.x, yinc); 17205b261ecSmrg if (dheight - delta >= minHeight) 17305b261ecSmrg dheight -= delta; 17405b261ecSmrg } 17505b261ecSmrg } 17605b261ecSmrg 17705b261ecSmrg if (hints.max_aspect.x * dheight < hints.max_aspect.y * dwidth) 17805b261ecSmrg { 17905b261ecSmrg delta = makemult(dwidth * hints.max_aspect.y / hints.max_aspect.x - dheight, yinc); 18005b261ecSmrg if (dheight + delta <= maxHeight) 18105b261ecSmrg dheight += delta; 18205b261ecSmrg else 18305b261ecSmrg { 18405b261ecSmrg delta = makemult(dwidth - hints.max_aspect.x*dheight/hints.max_aspect.y, xinc); 18505b261ecSmrg if (dwidth - delta >= minWidth) 18605b261ecSmrg dwidth -= delta; 18705b261ecSmrg } 18805b261ecSmrg } 18905b261ecSmrg } 19005b261ecSmrg 19105b261ecSmrg /* Return computed values */ 19205b261ecSmrg *widthp = dwidth; 19305b261ecSmrg *heightp = dheight; 19405b261ecSmrg} 19505b261ecSmrg#undef makemult 19605b261ecSmrg 19705b261ecSmrg 19805b261ecSmrg 19905b261ecSmrg/* 20005b261ecSmrg * ValidateSizing - Ensures size request respects hints 20105b261ecSmrg */ 20205b261ecSmrgstatic int 20305b261ecSmrgValidateSizing (HWND hwnd, WindowPtr pWin, 20405b261ecSmrg WPARAM wParam, LPARAM lParam) 20505b261ecSmrg{ 20605b261ecSmrg WinXSizeHints sizeHints; 20705b261ecSmrg RECT *rect; 20805b261ecSmrg int iWidth, iHeight; 20905b261ecSmrg 21005b261ecSmrg /* Invalid input checking */ 21105b261ecSmrg if (pWin==NULL || lParam==0) 21205b261ecSmrg return FALSE; 21305b261ecSmrg 21405b261ecSmrg /* No size hints, no checking */ 21505b261ecSmrg if (!winMultiWindowGetWMNormalHints (pWin, &sizeHints)) 21605b261ecSmrg return FALSE; 21705b261ecSmrg 21805b261ecSmrg /* Avoid divide-by-zero */ 21905b261ecSmrg if (sizeHints.flags & PResizeInc) 22005b261ecSmrg { 22105b261ecSmrg if (sizeHints.width_inc == 0) sizeHints.width_inc = 1; 22205b261ecSmrg if (sizeHints.height_inc == 0) sizeHints.height_inc = 1; 22305b261ecSmrg } 22405b261ecSmrg 22505b261ecSmrg rect = (RECT*)lParam; 22605b261ecSmrg 22705b261ecSmrg iWidth = rect->right - rect->left; 22805b261ecSmrg iHeight = rect->bottom - rect->top; 22905b261ecSmrg 23005b261ecSmrg /* Now remove size of any borders */ 23105b261ecSmrg iWidth -= 2 * GetSystemMetrics(SM_CXSIZEFRAME); 23205b261ecSmrg iHeight -= (GetSystemMetrics(SM_CYCAPTION) 23305b261ecSmrg + 2 * GetSystemMetrics(SM_CYSIZEFRAME)); 23405b261ecSmrg 23505b261ecSmrg 23605b261ecSmrg /* Constrain the size to legal values */ 23705b261ecSmrg ConstrainSize (sizeHints, &iWidth, &iHeight); 23805b261ecSmrg 23905b261ecSmrg /* Add back the borders */ 24005b261ecSmrg iWidth += 2 * GetSystemMetrics(SM_CXSIZEFRAME); 24105b261ecSmrg iHeight += (GetSystemMetrics(SM_CYCAPTION) 24205b261ecSmrg + 2 * GetSystemMetrics(SM_CYSIZEFRAME)); 24305b261ecSmrg 24405b261ecSmrg /* Adjust size according to where we're dragging from */ 24505b261ecSmrg switch(wParam) { 24605b261ecSmrg case WMSZ_TOP: 24705b261ecSmrg case WMSZ_TOPRIGHT: 24805b261ecSmrg case WMSZ_BOTTOM: 24905b261ecSmrg case WMSZ_BOTTOMRIGHT: 25005b261ecSmrg case WMSZ_RIGHT: 25105b261ecSmrg rect->right = rect->left + iWidth; 25205b261ecSmrg break; 25305b261ecSmrg default: 25405b261ecSmrg rect->left = rect->right - iWidth; 25505b261ecSmrg break; 25605b261ecSmrg } 25705b261ecSmrg switch(wParam) { 25805b261ecSmrg case WMSZ_BOTTOM: 25905b261ecSmrg case WMSZ_BOTTOMRIGHT: 26005b261ecSmrg case WMSZ_BOTTOMLEFT: 26105b261ecSmrg case WMSZ_RIGHT: 26205b261ecSmrg case WMSZ_LEFT: 26305b261ecSmrg rect->bottom = rect->top + iHeight; 26405b261ecSmrg break; 26505b261ecSmrg default: 26605b261ecSmrg rect->top = rect->bottom - iHeight; 26705b261ecSmrg break; 26805b261ecSmrg } 26905b261ecSmrg return TRUE; 27005b261ecSmrg} 27105b261ecSmrg 27205b261ecSmrgextern Bool winInDestroyWindowsWindow; 27305b261ecSmrgstatic Bool winInRaiseWindow = FALSE; 27405b261ecSmrgstatic void winRaiseWindow(WindowPtr pWin) 27505b261ecSmrg{ 27605b261ecSmrg if (!winInDestroyWindowsWindow && !winInRaiseWindow) 27705b261ecSmrg { 27805b261ecSmrg BOOL oldstate = winInRaiseWindow; 27905b261ecSmrg winInRaiseWindow = TRUE; 28005b261ecSmrg /* Call configure window directly to make sure it gets processed 28105b261ecSmrg * in time 28205b261ecSmrg */ 28305b261ecSmrg XID vlist[1] = { 0 }; 28405b261ecSmrg ConfigureWindow(pWin, CWStackMode, vlist, serverClient); 28505b261ecSmrg winInRaiseWindow = oldstate; 28605b261ecSmrg } 28705b261ecSmrg} 28805b261ecSmrg 28905b261ecSmrg 29005b261ecSmrg/* 29105b261ecSmrg * winTopLevelWindowProc - Window procedure for all top-level Windows windows. 29205b261ecSmrg */ 29305b261ecSmrg 29405b261ecSmrgLRESULT CALLBACK 29505b261ecSmrgwinTopLevelWindowProc (HWND hwnd, UINT message, 29605b261ecSmrg WPARAM wParam, LPARAM lParam) 29705b261ecSmrg{ 29805b261ecSmrg POINT ptMouse; 29905b261ecSmrg HDC hdcUpdate; 30005b261ecSmrg PAINTSTRUCT ps; 30105b261ecSmrg WindowPtr pWin = NULL; 30205b261ecSmrg winPrivWinPtr pWinPriv = NULL; 30305b261ecSmrg ScreenPtr s_pScreen = NULL; 30405b261ecSmrg winPrivScreenPtr s_pScreenPriv = NULL; 30505b261ecSmrg winScreenInfo *s_pScreenInfo = NULL; 30605b261ecSmrg HWND hwndScreen = NULL; 30705b261ecSmrg DrawablePtr pDraw = NULL; 30805b261ecSmrg winWMMessageRec wmMsg; 30905b261ecSmrg Bool fWMMsgInitialized = FALSE; 31005b261ecSmrg static Bool s_fTracking = FALSE; 31105b261ecSmrg Bool needRestack = FALSE; 31205b261ecSmrg LRESULT ret; 31305b261ecSmrg 31405b261ecSmrg#if CYGDEBUG 31505b261ecSmrg winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam, lParam); 31605b261ecSmrg#endif 31705b261ecSmrg 31805b261ecSmrg /* Check if the Windows window property for our X window pointer is valid */ 31905b261ecSmrg if ((pWin = GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) 32005b261ecSmrg { 32105b261ecSmrg /* Our X window pointer is valid */ 32205b261ecSmrg 32305b261ecSmrg /* Get pointers to the drawable and the screen */ 32405b261ecSmrg pDraw = &pWin->drawable; 32505b261ecSmrg s_pScreen = pWin->drawable.pScreen; 32605b261ecSmrg 32705b261ecSmrg /* Get a pointer to our window privates */ 32805b261ecSmrg pWinPriv = winGetWindowPriv(pWin); 32905b261ecSmrg 33005b261ecSmrg /* Get pointers to our screen privates and screen info */ 33105b261ecSmrg s_pScreenPriv = pWinPriv->pScreenPriv; 33205b261ecSmrg s_pScreenInfo = s_pScreenPriv->pScreenInfo; 33305b261ecSmrg 33405b261ecSmrg /* Get the handle for our screen-sized window */ 33505b261ecSmrg hwndScreen = s_pScreenPriv->hwndScreen; 33605b261ecSmrg 33705b261ecSmrg /* */ 33805b261ecSmrg wmMsg.msg = 0; 33905b261ecSmrg wmMsg.hwndWindow = hwnd; 34005b261ecSmrg wmMsg.iWindow = (Window)GetProp (hwnd, WIN_WID_PROP); 34105b261ecSmrg 34205b261ecSmrg wmMsg.iX = pDraw->x; 34305b261ecSmrg wmMsg.iY = pDraw->y; 34405b261ecSmrg wmMsg.iWidth = pDraw->width; 34505b261ecSmrg wmMsg.iHeight = pDraw->height; 34605b261ecSmrg 34705b261ecSmrg fWMMsgInitialized = TRUE; 34805b261ecSmrg 34905b261ecSmrg#if 0 35005b261ecSmrg /* 35105b261ecSmrg * Print some debugging information 35205b261ecSmrg */ 35305b261ecSmrg 35405b261ecSmrg ErrorF ("hWnd %08X\n", hwnd); 35505b261ecSmrg ErrorF ("pWin %08X\n", pWin); 35605b261ecSmrg ErrorF ("pDraw %08X\n", pDraw); 35705b261ecSmrg ErrorF ("\ttype %08X\n", pWin->drawable.type); 35805b261ecSmrg ErrorF ("\tclass %08X\n", pWin->drawable.class); 35905b261ecSmrg ErrorF ("\tdepth %08X\n", pWin->drawable.depth); 36005b261ecSmrg ErrorF ("\tbitsPerPixel %08X\n", pWin->drawable.bitsPerPixel); 36105b261ecSmrg ErrorF ("\tid %08X\n", pWin->drawable.id); 36205b261ecSmrg ErrorF ("\tx %08X\n", pWin->drawable.x); 36305b261ecSmrg ErrorF ("\ty %08X\n", pWin->drawable.y); 36405b261ecSmrg ErrorF ("\twidth %08X\n", pWin->drawable.width); 36505b261ecSmrg ErrorF ("\thenght %08X\n", pWin->drawable.height); 36605b261ecSmrg ErrorF ("\tpScreen %08X\n", pWin->drawable.pScreen); 36705b261ecSmrg ErrorF ("\tserialNumber %08X\n", pWin->drawable.serialNumber); 36805b261ecSmrg ErrorF ("g_iWindowPrivateIndex %d\n", g_iWindowPrivateIndex); 36905b261ecSmrg ErrorF ("pWinPriv %08X\n", pWinPriv); 37005b261ecSmrg ErrorF ("s_pScreenPriv %08X\n", s_pScreenPriv); 37105b261ecSmrg ErrorF ("s_pScreenInfo %08X\n", s_pScreenInfo); 37205b261ecSmrg ErrorF ("hwndScreen %08X\n", hwndScreen); 37305b261ecSmrg#endif 37405b261ecSmrg } 37505b261ecSmrg 37605b261ecSmrg /* Branch on message type */ 37705b261ecSmrg switch (message) 37805b261ecSmrg { 37905b261ecSmrg case WM_CREATE: 38005b261ecSmrg 38105b261ecSmrg /* */ 38205b261ecSmrg SetProp (hwnd, 38305b261ecSmrg WIN_WINDOW_PROP, 38405b261ecSmrg (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams); 38505b261ecSmrg 38605b261ecSmrg /* */ 38705b261ecSmrg SetProp (hwnd, 38805b261ecSmrg WIN_WID_PROP, 38905b261ecSmrg (HANDLE)winGetWindowID (((LPCREATESTRUCT) lParam)->lpCreateParams)); 39005b261ecSmrg 39105b261ecSmrg /* 39205b261ecSmrg * Make X windows' Z orders sync with Windows windows because 39305b261ecSmrg * there can be AlwaysOnTop windows overlapped on the window 39405b261ecSmrg * currently being created. 39505b261ecSmrg */ 39605b261ecSmrg winReorderWindowsMultiWindow (); 39705b261ecSmrg 39805b261ecSmrg /* Fix a 'round title bar corner background should be transparent not black' problem when first painted */ 39905b261ecSmrg RECT rWindow; 40005b261ecSmrg HRGN hRgnWindow; 40105b261ecSmrg GetWindowRect(hwnd, &rWindow); 40205b261ecSmrg hRgnWindow = CreateRectRgnIndirect(&rWindow); 40305b261ecSmrg SetWindowRgn (hwnd, hRgnWindow, TRUE); 40405b261ecSmrg DeleteObject(hRgnWindow); 40505b261ecSmrg 40605b261ecSmrg return 0; 40705b261ecSmrg 40805b261ecSmrg case WM_INIT_SYS_MENU: 40905b261ecSmrg /* 41005b261ecSmrg * Add whatever the setup file wants to for this window 41105b261ecSmrg */ 41205b261ecSmrg SetupSysMenu ((unsigned long)hwnd); 41305b261ecSmrg return 0; 41405b261ecSmrg 41505b261ecSmrg case WM_SYSCOMMAND: 41605b261ecSmrg /* 41705b261ecSmrg * Any window menu items go through here 41805b261ecSmrg */ 41905b261ecSmrg if (HandleCustomWM_COMMAND ((unsigned long)hwnd, LOWORD(wParam))) 42005b261ecSmrg { 42105b261ecSmrg /* Don't pass customized menus to DefWindowProc */ 42205b261ecSmrg return 0; 42305b261ecSmrg } 42405b261ecSmrg if (wParam == SC_RESTORE || wParam == SC_MAXIMIZE) 42505b261ecSmrg { 42605b261ecSmrg WINDOWPLACEMENT wndpl; 42705b261ecSmrg wndpl.length = sizeof(wndpl); 42805b261ecSmrg if (GetWindowPlacement(hwnd, &wndpl) && wndpl.showCmd == SW_SHOWMINIMIZED) 42905b261ecSmrg needRestack = TRUE; 43005b261ecSmrg } 43105b261ecSmrg break; 43205b261ecSmrg 43305b261ecSmrg case WM_INITMENU: 43405b261ecSmrg /* Checks/Unchecks any menu items before they are displayed */ 43505b261ecSmrg HandleCustomWM_INITMENU ((unsigned long)hwnd, wParam); 43605b261ecSmrg break; 43705b261ecSmrg 43805b261ecSmrg case WM_PAINT: 43905b261ecSmrg /* Only paint if our window handle is valid */ 44005b261ecSmrg if (hwndScreen == NULL) 44105b261ecSmrg break; 44205b261ecSmrg 44305b261ecSmrg /* BeginPaint gives us an hdc that clips to the invalidated region */ 44405b261ecSmrg hdcUpdate = BeginPaint (hwnd, &ps); 44505b261ecSmrg /* Avoid the BitBlt's if the PAINTSTRUCT is bogus */ 44605b261ecSmrg if (ps.rcPaint.right==0 && ps.rcPaint.bottom==0 && ps.rcPaint.left==0 && ps.rcPaint.top==0) 44705b261ecSmrg { 44805b261ecSmrg EndPaint (hwnd, &ps); 44905b261ecSmrg return 0; 45005b261ecSmrg } 45105b261ecSmrg 45205b261ecSmrg /* Try to copy from the shadow buffer */ 45305b261ecSmrg if (!BitBlt (hdcUpdate, 45405b261ecSmrg ps.rcPaint.left, ps.rcPaint.top, 45505b261ecSmrg ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, 45605b261ecSmrg s_pScreenPriv->hdcShadow, 45705b261ecSmrg ps.rcPaint.left + pWin->drawable.x, ps.rcPaint.top + pWin->drawable.y, 45805b261ecSmrg SRCCOPY)) 45905b261ecSmrg { 46005b261ecSmrg LPVOID lpMsgBuf; 46105b261ecSmrg 46205b261ecSmrg /* Display a fancy error message */ 46305b261ecSmrg FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | 46405b261ecSmrg FORMAT_MESSAGE_FROM_SYSTEM | 46505b261ecSmrg FORMAT_MESSAGE_IGNORE_INSERTS, 46605b261ecSmrg NULL, 46705b261ecSmrg GetLastError (), 46805b261ecSmrg MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 46905b261ecSmrg (LPTSTR) &lpMsgBuf, 47005b261ecSmrg 0, NULL); 47105b261ecSmrg 47205b261ecSmrg ErrorF ("winTopLevelWindowProc - BitBlt failed: %s\n", 47305b261ecSmrg (LPSTR)lpMsgBuf); 47405b261ecSmrg LocalFree (lpMsgBuf); 47505b261ecSmrg } 47605b261ecSmrg 47705b261ecSmrg /* EndPaint frees the DC */ 47805b261ecSmrg EndPaint (hwnd, &ps); 47905b261ecSmrg return 0; 48005b261ecSmrg 48105b261ecSmrg case WM_MOUSEMOVE: 48205b261ecSmrg /* Unpack the client area mouse coordinates */ 48305b261ecSmrg ptMouse.x = GET_X_LPARAM(lParam); 48405b261ecSmrg ptMouse.y = GET_Y_LPARAM(lParam); 48505b261ecSmrg 48605b261ecSmrg /* Translate the client area mouse coordinates to screen coordinates */ 48705b261ecSmrg ClientToScreen (hwnd, &ptMouse); 48805b261ecSmrg 48905b261ecSmrg /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */ 49005b261ecSmrg ptMouse.x -= GetSystemMetrics (SM_XVIRTUALSCREEN); 49105b261ecSmrg ptMouse.y -= GetSystemMetrics (SM_YVIRTUALSCREEN); 49205b261ecSmrg 49305b261ecSmrg /* We can't do anything without privates */ 49405b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 49505b261ecSmrg break; 49605b261ecSmrg 49705b261ecSmrg /* Has the mouse pointer crossed screens? */ 49805b261ecSmrg if (s_pScreen != miPointerGetScreen(inputInfo.pointer)) 49905b261ecSmrg miPointerSetScreen (inputInfo.pointer, s_pScreenInfo->dwScreen, 50005b261ecSmrg ptMouse.x - s_pScreenInfo->dwXOffset, 50105b261ecSmrg ptMouse.y - s_pScreenInfo->dwYOffset); 50205b261ecSmrg 50305b261ecSmrg /* Are we tracking yet? */ 50405b261ecSmrg if (!s_fTracking) 50505b261ecSmrg { 50605b261ecSmrg TRACKMOUSEEVENT tme; 50705b261ecSmrg 50805b261ecSmrg /* Setup data structure */ 50905b261ecSmrg ZeroMemory (&tme, sizeof (tme)); 51005b261ecSmrg tme.cbSize = sizeof (tme); 51105b261ecSmrg tme.dwFlags = TME_LEAVE; 51205b261ecSmrg tme.hwndTrack = hwnd; 51305b261ecSmrg 51405b261ecSmrg /* Call the tracking function */ 51505b261ecSmrg if (!(*g_fpTrackMouseEvent) (&tme)) 51605b261ecSmrg ErrorF ("winTopLevelWindowProc - _TrackMouseEvent failed\n"); 51705b261ecSmrg 51805b261ecSmrg /* Flag that we are tracking now */ 51905b261ecSmrg s_fTracking = TRUE; 52005b261ecSmrg } 52105b261ecSmrg 52205b261ecSmrg /* Hide or show the Windows mouse cursor */ 52305b261ecSmrg if (g_fSoftwareCursor && g_fCursor) 52405b261ecSmrg { 52505b261ecSmrg /* Hide Windows cursor */ 52605b261ecSmrg g_fCursor = FALSE; 52705b261ecSmrg ShowCursor (FALSE); 52805b261ecSmrg } 52905b261ecSmrg 53005b261ecSmrg /* Kill the timer used to poll mouse events */ 53105b261ecSmrg if (g_uipMousePollingTimerID != 0) 53205b261ecSmrg { 53305b261ecSmrg KillTimer (s_pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID); 53405b261ecSmrg g_uipMousePollingTimerID = 0; 53505b261ecSmrg } 53605b261ecSmrg 53705b261ecSmrg /* Deliver absolute cursor position to X Server */ 53805b261ecSmrg miPointerAbsoluteCursor (ptMouse.x - s_pScreenInfo->dwXOffset, 53905b261ecSmrg ptMouse.y - s_pScreenInfo->dwYOffset, 54005b261ecSmrg g_c32LastInputEventTime = GetTickCount ()); 54105b261ecSmrg return 0; 54205b261ecSmrg 54305b261ecSmrg case WM_NCMOUSEMOVE: 54405b261ecSmrg /* 54505b261ecSmrg * We break instead of returning 0 since we need to call 54605b261ecSmrg * DefWindowProc to get the mouse cursor changes 54705b261ecSmrg * and min/max/close button highlighting in Windows XP. 54805b261ecSmrg * The Platform SDK says that you should return 0 if you 54905b261ecSmrg * process this message, but it fails to mention that you 55005b261ecSmrg * will give up any default functionality if you do return 0. 55105b261ecSmrg */ 55205b261ecSmrg 55305b261ecSmrg /* We can't do anything without privates */ 55405b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 55505b261ecSmrg break; 55605b261ecSmrg 55705b261ecSmrg /* Non-client mouse movement, show Windows cursor */ 55805b261ecSmrg if (g_fSoftwareCursor && !g_fCursor) 55905b261ecSmrg { 56005b261ecSmrg g_fCursor = TRUE; 56105b261ecSmrg ShowCursor (TRUE); 56205b261ecSmrg } 56305b261ecSmrg 56405b261ecSmrg /* 56505b261ecSmrg * Timer to poll mouse events. This is needed to make 56605b261ecSmrg * programs like xeyes follow the mouse properly. 56705b261ecSmrg */ 56805b261ecSmrg if (g_uipMousePollingTimerID == 0) 56905b261ecSmrg g_uipMousePollingTimerID = SetTimer (s_pScreenPriv->hwndScreen, 57005b261ecSmrg WIN_POLLING_MOUSE_TIMER_ID, 57105b261ecSmrg MOUSE_POLLING_INTERVAL, 57205b261ecSmrg NULL); 57305b261ecSmrg break; 57405b261ecSmrg 57505b261ecSmrg case WM_MOUSELEAVE: 57605b261ecSmrg /* Mouse has left our client area */ 57705b261ecSmrg 57805b261ecSmrg /* Flag that we are no longer tracking */ 57905b261ecSmrg s_fTracking = FALSE; 58005b261ecSmrg 58105b261ecSmrg /* Show the mouse cursor, if necessary */ 58205b261ecSmrg if (g_fSoftwareCursor && !g_fCursor) 58305b261ecSmrg { 58405b261ecSmrg g_fCursor = TRUE; 58505b261ecSmrg ShowCursor (TRUE); 58605b261ecSmrg } 58705b261ecSmrg 58805b261ecSmrg /* 58905b261ecSmrg * Timer to poll mouse events. This is needed to make 59005b261ecSmrg * programs like xeyes follow the mouse properly. 59105b261ecSmrg */ 59205b261ecSmrg if (g_uipMousePollingTimerID == 0) 59305b261ecSmrg g_uipMousePollingTimerID = SetTimer (s_pScreenPriv->hwndScreen, 59405b261ecSmrg WIN_POLLING_MOUSE_TIMER_ID, 59505b261ecSmrg MOUSE_POLLING_INTERVAL, 59605b261ecSmrg NULL); 59705b261ecSmrg return 0; 59805b261ecSmrg 59905b261ecSmrg case WM_LBUTTONDBLCLK: 60005b261ecSmrg case WM_LBUTTONDOWN: 60105b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 60205b261ecSmrg break; 60305b261ecSmrg g_fButton[0] = TRUE; 60405b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam); 60505b261ecSmrg 60605b261ecSmrg case WM_LBUTTONUP: 60705b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 60805b261ecSmrg break; 60905b261ecSmrg g_fButton[0] = FALSE; 61005b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam); 61105b261ecSmrg 61205b261ecSmrg case WM_MBUTTONDBLCLK: 61305b261ecSmrg case WM_MBUTTONDOWN: 61405b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 61505b261ecSmrg break; 61605b261ecSmrg g_fButton[1] = TRUE; 61705b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam); 61805b261ecSmrg 61905b261ecSmrg case WM_MBUTTONUP: 62005b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 62105b261ecSmrg break; 62205b261ecSmrg g_fButton[1] = FALSE; 62305b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam); 62405b261ecSmrg 62505b261ecSmrg case WM_RBUTTONDBLCLK: 62605b261ecSmrg case WM_RBUTTONDOWN: 62705b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 62805b261ecSmrg break; 62905b261ecSmrg g_fButton[2] = TRUE; 63005b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam); 63105b261ecSmrg 63205b261ecSmrg case WM_RBUTTONUP: 63305b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 63405b261ecSmrg break; 63505b261ecSmrg g_fButton[2] = FALSE; 63605b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam); 63705b261ecSmrg 63805b261ecSmrg case WM_XBUTTONDBLCLK: 63905b261ecSmrg case WM_XBUTTONDOWN: 64005b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 64105b261ecSmrg break; 64205b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonPress, HIWORD(wParam) + 5, wParam); 64305b261ecSmrg case WM_XBUTTONUP: 64405b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 64505b261ecSmrg break; 64605b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam); 64705b261ecSmrg 64805b261ecSmrg case WM_MOUSEWHEEL: 64905b261ecSmrg 65005b261ecSmrg /* Pass the message to the root window */ 65105b261ecSmrg SendMessage (hwndScreen, message, wParam, lParam); 65205b261ecSmrg return 0; 65305b261ecSmrg 65405b261ecSmrg case WM_SETFOCUS: 65505b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 65605b261ecSmrg break; 65705b261ecSmrg 65805b261ecSmrg winRestoreModeKeyStates (); 65905b261ecSmrg 66005b261ecSmrg /* Add the keyboard hook if possible */ 66105b261ecSmrg if (g_fKeyboardHookLL) 66205b261ecSmrg g_fKeyboardHookLL = winInstallKeyboardHookLL (); 66305b261ecSmrg return 0; 66405b261ecSmrg 66505b261ecSmrg case WM_KILLFOCUS: 66605b261ecSmrg /* Pop any pressed keys since we are losing keyboard focus */ 66705b261ecSmrg winKeybdReleaseKeys (); 66805b261ecSmrg 66905b261ecSmrg /* Remove our keyboard hook if it is installed */ 67005b261ecSmrg winRemoveKeyboardHookLL (); 67105b261ecSmrg return 0; 67205b261ecSmrg 67305b261ecSmrg case WM_SYSDEADCHAR: 67405b261ecSmrg case WM_DEADCHAR: 67505b261ecSmrg /* 67605b261ecSmrg * NOTE: We do nothing with WM_*CHAR messages, 67705b261ecSmrg * nor does the root window, so we can just toss these messages. 67805b261ecSmrg */ 67905b261ecSmrg return 0; 68005b261ecSmrg 68105b261ecSmrg case WM_SYSKEYDOWN: 68205b261ecSmrg case WM_KEYDOWN: 68305b261ecSmrg 68405b261ecSmrg /* 68505b261ecSmrg * Don't pass Alt-F4 key combo to root window, 68605b261ecSmrg * let Windows translate to WM_CLOSE and close this top-level window. 68705b261ecSmrg * 68805b261ecSmrg * NOTE: We purposely don't check the fUseWinKillKey setting because 68905b261ecSmrg * it should only apply to the key handling for the root window, 69005b261ecSmrg * not for top-level window-manager windows. 69105b261ecSmrg * 69205b261ecSmrg * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window 69305b261ecSmrg * because that is a key combo that no X app should be expecting to 69405b261ecSmrg * receive, since it has historically been used to shutdown the X server. 69505b261ecSmrg * Passing Ctrl-Alt-Backspace to the root window preserves that 69605b261ecSmrg * behavior, assuming that -unixkill has been passed as a parameter. 69705b261ecSmrg */ 69805b261ecSmrg if (wParam == VK_F4 && (GetKeyState (VK_MENU) & 0x8000)) 69905b261ecSmrg break; 70005b261ecSmrg 70105b261ecSmrg#if CYGWINDOWING_DEBUG 70205b261ecSmrg if (wParam == VK_ESCAPE) 70305b261ecSmrg { 70405b261ecSmrg /* Place for debug: put any tests and dumps here */ 70505b261ecSmrg WINDOWPLACEMENT windPlace; 70605b261ecSmrg RECT rc; 70705b261ecSmrg LPRECT pRect; 70805b261ecSmrg 70905b261ecSmrg windPlace.length = sizeof (WINDOWPLACEMENT); 71005b261ecSmrg GetWindowPlacement (hwnd, &windPlace); 71105b261ecSmrg pRect = &windPlace.rcNormalPosition; 71205b261ecSmrg ErrorF ("\nCYGWINDOWING Dump:\n" 71305b261ecSmrg "\tdrawable: (%hd, %hd) - %hdx%hd\n", pDraw->x, 71405b261ecSmrg pDraw->y, pDraw->width, pDraw->height); 71505b261ecSmrg ErrorF ("\twindPlace: (%ld, %ld) - %ldx%ld\n", pRect->left, 71605b261ecSmrg pRect->top, pRect->right - pRect->left, 71705b261ecSmrg pRect->bottom - pRect->top); 71805b261ecSmrg if (GetClientRect (hwnd, &rc)) 71905b261ecSmrg { 72005b261ecSmrg pRect = &rc; 72105b261ecSmrg ErrorF ("\tClientRect: (%ld, %ld) - %ldx%ld\n", pRect->left, 72205b261ecSmrg pRect->top, pRect->right - pRect->left, 72305b261ecSmrg pRect->bottom - pRect->top); 72405b261ecSmrg } 72505b261ecSmrg if (GetWindowRect (hwnd, &rc)) 72605b261ecSmrg { 72705b261ecSmrg pRect = &rc; 72805b261ecSmrg ErrorF ("\tWindowRect: (%ld, %ld) - %ldx%ld\n", pRect->left, 72905b261ecSmrg pRect->top, pRect->right - pRect->left, 73005b261ecSmrg pRect->bottom - pRect->top); 73105b261ecSmrg } 73205b261ecSmrg ErrorF ("\n"); 73305b261ecSmrg } 73405b261ecSmrg#endif 73505b261ecSmrg 73605b261ecSmrg /* Pass the message to the root window */ 73705b261ecSmrg return winWindowProc(hwndScreen, message, wParam, lParam); 73805b261ecSmrg 73905b261ecSmrg case WM_SYSKEYUP: 74005b261ecSmrg case WM_KEYUP: 74105b261ecSmrg 74205b261ecSmrg 74305b261ecSmrg /* Pass the message to the root window */ 74405b261ecSmrg return winWindowProc(hwndScreen, message, wParam, lParam); 74505b261ecSmrg 74605b261ecSmrg case WM_HOTKEY: 74705b261ecSmrg 74805b261ecSmrg /* Pass the message to the root window */ 74905b261ecSmrg SendMessage (hwndScreen, message, wParam, lParam); 75005b261ecSmrg return 0; 75105b261ecSmrg 75205b261ecSmrg case WM_ACTIVATE: 75305b261ecSmrg 75405b261ecSmrg /* Pass the message to the root window */ 75505b261ecSmrg SendMessage (hwndScreen, message, wParam, lParam); 75605b261ecSmrg 75705b261ecSmrg if (LOWORD(wParam) != WA_INACTIVE) 75805b261ecSmrg { 75905b261ecSmrg /* Raise the window to the top in Z order */ 76005b261ecSmrg /* ago: Activate does not mean putting it to front! */ 76105b261ecSmrg /* 76205b261ecSmrg wmMsg.msg = WM_WM_RAISE; 76305b261ecSmrg if (fWMMsgInitialized) 76405b261ecSmrg winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); 76505b261ecSmrg */ 76605b261ecSmrg 76705b261ecSmrg /* Tell our Window Manager thread to activate the window */ 76805b261ecSmrg wmMsg.msg = WM_WM_ACTIVATE; 76905b261ecSmrg if (fWMMsgInitialized) 77005b261ecSmrg if (!pWin || !pWin->overrideRedirect) /* for OOo menus */ 77105b261ecSmrg winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); 77205b261ecSmrg } 77305b261ecSmrg return 0; 77405b261ecSmrg 77505b261ecSmrg case WM_ACTIVATEAPP: 77605b261ecSmrg /* 77705b261ecSmrg * This message is also sent to the root window 77805b261ecSmrg * so we do nothing for individual multiwindow windows 77905b261ecSmrg */ 78005b261ecSmrg break; 78105b261ecSmrg 78205b261ecSmrg case WM_CLOSE: 78305b261ecSmrg /* Branch on if the window was killed in X already */ 78405b261ecSmrg if (pWinPriv->fXKilled) 78505b261ecSmrg { 78605b261ecSmrg /* Window was killed, go ahead and destroy the window */ 78705b261ecSmrg DestroyWindow (hwnd); 78805b261ecSmrg } 78905b261ecSmrg else 79005b261ecSmrg { 79105b261ecSmrg /* Tell our Window Manager thread to kill the window */ 79205b261ecSmrg wmMsg.msg = WM_WM_KILL; 79305b261ecSmrg if (fWMMsgInitialized) 79405b261ecSmrg winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); 79505b261ecSmrg } 79605b261ecSmrg return 0; 79705b261ecSmrg 79805b261ecSmrg case WM_DESTROY: 79905b261ecSmrg 80005b261ecSmrg /* Branch on if the window was killed in X already */ 80105b261ecSmrg if (pWinPriv && !pWinPriv->fXKilled) 80205b261ecSmrg { 80305b261ecSmrg ErrorF ("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n"); 80405b261ecSmrg 80505b261ecSmrg /* Tell our Window Manager thread to kill the window */ 80605b261ecSmrg wmMsg.msg = WM_WM_KILL; 80705b261ecSmrg if (fWMMsgInitialized) 80805b261ecSmrg winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); 80905b261ecSmrg } 81005b261ecSmrg 81105b261ecSmrg RemoveProp (hwnd, WIN_WINDOW_PROP); 81205b261ecSmrg RemoveProp (hwnd, WIN_WID_PROP); 81305b261ecSmrg RemoveProp (hwnd, WIN_NEEDMANAGE_PROP); 81405b261ecSmrg 81505b261ecSmrg break; 81605b261ecSmrg 81705b261ecSmrg case WM_MOVE: 81805b261ecSmrg /* Adjust the X Window to the moved Windows window */ 81905b261ecSmrg winAdjustXWindow (pWin, hwnd); 82005b261ecSmrg return 0; 82105b261ecSmrg 82205b261ecSmrg case WM_SHOWWINDOW: 82305b261ecSmrg /* Bail out if the window is being hidden */ 82405b261ecSmrg if (!wParam) 82505b261ecSmrg return 0; 82605b261ecSmrg 82705b261ecSmrg /* Tell X to map the window */ 82805b261ecSmrg MapWindow (pWin, wClient(pWin)); 82905b261ecSmrg 83005b261ecSmrg /* */ 83105b261ecSmrg if (!pWin->overrideRedirect) 83205b261ecSmrg { 83305b261ecSmrg DWORD dwExStyle; 83405b261ecSmrg DWORD dwStyle; 83505b261ecSmrg RECT rcNew; 83605b261ecSmrg int iDx, iDy; 83705b261ecSmrg 83805b261ecSmrg /* Flag that this window needs to be made active when clicked */ 83905b261ecSmrg SetProp (hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1); 84005b261ecSmrg 84105b261ecSmrg /* Get the standard and extended window style information */ 84205b261ecSmrg dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE); 84305b261ecSmrg dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE); 84405b261ecSmrg 84505b261ecSmrg /* */ 84605b261ecSmrg if (dwExStyle != WS_EX_APPWINDOW) 84705b261ecSmrg { 84805b261ecSmrg /* Setup a rectangle with the X window position and size */ 84905b261ecSmrg SetRect (&rcNew, 85005b261ecSmrg pDraw->x, 85105b261ecSmrg pDraw->y, 85205b261ecSmrg pDraw->x + pDraw->width, 85305b261ecSmrg pDraw->y + pDraw->height); 85405b261ecSmrg 85505b261ecSmrg#if 0 85605b261ecSmrg ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n", 85705b261ecSmrg rcNew.left, rcNew.top, 85805b261ecSmrg rcNew.right, rcNew.bottom); 85905b261ecSmrg#endif 86005b261ecSmrg 86105b261ecSmrg /* */ 86205b261ecSmrg AdjustWindowRectEx (&rcNew, 86305b261ecSmrg WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW, 86405b261ecSmrg FALSE, 86505b261ecSmrg WS_EX_APPWINDOW); 86605b261ecSmrg 86705b261ecSmrg /* Calculate position deltas */ 86805b261ecSmrg iDx = pDraw->x - rcNew.left; 86905b261ecSmrg iDy = pDraw->y - rcNew.top; 87005b261ecSmrg 87105b261ecSmrg /* Calculate new rectangle */ 87205b261ecSmrg rcNew.left += iDx; 87305b261ecSmrg rcNew.right += iDx; 87405b261ecSmrg rcNew.top += iDy; 87505b261ecSmrg rcNew.bottom += iDy; 87605b261ecSmrg 87705b261ecSmrg#if 0 87805b261ecSmrg ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n", 87905b261ecSmrg rcNew.left, rcNew.top, 88005b261ecSmrg rcNew.right, rcNew.bottom); 88105b261ecSmrg#endif 88205b261ecSmrg 88305b261ecSmrg /* Set the window extended style flags */ 88405b261ecSmrg SetWindowLongPtr (hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW); 88505b261ecSmrg 88605b261ecSmrg /* Set the window standard style flags */ 88705b261ecSmrg SetWindowLongPtr (hwnd, GWL_STYLE, 88805b261ecSmrg WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW); 88905b261ecSmrg 89005b261ecSmrg /* Position the Windows window */ 89105b261ecSmrg SetWindowPos (hwnd, HWND_TOP, 89205b261ecSmrg rcNew.left, rcNew.top, 89305b261ecSmrg rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, 89405b261ecSmrg SWP_NOMOVE | SWP_FRAMECHANGED 89505b261ecSmrg | SWP_SHOWWINDOW | SWP_NOACTIVATE); 89605b261ecSmrg 89705b261ecSmrg /* Bring the Windows window to the foreground */ 89805b261ecSmrg SetForegroundWindow (hwnd); 89905b261ecSmrg } 90005b261ecSmrg } 90105b261ecSmrg else /* It is an overridden window so make it top of Z stack */ 90205b261ecSmrg { 90305b261ecSmrg#if CYGWINDOWING_DEBUG 90405b261ecSmrg ErrorF ("overridden window is shown\n"); 90505b261ecSmrg#endif 90605b261ecSmrg SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0, 90705b261ecSmrg SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 90805b261ecSmrg } 90905b261ecSmrg 91005b261ecSmrg /* Setup the Window Manager message */ 91105b261ecSmrg wmMsg.msg = WM_WM_MAP; 91205b261ecSmrg wmMsg.iWidth = pDraw->width; 91305b261ecSmrg wmMsg.iHeight = pDraw->height; 91405b261ecSmrg 91505b261ecSmrg /* Tell our Window Manager thread to map the window */ 91605b261ecSmrg if (fWMMsgInitialized) 91705b261ecSmrg winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); 91805b261ecSmrg 91905b261ecSmrg return 0; 92005b261ecSmrg 92105b261ecSmrg case WM_SIZING: 92205b261ecSmrg /* Need to legalize the size according to WM_NORMAL_HINTS */ 92305b261ecSmrg /* for applications like xterm */ 92405b261ecSmrg return ValidateSizing (hwnd, pWin, wParam, lParam); 92505b261ecSmrg 92605b261ecSmrg case WM_WINDOWPOSCHANGED: 92705b261ecSmrg { 92805b261ecSmrg LPWINDOWPOS pWinPos = (LPWINDOWPOS) lParam; 92905b261ecSmrg 93005b261ecSmrg if (!(pWinPos->flags & SWP_NOZORDER)) 93105b261ecSmrg { 93205b261ecSmrg#if CYGWINDOWING_DEBUG 93305b261ecSmrg winDebug ("\twindow z order was changed\n"); 93405b261ecSmrg#endif 93505b261ecSmrg if (pWinPos->hwndInsertAfter == HWND_TOP 93605b261ecSmrg ||pWinPos->hwndInsertAfter == HWND_TOPMOST 93705b261ecSmrg ||pWinPos->hwndInsertAfter == HWND_NOTOPMOST) 93805b261ecSmrg { 93905b261ecSmrg#if CYGWINDOWING_DEBUG 94005b261ecSmrg winDebug ("\traise to top\n"); 94105b261ecSmrg#endif 94205b261ecSmrg /* Raise the window to the top in Z order */ 94305b261ecSmrg winRaiseWindow(pWin); 94405b261ecSmrg } 94505b261ecSmrg else if (pWinPos->hwndInsertAfter == HWND_BOTTOM) 94605b261ecSmrg { 94705b261ecSmrg } 94805b261ecSmrg else 94905b261ecSmrg { 95005b261ecSmrg /* Check if this window is top of X windows. */ 95105b261ecSmrg HWND hWndAbove = NULL; 95205b261ecSmrg DWORD dwCurrentProcessID = GetCurrentProcessId (); 95305b261ecSmrg DWORD dwWindowProcessID = 0; 95405b261ecSmrg 95505b261ecSmrg for (hWndAbove = pWinPos->hwndInsertAfter; 95605b261ecSmrg hWndAbove != NULL; 95705b261ecSmrg hWndAbove = GetNextWindow (hWndAbove, GW_HWNDPREV)) 95805b261ecSmrg { 95905b261ecSmrg /* Ignore other XWin process's window */ 96005b261ecSmrg GetWindowThreadProcessId (hWndAbove, &dwWindowProcessID); 96105b261ecSmrg 96205b261ecSmrg if ((dwWindowProcessID == dwCurrentProcessID) 96305b261ecSmrg && GetProp (hWndAbove, WIN_WINDOW_PROP) 96405b261ecSmrg && !IsWindowVisible (hWndAbove) 96505b261ecSmrg && !IsIconic (hWndAbove) ) /* ignore minimized windows */ 96605b261ecSmrg break; 96705b261ecSmrg } 96805b261ecSmrg /* If this is top of X windows in Windows stack, 96905b261ecSmrg raise it in X stack. */ 97005b261ecSmrg if (hWndAbove == NULL) 97105b261ecSmrg { 97205b261ecSmrg#if CYGWINDOWING_DEBUG 97305b261ecSmrg winDebug ("\traise to top\n"); 97405b261ecSmrg#endif 97505b261ecSmrg winRaiseWindow(pWin); 97605b261ecSmrg } 97705b261ecSmrg } 97805b261ecSmrg } 97905b261ecSmrg } 98005b261ecSmrg /* 98105b261ecSmrg * Pass the message to DefWindowProc to let the function 98205b261ecSmrg * break down WM_WINDOWPOSCHANGED to WM_MOVE and WM_SIZE. 98305b261ecSmrg */ 98405b261ecSmrg break; 98505b261ecSmrg 98605b261ecSmrg case WM_SIZE: 98705b261ecSmrg /* see dix/window.c */ 98805b261ecSmrg#if CYGWINDOWING_DEBUG 98905b261ecSmrg { 99005b261ecSmrg char buf[64]; 99105b261ecSmrg switch (wParam) 99205b261ecSmrg { 99305b261ecSmrg case SIZE_MINIMIZED: 99405b261ecSmrg strcpy(buf, "SIZE_MINIMIZED"); 99505b261ecSmrg break; 99605b261ecSmrg case SIZE_MAXIMIZED: 99705b261ecSmrg strcpy(buf, "SIZE_MAXIMIZED"); 99805b261ecSmrg break; 99905b261ecSmrg case SIZE_RESTORED: 100005b261ecSmrg strcpy(buf, "SIZE_RESTORED"); 100105b261ecSmrg break; 100205b261ecSmrg default: 100305b261ecSmrg strcpy(buf, "UNKNOWN_FLAG"); 100405b261ecSmrg } 100505b261ecSmrg ErrorF ("winTopLevelWindowProc - WM_SIZE to %dx%d (%s) - %d ms\n", 100605b261ecSmrg (int)LOWORD(lParam), (int)HIWORD(lParam), buf, 100705b261ecSmrg (int)(GetTickCount ())); 100805b261ecSmrg } 100905b261ecSmrg#endif 101005b261ecSmrg /* Adjust the X Window to the moved Windows window */ 101105b261ecSmrg winAdjustXWindow (pWin, hwnd); 101205b261ecSmrg return 0; /* end of WM_SIZE handler */ 101305b261ecSmrg 101405b261ecSmrg case WM_MOUSEACTIVATE: 101505b261ecSmrg 101605b261ecSmrg /* Check if this window needs to be made active when clicked */ 101705b261ecSmrg if (!GetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP)) 101805b261ecSmrg { 101905b261ecSmrg#if CYGMULTIWINDOW_DEBUG 102005b261ecSmrg ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE - " 102105b261ecSmrg "MA_NOACTIVATE\n"); 102205b261ecSmrg#endif 102305b261ecSmrg 102405b261ecSmrg /* */ 102505b261ecSmrg return MA_NOACTIVATE; 102605b261ecSmrg } 102705b261ecSmrg break; 102805b261ecSmrg 102905b261ecSmrg case WM_SETCURSOR: 103005b261ecSmrg if (LOWORD(lParam) == HTCLIENT) 103105b261ecSmrg { 103205b261ecSmrg if (!g_fSoftwareCursor) SetCursor (s_pScreenPriv->cursor.handle); 103305b261ecSmrg return TRUE; 103405b261ecSmrg } 103505b261ecSmrg break; 103605b261ecSmrg 103705b261ecSmrg default: 103805b261ecSmrg break; 103905b261ecSmrg } 104005b261ecSmrg 104105b261ecSmrg ret = DefWindowProc (hwnd, message, wParam, lParam); 104205b261ecSmrg /* 104305b261ecSmrg * If the window was minized we get the stack change before the window is restored 104405b261ecSmrg * and so it gets lost. Ensure there stacking order is correct. 104505b261ecSmrg */ 104605b261ecSmrg if (needRestack) 104705b261ecSmrg winReorderWindowsMultiWindow(); 104805b261ecSmrg return ret; 104905b261ecSmrg} 1050