1706f2543Smrg/* 2706f2543Smrg *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 3706f2543Smrg *Copyright (C) Colin Harrison 2005-2008 4706f2543Smrg * 5706f2543Smrg *Permission is hereby granted, free of charge, to any person obtaining 6706f2543Smrg * a copy of this software and associated documentation files (the 7706f2543Smrg *"Software"), to deal in the Software without restriction, including 8706f2543Smrg *without limitation the rights to use, copy, modify, merge, publish, 9706f2543Smrg *distribute, sublicense, and/or sell copies of the Software, and to 10706f2543Smrg *permit persons to whom the Software is furnished to do so, subject to 11706f2543Smrg *the following conditions: 12706f2543Smrg * 13706f2543Smrg *The above copyright notice and this permission notice shall be 14706f2543Smrg *included in all copies or substantial portions of the Software. 15706f2543Smrg * 16706f2543Smrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17706f2543Smrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18706f2543Smrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19706f2543Smrg *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR 20706f2543Smrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 21706f2543Smrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22706f2543Smrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23706f2543Smrg * 24706f2543Smrg *Except as contained in this notice, the name of the XFree86 Project 25706f2543Smrg *shall not be used in advertising or otherwise to promote the sale, use 26706f2543Smrg *or other dealings in this Software without prior written authorization 27706f2543Smrg *from the XFree86 Project. 28706f2543Smrg * 29706f2543Smrg * Authors: Kensuke Matsuzaki 30706f2543Smrg * Earle F. Philhower, III 31706f2543Smrg * Harold L Hunt II 32706f2543Smrg * Colin Harrison 33706f2543Smrg */ 34706f2543Smrg 35706f2543Smrg#ifdef HAVE_XWIN_CONFIG_H 36706f2543Smrg#include <xwin-config.h> 37706f2543Smrg#endif 38706f2543Smrg#include "win.h" 39706f2543Smrg#include "dixevents.h" 40706f2543Smrg#include "winmultiwindowclass.h" 41706f2543Smrg#include "winprefs.h" 42706f2543Smrg#include "winmsg.h" 43706f2543Smrg#include "inputstr.h" 44706f2543Smrg 45706f2543Smrgextern void winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle); 46706f2543Smrg 47706f2543Smrg 48706f2543Smrg/* 49706f2543Smrg * Local globals 50706f2543Smrg */ 51706f2543Smrg 52706f2543Smrgstatic UINT_PTR g_uipMousePollingTimerID = 0; 53706f2543Smrg 54706f2543Smrg 55706f2543Smrg/* 56706f2543Smrg * Constant defines 57706f2543Smrg */ 58706f2543Smrg 59706f2543Smrg#define WIN_MULTIWINDOW_SHAPE YES 60706f2543Smrg 61706f2543Smrg 62706f2543Smrg/* 63706f2543Smrg * ConstrainSize - Taken from TWM sources - Respects hints for sizing 64706f2543Smrg */ 65706f2543Smrg#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) ) 66706f2543Smrgstatic void 67706f2543SmrgConstrainSize (WinXSizeHints hints, int *widthp, int *heightp) 68706f2543Smrg{ 69706f2543Smrg int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta; 70706f2543Smrg int baseWidth, baseHeight; 71706f2543Smrg int dwidth = *widthp, dheight = *heightp; 72706f2543Smrg 73706f2543Smrg if (hints.flags & PMinSize) 74706f2543Smrg { 75706f2543Smrg minWidth = hints.min_width; 76706f2543Smrg minHeight = hints.min_height; 77706f2543Smrg } 78706f2543Smrg else if (hints.flags & PBaseSize) 79706f2543Smrg { 80706f2543Smrg minWidth = hints.base_width; 81706f2543Smrg minHeight = hints.base_height; 82706f2543Smrg } 83706f2543Smrg else 84706f2543Smrg minWidth = minHeight = 1; 85706f2543Smrg 86706f2543Smrg if (hints.flags & PBaseSize) 87706f2543Smrg { 88706f2543Smrg baseWidth = hints.base_width; 89706f2543Smrg baseHeight = hints.base_height; 90706f2543Smrg } 91706f2543Smrg else if (hints.flags & PMinSize) 92706f2543Smrg { 93706f2543Smrg baseWidth = hints.min_width; 94706f2543Smrg baseHeight = hints.min_height; 95706f2543Smrg } 96706f2543Smrg else 97706f2543Smrg baseWidth = baseHeight = 0; 98706f2543Smrg 99706f2543Smrg if (hints.flags & PMaxSize) 100706f2543Smrg { 101706f2543Smrg maxWidth = hints.max_width; 102706f2543Smrg maxHeight = hints.max_height; 103706f2543Smrg } 104706f2543Smrg else 105706f2543Smrg { 106706f2543Smrg maxWidth = MAXINT; 107706f2543Smrg maxHeight = MAXINT; 108706f2543Smrg } 109706f2543Smrg 110706f2543Smrg if (hints.flags & PResizeInc) 111706f2543Smrg { 112706f2543Smrg xinc = hints.width_inc; 113706f2543Smrg yinc = hints.height_inc; 114706f2543Smrg } 115706f2543Smrg else 116706f2543Smrg xinc = yinc = 1; 117706f2543Smrg 118706f2543Smrg /* 119706f2543Smrg * First, clamp to min and max values 120706f2543Smrg */ 121706f2543Smrg if (dwidth < minWidth) 122706f2543Smrg dwidth = minWidth; 123706f2543Smrg if (dheight < minHeight) 124706f2543Smrg dheight = minHeight; 125706f2543Smrg 126706f2543Smrg if (dwidth > maxWidth) 127706f2543Smrg dwidth = maxWidth; 128706f2543Smrg if (dheight > maxHeight) 129706f2543Smrg dheight = maxHeight; 130706f2543Smrg 131706f2543Smrg /* 132706f2543Smrg * Second, fit to base + N * inc 133706f2543Smrg */ 134706f2543Smrg dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth; 135706f2543Smrg dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight; 136706f2543Smrg 137706f2543Smrg /* 138706f2543Smrg * Third, adjust for aspect ratio 139706f2543Smrg */ 140706f2543Smrg 141706f2543Smrg /* 142706f2543Smrg * The math looks like this: 143706f2543Smrg * 144706f2543Smrg * minAspectX dwidth maxAspectX 145706f2543Smrg * ---------- <= ------- <= ---------- 146706f2543Smrg * minAspectY dheight maxAspectY 147706f2543Smrg * 148706f2543Smrg * If that is multiplied out, then the width and height are 149706f2543Smrg * invalid in the following situations: 150706f2543Smrg * 151706f2543Smrg * minAspectX * dheight > minAspectY * dwidth 152706f2543Smrg * maxAspectX * dheight < maxAspectY * dwidth 153706f2543Smrg * 154706f2543Smrg */ 155706f2543Smrg 156706f2543Smrg if (hints.flags & PAspect) 157706f2543Smrg { 158706f2543Smrg if (hints.min_aspect.x * dheight > hints.min_aspect.y * dwidth) 159706f2543Smrg { 160706f2543Smrg delta = makemult(hints.min_aspect.x * dheight / hints.min_aspect.y - dwidth, xinc); 161706f2543Smrg if (dwidth + delta <= maxWidth) 162706f2543Smrg dwidth += delta; 163706f2543Smrg else 164706f2543Smrg { 165706f2543Smrg delta = makemult(dheight - dwidth*hints.min_aspect.y/hints.min_aspect.x, yinc); 166706f2543Smrg if (dheight - delta >= minHeight) 167706f2543Smrg dheight -= delta; 168706f2543Smrg } 169706f2543Smrg } 170706f2543Smrg 171706f2543Smrg if (hints.max_aspect.x * dheight < hints.max_aspect.y * dwidth) 172706f2543Smrg { 173706f2543Smrg delta = makemult(dwidth * hints.max_aspect.y / hints.max_aspect.x - dheight, yinc); 174706f2543Smrg if (dheight + delta <= maxHeight) 175706f2543Smrg dheight += delta; 176706f2543Smrg else 177706f2543Smrg { 178706f2543Smrg delta = makemult(dwidth - hints.max_aspect.x*dheight/hints.max_aspect.y, xinc); 179706f2543Smrg if (dwidth - delta >= minWidth) 180706f2543Smrg dwidth -= delta; 181706f2543Smrg } 182706f2543Smrg } 183706f2543Smrg } 184706f2543Smrg 185706f2543Smrg /* Return computed values */ 186706f2543Smrg *widthp = dwidth; 187706f2543Smrg *heightp = dheight; 188706f2543Smrg} 189706f2543Smrg#undef makemult 190706f2543Smrg 191706f2543Smrg 192706f2543Smrg 193706f2543Smrg/* 194706f2543Smrg * ValidateSizing - Ensures size request respects hints 195706f2543Smrg */ 196706f2543Smrgstatic int 197706f2543SmrgValidateSizing (HWND hwnd, WindowPtr pWin, 198706f2543Smrg WPARAM wParam, LPARAM lParam) 199706f2543Smrg{ 200706f2543Smrg WinXSizeHints sizeHints; 201706f2543Smrg RECT *rect; 202706f2543Smrg int iWidth, iHeight; 203706f2543Smrg RECT rcClient, rcWindow; 204706f2543Smrg int iBorderWidthX, iBorderWidthY; 205706f2543Smrg 206706f2543Smrg /* Invalid input checking */ 207706f2543Smrg if (pWin==NULL || lParam==0) 208706f2543Smrg return FALSE; 209706f2543Smrg 210706f2543Smrg /* No size hints, no checking */ 211706f2543Smrg if (!winMultiWindowGetWMNormalHints (pWin, &sizeHints)) 212706f2543Smrg return FALSE; 213706f2543Smrg 214706f2543Smrg /* Avoid divide-by-zero */ 215706f2543Smrg if (sizeHints.flags & PResizeInc) 216706f2543Smrg { 217706f2543Smrg if (sizeHints.width_inc == 0) sizeHints.width_inc = 1; 218706f2543Smrg if (sizeHints.height_inc == 0) sizeHints.height_inc = 1; 219706f2543Smrg } 220706f2543Smrg 221706f2543Smrg rect = (RECT*)lParam; 222706f2543Smrg 223706f2543Smrg iWidth = rect->right - rect->left; 224706f2543Smrg iHeight = rect->bottom - rect->top; 225706f2543Smrg 226706f2543Smrg /* Now remove size of any borders and title bar */ 227706f2543Smrg GetClientRect(hwnd, &rcClient); 228706f2543Smrg GetWindowRect(hwnd, &rcWindow); 229706f2543Smrg iBorderWidthX = (rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left); 230706f2543Smrg iBorderWidthY = (rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top); 231706f2543Smrg iWidth -= iBorderWidthX; 232706f2543Smrg iHeight -= iBorderWidthY; 233706f2543Smrg 234706f2543Smrg /* Constrain the size to legal values */ 235706f2543Smrg ConstrainSize (sizeHints, &iWidth, &iHeight); 236706f2543Smrg 237706f2543Smrg /* Add back the size of borders and title bar */ 238706f2543Smrg iWidth += iBorderWidthX; 239706f2543Smrg iHeight += iBorderWidthY; 240706f2543Smrg 241706f2543Smrg /* Adjust size according to where we're dragging from */ 242706f2543Smrg switch(wParam) { 243706f2543Smrg case WMSZ_TOP: 244706f2543Smrg case WMSZ_TOPRIGHT: 245706f2543Smrg case WMSZ_BOTTOM: 246706f2543Smrg case WMSZ_BOTTOMRIGHT: 247706f2543Smrg case WMSZ_RIGHT: 248706f2543Smrg rect->right = rect->left + iWidth; 249706f2543Smrg break; 250706f2543Smrg default: 251706f2543Smrg rect->left = rect->right - iWidth; 252706f2543Smrg break; 253706f2543Smrg } 254706f2543Smrg switch(wParam) { 255706f2543Smrg case WMSZ_BOTTOM: 256706f2543Smrg case WMSZ_BOTTOMRIGHT: 257706f2543Smrg case WMSZ_BOTTOMLEFT: 258706f2543Smrg case WMSZ_RIGHT: 259706f2543Smrg case WMSZ_LEFT: 260706f2543Smrg rect->bottom = rect->top + iHeight; 261706f2543Smrg break; 262706f2543Smrg default: 263706f2543Smrg rect->top = rect->bottom - iHeight; 264706f2543Smrg break; 265706f2543Smrg } 266706f2543Smrg return TRUE; 267706f2543Smrg} 268706f2543Smrg 269706f2543Smrgextern Bool winInDestroyWindowsWindow; 270706f2543Smrgstatic Bool winInRaiseWindow = FALSE; 271706f2543Smrgstatic void winRaiseWindow(WindowPtr pWin) 272706f2543Smrg{ 273706f2543Smrg if (!winInDestroyWindowsWindow && !winInRaiseWindow) 274706f2543Smrg { 275706f2543Smrg BOOL oldstate = winInRaiseWindow; 276706f2543Smrg XID vlist[1] = { 0 }; 277706f2543Smrg winInRaiseWindow = TRUE; 278706f2543Smrg /* Call configure window directly to make sure it gets processed 279706f2543Smrg * in time 280706f2543Smrg */ 281706f2543Smrg ConfigureWindow(pWin, CWStackMode, vlist, serverClient); 282706f2543Smrg winInRaiseWindow = oldstate; 283706f2543Smrg } 284706f2543Smrg} 285706f2543Smrg 286706f2543Smrgstatic 287706f2543Smrgvoid winStartMousePolling(winPrivScreenPtr s_pScreenPriv) 288706f2543Smrg{ 289706f2543Smrg /* 290706f2543Smrg * Timer to poll mouse position. This is needed to make 291706f2543Smrg * programs like xeyes follow the mouse properly when the 292706f2543Smrg * mouse pointer is outside of any X window. 293706f2543Smrg */ 294706f2543Smrg if (g_uipMousePollingTimerID == 0) 295706f2543Smrg g_uipMousePollingTimerID = SetTimer (s_pScreenPriv->hwndScreen, 296706f2543Smrg WIN_POLLING_MOUSE_TIMER_ID, 297706f2543Smrg MOUSE_POLLING_INTERVAL, 298706f2543Smrg NULL); 299706f2543Smrg} 300706f2543Smrg 301706f2543Smrg/* 302706f2543Smrg * winTopLevelWindowProc - Window procedure for all top-level Windows windows. 303706f2543Smrg */ 304706f2543Smrg 305706f2543SmrgLRESULT CALLBACK 306706f2543SmrgwinTopLevelWindowProc (HWND hwnd, UINT message, 307706f2543Smrg WPARAM wParam, LPARAM lParam) 308706f2543Smrg{ 309706f2543Smrg POINT ptMouse; 310706f2543Smrg HDC hdcUpdate; 311706f2543Smrg PAINTSTRUCT ps; 312706f2543Smrg WindowPtr pWin = NULL; 313706f2543Smrg winPrivWinPtr pWinPriv = NULL; 314706f2543Smrg ScreenPtr s_pScreen = NULL; 315706f2543Smrg winPrivScreenPtr s_pScreenPriv = NULL; 316706f2543Smrg winScreenInfo *s_pScreenInfo = NULL; 317706f2543Smrg HWND hwndScreen = NULL; 318706f2543Smrg DrawablePtr pDraw = NULL; 319706f2543Smrg winWMMessageRec wmMsg; 320706f2543Smrg Bool fWMMsgInitialized = FALSE; 321706f2543Smrg static Bool s_fTracking = FALSE; 322706f2543Smrg Bool needRestack = FALSE; 323706f2543Smrg LRESULT ret; 324706f2543Smrg 325706f2543Smrg#if CYGDEBUG 326706f2543Smrg winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam, lParam); 327706f2543Smrg#endif 328706f2543Smrg 329706f2543Smrg /* Check if the Windows window property for our X window pointer is valid */ 330706f2543Smrg if ((pWin = GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) 331706f2543Smrg { 332706f2543Smrg /* Our X window pointer is valid */ 333706f2543Smrg 334706f2543Smrg /* Get pointers to the drawable and the screen */ 335706f2543Smrg pDraw = &pWin->drawable; 336706f2543Smrg s_pScreen = pWin->drawable.pScreen; 337706f2543Smrg 338706f2543Smrg /* Get a pointer to our window privates */ 339706f2543Smrg pWinPriv = winGetWindowPriv(pWin); 340706f2543Smrg 341706f2543Smrg /* Get pointers to our screen privates and screen info */ 342706f2543Smrg s_pScreenPriv = pWinPriv->pScreenPriv; 343706f2543Smrg s_pScreenInfo = s_pScreenPriv->pScreenInfo; 344706f2543Smrg 345706f2543Smrg /* Get the handle for our screen-sized window */ 346706f2543Smrg hwndScreen = s_pScreenPriv->hwndScreen; 347706f2543Smrg 348706f2543Smrg /* */ 349706f2543Smrg wmMsg.msg = 0; 350706f2543Smrg wmMsg.hwndWindow = hwnd; 351706f2543Smrg wmMsg.iWindow = (Window)GetProp (hwnd, WIN_WID_PROP); 352706f2543Smrg 353706f2543Smrg wmMsg.iX = pDraw->x; 354706f2543Smrg wmMsg.iY = pDraw->y; 355706f2543Smrg wmMsg.iWidth = pDraw->width; 356706f2543Smrg wmMsg.iHeight = pDraw->height; 357706f2543Smrg 358706f2543Smrg fWMMsgInitialized = TRUE; 359706f2543Smrg 360706f2543Smrg#if 0 361706f2543Smrg /* 362706f2543Smrg * Print some debugging information 363706f2543Smrg */ 364706f2543Smrg 365706f2543Smrg ErrorF ("hWnd %08X\n", hwnd); 366706f2543Smrg ErrorF ("pWin %08X\n", pWin); 367706f2543Smrg ErrorF ("pDraw %08X\n", pDraw); 368706f2543Smrg ErrorF ("\ttype %08X\n", pWin->drawable.type); 369706f2543Smrg ErrorF ("\tclass %08X\n", pWin->drawable.class); 370706f2543Smrg ErrorF ("\tdepth %08X\n", pWin->drawable.depth); 371706f2543Smrg ErrorF ("\tbitsPerPixel %08X\n", pWin->drawable.bitsPerPixel); 372706f2543Smrg ErrorF ("\tid %08X\n", pWin->drawable.id); 373706f2543Smrg ErrorF ("\tx %08X\n", pWin->drawable.x); 374706f2543Smrg ErrorF ("\ty %08X\n", pWin->drawable.y); 375706f2543Smrg ErrorF ("\twidth %08X\n", pWin->drawable.width); 376706f2543Smrg ErrorF ("\thenght %08X\n", pWin->drawable.height); 377706f2543Smrg ErrorF ("\tpScreen %08X\n", pWin->drawable.pScreen); 378706f2543Smrg ErrorF ("\tserialNumber %08X\n", pWin->drawable.serialNumber); 379706f2543Smrg ErrorF ("g_iWindowPrivateKey %p\n", g_iWindowPrivateKey); 380706f2543Smrg ErrorF ("pWinPriv %08X\n", pWinPriv); 381706f2543Smrg ErrorF ("s_pScreenPriv %08X\n", s_pScreenPriv); 382706f2543Smrg ErrorF ("s_pScreenInfo %08X\n", s_pScreenInfo); 383706f2543Smrg ErrorF ("hwndScreen %08X\n", hwndScreen); 384706f2543Smrg#endif 385706f2543Smrg } 386706f2543Smrg 387706f2543Smrg /* Branch on message type */ 388706f2543Smrg switch (message) 389706f2543Smrg { 390706f2543Smrg case WM_CREATE: 391706f2543Smrg 392706f2543Smrg /* */ 393706f2543Smrg SetProp (hwnd, 394706f2543Smrg WIN_WINDOW_PROP, 395706f2543Smrg (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams); 396706f2543Smrg 397706f2543Smrg /* */ 398706f2543Smrg SetProp (hwnd, 399706f2543Smrg WIN_WID_PROP, 400706f2543Smrg (HANDLE)winGetWindowID (((LPCREATESTRUCT) lParam)->lpCreateParams)); 401706f2543Smrg 402706f2543Smrg /* 403706f2543Smrg * Make X windows' Z orders sync with Windows windows because 404706f2543Smrg * there can be AlwaysOnTop windows overlapped on the window 405706f2543Smrg * currently being created. 406706f2543Smrg */ 407706f2543Smrg winReorderWindowsMultiWindow (); 408706f2543Smrg 409706f2543Smrg /* Fix a 'round title bar corner background should be transparent not black' problem when first painted */ 410706f2543Smrg { 411706f2543Smrg RECT rWindow; 412706f2543Smrg HRGN hRgnWindow; 413706f2543Smrg GetWindowRect(hwnd, &rWindow); 414706f2543Smrg hRgnWindow = CreateRectRgnIndirect(&rWindow); 415706f2543Smrg SetWindowRgn (hwnd, hRgnWindow, TRUE); 416706f2543Smrg DeleteObject(hRgnWindow); 417706f2543Smrg } 418706f2543Smrg 419706f2543Smrg SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)XMING_SIGNATURE); 420706f2543Smrg 421706f2543Smrg return 0; 422706f2543Smrg 423706f2543Smrg case WM_INIT_SYS_MENU: 424706f2543Smrg /* 425706f2543Smrg * Add whatever the setup file wants to for this window 426706f2543Smrg */ 427706f2543Smrg SetupSysMenu ((unsigned long)hwnd); 428706f2543Smrg return 0; 429706f2543Smrg 430706f2543Smrg case WM_SYSCOMMAND: 431706f2543Smrg /* 432706f2543Smrg * Any window menu items go through here 433706f2543Smrg */ 434706f2543Smrg if (HandleCustomWM_COMMAND ((unsigned long)hwnd, LOWORD(wParam))) 435706f2543Smrg { 436706f2543Smrg /* Don't pass customized menus to DefWindowProc */ 437706f2543Smrg return 0; 438706f2543Smrg } 439706f2543Smrg if (wParam == SC_RESTORE || wParam == SC_MAXIMIZE) 440706f2543Smrg { 441706f2543Smrg WINDOWPLACEMENT wndpl; 442706f2543Smrg wndpl.length = sizeof(wndpl); 443706f2543Smrg if (GetWindowPlacement(hwnd, &wndpl) && wndpl.showCmd == SW_SHOWMINIMIZED) 444706f2543Smrg needRestack = TRUE; 445706f2543Smrg } 446706f2543Smrg break; 447706f2543Smrg 448706f2543Smrg case WM_INITMENU: 449706f2543Smrg /* Checks/Unchecks any menu items before they are displayed */ 450706f2543Smrg HandleCustomWM_INITMENU ((unsigned long)hwnd, wParam); 451706f2543Smrg break; 452706f2543Smrg 453706f2543Smrg case WM_ERASEBKGND: 454706f2543Smrg /* 455706f2543Smrg * Pretend that we did erase the background but we don't care, 456706f2543Smrg * since we repaint the entire region anyhow 457706f2543Smrg * This avoids some flickering when resizing. 458706f2543Smrg */ 459706f2543Smrg return TRUE; 460706f2543Smrg 461706f2543Smrg case WM_PAINT: 462706f2543Smrg /* Only paint if our window handle is valid */ 463706f2543Smrg if (hwndScreen == NULL) 464706f2543Smrg break; 465706f2543Smrg 466706f2543Smrg /* BeginPaint gives us an hdc that clips to the invalidated region */ 467706f2543Smrg hdcUpdate = BeginPaint (hwnd, &ps); 468706f2543Smrg /* Avoid the BitBlt's if the PAINTSTRUCT is bogus */ 469706f2543Smrg if (ps.rcPaint.right==0 && ps.rcPaint.bottom==0 && ps.rcPaint.left==0 && ps.rcPaint.top==0) 470706f2543Smrg { 471706f2543Smrg EndPaint (hwnd, &ps); 472706f2543Smrg return 0; 473706f2543Smrg } 474706f2543Smrg 475706f2543Smrg /* Try to copy from the shadow buffer */ 476706f2543Smrg if (!BitBlt (hdcUpdate, 477706f2543Smrg ps.rcPaint.left, ps.rcPaint.top, 478706f2543Smrg ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, 479706f2543Smrg s_pScreenPriv->hdcShadow, 480706f2543Smrg ps.rcPaint.left + pWin->drawable.x, ps.rcPaint.top + pWin->drawable.y, 481706f2543Smrg SRCCOPY)) 482706f2543Smrg { 483706f2543Smrg LPVOID lpMsgBuf; 484706f2543Smrg 485706f2543Smrg /* Display a fancy error message */ 486706f2543Smrg FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | 487706f2543Smrg FORMAT_MESSAGE_FROM_SYSTEM | 488706f2543Smrg FORMAT_MESSAGE_IGNORE_INSERTS, 489706f2543Smrg NULL, 490706f2543Smrg GetLastError (), 491706f2543Smrg MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 492706f2543Smrg (LPTSTR) &lpMsgBuf, 493706f2543Smrg 0, NULL); 494706f2543Smrg 495706f2543Smrg ErrorF ("winTopLevelWindowProc - BitBlt failed: %s\n", 496706f2543Smrg (LPSTR)lpMsgBuf); 497706f2543Smrg LocalFree (lpMsgBuf); 498706f2543Smrg } 499706f2543Smrg 500706f2543Smrg /* EndPaint frees the DC */ 501706f2543Smrg EndPaint (hwnd, &ps); 502706f2543Smrg return 0; 503706f2543Smrg 504706f2543Smrg case WM_MOUSEMOVE: 505706f2543Smrg /* Unpack the client area mouse coordinates */ 506706f2543Smrg ptMouse.x = GET_X_LPARAM(lParam); 507706f2543Smrg ptMouse.y = GET_Y_LPARAM(lParam); 508706f2543Smrg 509706f2543Smrg /* Translate the client area mouse coordinates to screen coordinates */ 510706f2543Smrg ClientToScreen (hwnd, &ptMouse); 511706f2543Smrg 512706f2543Smrg /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */ 513706f2543Smrg ptMouse.x -= GetSystemMetrics (SM_XVIRTUALSCREEN); 514706f2543Smrg ptMouse.y -= GetSystemMetrics (SM_YVIRTUALSCREEN); 515706f2543Smrg 516706f2543Smrg /* We can't do anything without privates */ 517706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 518706f2543Smrg break; 519706f2543Smrg 520706f2543Smrg /* Has the mouse pointer crossed screens? */ 521706f2543Smrg if (s_pScreen != miPointerGetScreen(g_pwinPointer)) 522706f2543Smrg miPointerSetScreen (g_pwinPointer, s_pScreenInfo->dwScreen, 523706f2543Smrg ptMouse.x - s_pScreenInfo->dwXOffset, 524706f2543Smrg ptMouse.y - s_pScreenInfo->dwYOffset); 525706f2543Smrg 526706f2543Smrg /* Are we tracking yet? */ 527706f2543Smrg if (!s_fTracking) 528706f2543Smrg { 529706f2543Smrg TRACKMOUSEEVENT tme; 530706f2543Smrg 531706f2543Smrg /* Setup data structure */ 532706f2543Smrg ZeroMemory (&tme, sizeof (tme)); 533706f2543Smrg tme.cbSize = sizeof (tme); 534706f2543Smrg tme.dwFlags = TME_LEAVE; 535706f2543Smrg tme.hwndTrack = hwnd; 536706f2543Smrg 537706f2543Smrg /* Call the tracking function */ 538706f2543Smrg if (!(*g_fpTrackMouseEvent) (&tme)) 539706f2543Smrg ErrorF ("winTopLevelWindowProc - _TrackMouseEvent failed\n"); 540706f2543Smrg 541706f2543Smrg /* Flag that we are tracking now */ 542706f2543Smrg s_fTracking = TRUE; 543706f2543Smrg } 544706f2543Smrg 545706f2543Smrg /* Hide or show the Windows mouse cursor */ 546706f2543Smrg if (g_fSoftwareCursor && g_fCursor) 547706f2543Smrg { 548706f2543Smrg /* Hide Windows cursor */ 549706f2543Smrg g_fCursor = FALSE; 550706f2543Smrg ShowCursor (FALSE); 551706f2543Smrg } 552706f2543Smrg 553706f2543Smrg /* Kill the timer used to poll mouse events */ 554706f2543Smrg if (g_uipMousePollingTimerID != 0) 555706f2543Smrg { 556706f2543Smrg KillTimer (s_pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID); 557706f2543Smrg g_uipMousePollingTimerID = 0; 558706f2543Smrg } 559706f2543Smrg 560706f2543Smrg /* Deliver absolute cursor position to X Server */ 561706f2543Smrg winEnqueueMotion(ptMouse.x - s_pScreenInfo->dwXOffset, 562706f2543Smrg ptMouse.y - s_pScreenInfo->dwYOffset); 563706f2543Smrg 564706f2543Smrg return 0; 565706f2543Smrg 566706f2543Smrg case WM_NCMOUSEMOVE: 567706f2543Smrg /* 568706f2543Smrg * We break instead of returning 0 since we need to call 569706f2543Smrg * DefWindowProc to get the mouse cursor changes 570706f2543Smrg * and min/max/close button highlighting in Windows XP. 571706f2543Smrg * The Platform SDK says that you should return 0 if you 572706f2543Smrg * process this message, but it fails to mention that you 573706f2543Smrg * will give up any default functionality if you do return 0. 574706f2543Smrg */ 575706f2543Smrg 576706f2543Smrg /* We can't do anything without privates */ 577706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 578706f2543Smrg break; 579706f2543Smrg 580706f2543Smrg /* Non-client mouse movement, show Windows cursor */ 581706f2543Smrg if (g_fSoftwareCursor && !g_fCursor) 582706f2543Smrg { 583706f2543Smrg g_fCursor = TRUE; 584706f2543Smrg ShowCursor (TRUE); 585706f2543Smrg } 586706f2543Smrg 587706f2543Smrg winStartMousePolling(s_pScreenPriv); 588706f2543Smrg 589706f2543Smrg break; 590706f2543Smrg 591706f2543Smrg case WM_MOUSELEAVE: 592706f2543Smrg /* Mouse has left our client area */ 593706f2543Smrg 594706f2543Smrg /* Flag that we are no longer tracking */ 595706f2543Smrg s_fTracking = FALSE; 596706f2543Smrg 597706f2543Smrg /* Show the mouse cursor, if necessary */ 598706f2543Smrg if (g_fSoftwareCursor && !g_fCursor) 599706f2543Smrg { 600706f2543Smrg g_fCursor = TRUE; 601706f2543Smrg ShowCursor (TRUE); 602706f2543Smrg } 603706f2543Smrg 604706f2543Smrg winStartMousePolling(s_pScreenPriv); 605706f2543Smrg 606706f2543Smrg return 0; 607706f2543Smrg 608706f2543Smrg case WM_LBUTTONDBLCLK: 609706f2543Smrg case WM_LBUTTONDOWN: 610706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 611706f2543Smrg break; 612706f2543Smrg g_fButton[0] = TRUE; 613706f2543Smrg SetCapture(hwnd); 614706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam); 615706f2543Smrg 616706f2543Smrg case WM_LBUTTONUP: 617706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 618706f2543Smrg break; 619706f2543Smrg g_fButton[0] = FALSE; 620706f2543Smrg ReleaseCapture(); 621706f2543Smrg winStartMousePolling(s_pScreenPriv); 622706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam); 623706f2543Smrg 624706f2543Smrg case WM_MBUTTONDBLCLK: 625706f2543Smrg case WM_MBUTTONDOWN: 626706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 627706f2543Smrg break; 628706f2543Smrg g_fButton[1] = TRUE; 629706f2543Smrg SetCapture(hwnd); 630706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam); 631706f2543Smrg 632706f2543Smrg case WM_MBUTTONUP: 633706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 634706f2543Smrg break; 635706f2543Smrg g_fButton[1] = FALSE; 636706f2543Smrg ReleaseCapture(); 637706f2543Smrg winStartMousePolling(s_pScreenPriv); 638706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam); 639706f2543Smrg 640706f2543Smrg case WM_RBUTTONDBLCLK: 641706f2543Smrg case WM_RBUTTONDOWN: 642706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 643706f2543Smrg break; 644706f2543Smrg g_fButton[2] = TRUE; 645706f2543Smrg SetCapture(hwnd); 646706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam); 647706f2543Smrg 648706f2543Smrg case WM_RBUTTONUP: 649706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 650706f2543Smrg break; 651706f2543Smrg g_fButton[2] = FALSE; 652706f2543Smrg ReleaseCapture(); 653706f2543Smrg winStartMousePolling(s_pScreenPriv); 654706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam); 655706f2543Smrg 656706f2543Smrg case WM_XBUTTONDBLCLK: 657706f2543Smrg case WM_XBUTTONDOWN: 658706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 659706f2543Smrg break; 660706f2543Smrg SetCapture(hwnd); 661706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonPress, HIWORD(wParam) + 5, wParam); 662706f2543Smrg 663706f2543Smrg case WM_XBUTTONUP: 664706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 665706f2543Smrg break; 666706f2543Smrg ReleaseCapture(); 667706f2543Smrg winStartMousePolling(s_pScreenPriv); 668706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam); 669706f2543Smrg 670706f2543Smrg case WM_MOUSEWHEEL: 671706f2543Smrg if (SendMessage(hwnd, WM_NCHITTEST, 0, MAKELONG(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) == HTCLIENT) 672706f2543Smrg { 673706f2543Smrg /* Pass the message to the root window */ 674706f2543Smrg SendMessage (hwndScreen, message, wParam, lParam); 675706f2543Smrg return 0; 676706f2543Smrg } 677706f2543Smrg else break; 678706f2543Smrg 679706f2543Smrg case WM_SETFOCUS: 680706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 681706f2543Smrg break; 682706f2543Smrg 683706f2543Smrg { 684706f2543Smrg /* Get the parent window for transient handling */ 685706f2543Smrg HWND hParent = GetParent(hwnd); 686706f2543Smrg if (hParent && IsIconic(hParent)) ShowWindow (hParent, SW_RESTORE); 687706f2543Smrg } 688706f2543Smrg 689706f2543Smrg winRestoreModeKeyStates (); 690706f2543Smrg 691706f2543Smrg /* Add the keyboard hook if possible */ 692706f2543Smrg if (g_fKeyboardHookLL) 693706f2543Smrg g_fKeyboardHookLL = winInstallKeyboardHookLL (); 694706f2543Smrg return 0; 695706f2543Smrg 696706f2543Smrg case WM_KILLFOCUS: 697706f2543Smrg /* Pop any pressed keys since we are losing keyboard focus */ 698706f2543Smrg winKeybdReleaseKeys (); 699706f2543Smrg 700706f2543Smrg /* Remove our keyboard hook if it is installed */ 701706f2543Smrg winRemoveKeyboardHookLL (); 702706f2543Smrg if (!wParam) 703706f2543Smrg /* Revert the X focus as well, but only if the Windows focus is going to another window */ 704706f2543Smrg DeleteWindowFromAnyEvents(pWin, FALSE); 705706f2543Smrg return 0; 706706f2543Smrg 707706f2543Smrg case WM_SYSDEADCHAR: 708706f2543Smrg case WM_DEADCHAR: 709706f2543Smrg /* 710706f2543Smrg * NOTE: We do nothing with WM_*CHAR messages, 711706f2543Smrg * nor does the root window, so we can just toss these messages. 712706f2543Smrg */ 713706f2543Smrg return 0; 714706f2543Smrg 715706f2543Smrg case WM_SYSKEYDOWN: 716706f2543Smrg case WM_KEYDOWN: 717706f2543Smrg 718706f2543Smrg /* 719706f2543Smrg * Don't pass Alt-F4 key combo to root window, 720706f2543Smrg * let Windows translate to WM_CLOSE and close this top-level window. 721706f2543Smrg * 722706f2543Smrg * NOTE: We purposely don't check the fUseWinKillKey setting because 723706f2543Smrg * it should only apply to the key handling for the root window, 724706f2543Smrg * not for top-level window-manager windows. 725706f2543Smrg * 726706f2543Smrg * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window 727706f2543Smrg * because that is a key combo that no X app should be expecting to 728706f2543Smrg * receive, since it has historically been used to shutdown the X server. 729706f2543Smrg * Passing Ctrl-Alt-Backspace to the root window preserves that 730706f2543Smrg * behavior, assuming that -unixkill has been passed as a parameter. 731706f2543Smrg */ 732706f2543Smrg if (wParam == VK_F4 && (GetKeyState (VK_MENU) & 0x8000)) 733706f2543Smrg break; 734706f2543Smrg 735706f2543Smrg#if CYGWINDOWING_DEBUG 736706f2543Smrg if (wParam == VK_ESCAPE) 737706f2543Smrg { 738706f2543Smrg /* Place for debug: put any tests and dumps here */ 739706f2543Smrg WINDOWPLACEMENT windPlace; 740706f2543Smrg RECT rc; 741706f2543Smrg LPRECT pRect; 742706f2543Smrg 743706f2543Smrg windPlace.length = sizeof (WINDOWPLACEMENT); 744706f2543Smrg GetWindowPlacement (hwnd, &windPlace); 745706f2543Smrg pRect = &windPlace.rcNormalPosition; 746706f2543Smrg ErrorF ("\nCYGWINDOWING Dump:\n" 747706f2543Smrg "\tdrawable: (%hd, %hd) - %hdx%hd\n", pDraw->x, 748706f2543Smrg pDraw->y, pDraw->width, pDraw->height); 749706f2543Smrg ErrorF ("\twindPlace: (%ld, %ld) - %ldx%ld\n", pRect->left, 750706f2543Smrg pRect->top, pRect->right - pRect->left, 751706f2543Smrg pRect->bottom - pRect->top); 752706f2543Smrg if (GetClientRect (hwnd, &rc)) 753706f2543Smrg { 754706f2543Smrg pRect = &rc; 755706f2543Smrg ErrorF ("\tClientRect: (%ld, %ld) - %ldx%ld\n", pRect->left, 756706f2543Smrg pRect->top, pRect->right - pRect->left, 757706f2543Smrg pRect->bottom - pRect->top); 758706f2543Smrg } 759706f2543Smrg if (GetWindowRect (hwnd, &rc)) 760706f2543Smrg { 761706f2543Smrg pRect = &rc; 762706f2543Smrg ErrorF ("\tWindowRect: (%ld, %ld) - %ldx%ld\n", pRect->left, 763706f2543Smrg pRect->top, pRect->right - pRect->left, 764706f2543Smrg pRect->bottom - pRect->top); 765706f2543Smrg } 766706f2543Smrg ErrorF ("\n"); 767706f2543Smrg } 768706f2543Smrg#endif 769706f2543Smrg 770706f2543Smrg /* Pass the message to the root window */ 771706f2543Smrg return winWindowProc(hwndScreen, message, wParam, lParam); 772706f2543Smrg 773706f2543Smrg case WM_SYSKEYUP: 774706f2543Smrg case WM_KEYUP: 775706f2543Smrg 776706f2543Smrg 777706f2543Smrg /* Pass the message to the root window */ 778706f2543Smrg return winWindowProc(hwndScreen, message, wParam, lParam); 779706f2543Smrg 780706f2543Smrg case WM_HOTKEY: 781706f2543Smrg 782706f2543Smrg /* Pass the message to the root window */ 783706f2543Smrg SendMessage (hwndScreen, message, wParam, lParam); 784706f2543Smrg return 0; 785706f2543Smrg 786706f2543Smrg case WM_ACTIVATE: 787706f2543Smrg 788706f2543Smrg /* Pass the message to the root window */ 789706f2543Smrg SendMessage (hwndScreen, message, wParam, lParam); 790706f2543Smrg 791706f2543Smrg if (LOWORD(wParam) != WA_INACTIVE) 792706f2543Smrg { 793706f2543Smrg /* Raise the window to the top in Z order */ 794706f2543Smrg /* ago: Activate does not mean putting it to front! */ 795706f2543Smrg /* 796706f2543Smrg wmMsg.msg = WM_WM_RAISE; 797706f2543Smrg if (fWMMsgInitialized) 798706f2543Smrg winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); 799706f2543Smrg */ 800706f2543Smrg 801706f2543Smrg /* Tell our Window Manager thread to activate the window */ 802706f2543Smrg wmMsg.msg = WM_WM_ACTIVATE; 803706f2543Smrg if (fWMMsgInitialized) 804706f2543Smrg if (!pWin || !pWin->overrideRedirect) /* for OOo menus */ 805706f2543Smrg winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); 806706f2543Smrg } 807706f2543Smrg /* Prevent the mouse wheel from stalling when another window is minimized */ 808706f2543Smrg if (HIWORD(wParam) == 0 && LOWORD(wParam) == WA_ACTIVE && 809706f2543Smrg (HWND)lParam != NULL && (HWND)lParam != (HWND)GetParent(hwnd)) 810706f2543Smrg SetFocus(hwnd); 811706f2543Smrg return 0; 812706f2543Smrg 813706f2543Smrg case WM_ACTIVATEAPP: 814706f2543Smrg /* 815706f2543Smrg * This message is also sent to the root window 816706f2543Smrg * so we do nothing for individual multiwindow windows 817706f2543Smrg */ 818706f2543Smrg break; 819706f2543Smrg 820706f2543Smrg case WM_CLOSE: 821706f2543Smrg /* Branch on if the window was killed in X already */ 822706f2543Smrg if (pWinPriv->fXKilled) 823706f2543Smrg { 824706f2543Smrg /* Window was killed, go ahead and destroy the window */ 825706f2543Smrg DestroyWindow (hwnd); 826706f2543Smrg } 827706f2543Smrg else 828706f2543Smrg { 829706f2543Smrg /* Tell our Window Manager thread to kill the window */ 830706f2543Smrg wmMsg.msg = WM_WM_KILL; 831706f2543Smrg if (fWMMsgInitialized) 832706f2543Smrg winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); 833706f2543Smrg } 834706f2543Smrg return 0; 835706f2543Smrg 836706f2543Smrg case WM_DESTROY: 837706f2543Smrg 838706f2543Smrg /* Branch on if the window was killed in X already */ 839706f2543Smrg if (pWinPriv && !pWinPriv->fXKilled) 840706f2543Smrg { 841706f2543Smrg ErrorF ("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n"); 842706f2543Smrg 843706f2543Smrg /* Tell our Window Manager thread to kill the window */ 844706f2543Smrg wmMsg.msg = WM_WM_KILL; 845706f2543Smrg if (fWMMsgInitialized) 846706f2543Smrg winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); 847706f2543Smrg } 848706f2543Smrg 849706f2543Smrg RemoveProp (hwnd, WIN_WINDOW_PROP); 850706f2543Smrg RemoveProp (hwnd, WIN_WID_PROP); 851706f2543Smrg RemoveProp (hwnd, WIN_NEEDMANAGE_PROP); 852706f2543Smrg 853706f2543Smrg break; 854706f2543Smrg 855706f2543Smrg case WM_MOVE: 856706f2543Smrg /* Adjust the X Window to the moved Windows window */ 857706f2543Smrg winAdjustXWindow (pWin, hwnd); 858706f2543Smrg return 0; 859706f2543Smrg 860706f2543Smrg case WM_SHOWWINDOW: 861706f2543Smrg /* Bail out if the window is being hidden */ 862706f2543Smrg if (!wParam) 863706f2543Smrg return 0; 864706f2543Smrg 865706f2543Smrg /* */ 866706f2543Smrg if (!pWin->overrideRedirect) 867706f2543Smrg { 868706f2543Smrg /* Flag that this window needs to be made active when clicked */ 869706f2543Smrg SetProp (hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1); 870706f2543Smrg 871706f2543Smrg if (!(GetWindowLongPtr (hwnd, GWL_EXSTYLE) & WS_EX_APPWINDOW)) 872706f2543Smrg { 873706f2543Smrg HWND zstyle = HWND_NOTOPMOST; 874706f2543Smrg 875706f2543Smrg /* Set the window extended style flags */ 876706f2543Smrg SetWindowLongPtr (hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW); 877706f2543Smrg 878706f2543Smrg /* Set the transient style flags */ 879706f2543Smrg if (GetParent(hwnd)) SetWindowLongPtr (hwnd, GWL_STYLE, 880706f2543Smrg WS_POPUP | WS_OVERLAPPED | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); 881706f2543Smrg /* Set the window standard style flags */ 882706f2543Smrg else SetWindowLongPtr (hwnd, GWL_STYLE, 883706f2543Smrg (WS_POPUP | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS) 884706f2543Smrg & ~WS_CAPTION & ~WS_SIZEBOX); 885706f2543Smrg 886706f2543Smrg winUpdateWindowPosition (hwnd, FALSE, &zstyle); 887706f2543Smrg SetForegroundWindow (hwnd); 888706f2543Smrg } 889706f2543Smrg wmMsg.msg = WM_WM_MAP3; 890706f2543Smrg } 891706f2543Smrg else /* It is an overridden window so make it top of Z stack */ 892706f2543Smrg { 893706f2543Smrg HWND forHwnd = GetForegroundWindow(); 894706f2543Smrg#if CYGWINDOWING_DEBUG 895706f2543Smrg ErrorF ("overridden window is shown\n"); 896706f2543Smrg#endif 897706f2543Smrg if (forHwnd != NULL) 898706f2543Smrg { 899706f2543Smrg if (GetWindowLongPtr(forHwnd, GWLP_USERDATA) & (LONG_PTR)XMING_SIGNATURE) 900706f2543Smrg { 901706f2543Smrg if (GetWindowLongPtr(forHwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) 902706f2543Smrg SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 903706f2543Smrg else 904706f2543Smrg SetWindowPos (hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 905706f2543Smrg } 906706f2543Smrg } 907706f2543Smrg wmMsg.msg = WM_WM_MAP2; 908706f2543Smrg } 909706f2543Smrg 910706f2543Smrg /* Tell our Window Manager thread to map the window */ 911706f2543Smrg if (fWMMsgInitialized) 912706f2543Smrg winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); 913706f2543Smrg 914706f2543Smrg winStartMousePolling(s_pScreenPriv); 915706f2543Smrg 916706f2543Smrg return 0; 917706f2543Smrg 918706f2543Smrg case WM_SIZING: 919706f2543Smrg /* Need to legalize the size according to WM_NORMAL_HINTS */ 920706f2543Smrg /* for applications like xterm */ 921706f2543Smrg return ValidateSizing (hwnd, pWin, wParam, lParam); 922706f2543Smrg 923706f2543Smrg case WM_WINDOWPOSCHANGED: 924706f2543Smrg { 925706f2543Smrg LPWINDOWPOS pWinPos = (LPWINDOWPOS) lParam; 926706f2543Smrg 927706f2543Smrg if (!(pWinPos->flags & SWP_NOZORDER)) 928706f2543Smrg { 929706f2543Smrg#if CYGWINDOWING_DEBUG 930706f2543Smrg winDebug ("\twindow z order was changed\n"); 931706f2543Smrg#endif 932706f2543Smrg if (pWinPos->hwndInsertAfter == HWND_TOP 933706f2543Smrg ||pWinPos->hwndInsertAfter == HWND_TOPMOST 934706f2543Smrg ||pWinPos->hwndInsertAfter == HWND_NOTOPMOST) 935706f2543Smrg { 936706f2543Smrg#if CYGWINDOWING_DEBUG 937706f2543Smrg winDebug ("\traise to top\n"); 938706f2543Smrg#endif 939706f2543Smrg /* Raise the window to the top in Z order */ 940706f2543Smrg winRaiseWindow(pWin); 941706f2543Smrg } 942706f2543Smrg else if (pWinPos->hwndInsertAfter == HWND_BOTTOM) 943706f2543Smrg { 944706f2543Smrg } 945706f2543Smrg else 946706f2543Smrg { 947706f2543Smrg /* Check if this window is top of X windows. */ 948706f2543Smrg HWND hWndAbove = NULL; 949706f2543Smrg DWORD dwCurrentProcessID = GetCurrentProcessId (); 950706f2543Smrg DWORD dwWindowProcessID = 0; 951706f2543Smrg 952706f2543Smrg for (hWndAbove = pWinPos->hwndInsertAfter; 953706f2543Smrg hWndAbove != NULL; 954706f2543Smrg hWndAbove = GetNextWindow (hWndAbove, GW_HWNDPREV)) 955706f2543Smrg { 956706f2543Smrg /* Ignore other XWin process's window */ 957706f2543Smrg GetWindowThreadProcessId (hWndAbove, &dwWindowProcessID); 958706f2543Smrg 959706f2543Smrg if ((dwWindowProcessID == dwCurrentProcessID) 960706f2543Smrg && GetProp (hWndAbove, WIN_WINDOW_PROP) 961706f2543Smrg && !IsWindowVisible (hWndAbove) 962706f2543Smrg && !IsIconic (hWndAbove) ) /* ignore minimized windows */ 963706f2543Smrg break; 964706f2543Smrg } 965706f2543Smrg /* If this is top of X windows in Windows stack, 966706f2543Smrg raise it in X stack. */ 967706f2543Smrg if (hWndAbove == NULL) 968706f2543Smrg { 969706f2543Smrg#if CYGWINDOWING_DEBUG 970706f2543Smrg winDebug ("\traise to top\n"); 971706f2543Smrg#endif 972706f2543Smrg winRaiseWindow(pWin); 973706f2543Smrg } 974706f2543Smrg } 975706f2543Smrg } 976706f2543Smrg } 977706f2543Smrg /* 978706f2543Smrg * Pass the message to DefWindowProc to let the function 979706f2543Smrg * break down WM_WINDOWPOSCHANGED to WM_MOVE and WM_SIZE. 980706f2543Smrg */ 981706f2543Smrg break; 982706f2543Smrg 983706f2543Smrg case WM_SIZE: 984706f2543Smrg /* see dix/window.c */ 985706f2543Smrg#if CYGWINDOWING_DEBUG 986706f2543Smrg { 987706f2543Smrg char buf[64]; 988706f2543Smrg switch (wParam) 989706f2543Smrg { 990706f2543Smrg case SIZE_MINIMIZED: 991706f2543Smrg strcpy(buf, "SIZE_MINIMIZED"); 992706f2543Smrg break; 993706f2543Smrg case SIZE_MAXIMIZED: 994706f2543Smrg strcpy(buf, "SIZE_MAXIMIZED"); 995706f2543Smrg break; 996706f2543Smrg case SIZE_RESTORED: 997706f2543Smrg strcpy(buf, "SIZE_RESTORED"); 998706f2543Smrg break; 999706f2543Smrg default: 1000706f2543Smrg strcpy(buf, "UNKNOWN_FLAG"); 1001706f2543Smrg } 1002706f2543Smrg ErrorF ("winTopLevelWindowProc - WM_SIZE to %dx%d (%s) - %d ms\n", 1003706f2543Smrg (int)LOWORD(lParam), (int)HIWORD(lParam), buf, 1004706f2543Smrg (int)(GetTickCount ())); 1005706f2543Smrg } 1006706f2543Smrg#endif 1007706f2543Smrg /* Adjust the X Window to the moved Windows window */ 1008706f2543Smrg winAdjustXWindow (pWin, hwnd); 1009706f2543Smrg return 0; /* end of WM_SIZE handler */ 1010706f2543Smrg 1011706f2543Smrg case WM_MOUSEACTIVATE: 1012706f2543Smrg 1013706f2543Smrg /* Check if this window needs to be made active when clicked */ 1014706f2543Smrg if (!GetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP)) 1015706f2543Smrg { 1016706f2543Smrg#if CYGMULTIWINDOW_DEBUG 1017706f2543Smrg ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE - " 1018706f2543Smrg "MA_NOACTIVATE\n"); 1019706f2543Smrg#endif 1020706f2543Smrg 1021706f2543Smrg /* */ 1022706f2543Smrg return MA_NOACTIVATE; 1023706f2543Smrg } 1024706f2543Smrg break; 1025706f2543Smrg 1026706f2543Smrg case WM_SETCURSOR: 1027706f2543Smrg if (LOWORD(lParam) == HTCLIENT) 1028706f2543Smrg { 1029706f2543Smrg if (!g_fSoftwareCursor) SetCursor (s_pScreenPriv->cursor.handle); 1030706f2543Smrg return TRUE; 1031706f2543Smrg } 1032706f2543Smrg break; 1033706f2543Smrg 1034706f2543Smrg default: 1035706f2543Smrg break; 1036706f2543Smrg } 1037706f2543Smrg 1038706f2543Smrg ret = DefWindowProc (hwnd, message, wParam, lParam); 1039706f2543Smrg /* 1040706f2543Smrg * If the window was minized we get the stack change before the window is restored 1041706f2543Smrg * and so it gets lost. Ensure there stacking order is correct. 1042706f2543Smrg */ 1043706f2543Smrg if (needRestack) 1044706f2543Smrg winReorderWindowsMultiWindow(); 1045706f2543Smrg return ret; 1046706f2543Smrg} 1047