1706f2543Smrg/* 2706f2543Smrg *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 3706f2543Smrg * 4706f2543Smrg *Permission is hereby granted, free of charge, to any person obtaining 5706f2543Smrg * a copy of this software and associated documentation files (the 6706f2543Smrg *"Software"), to deal in the Software without restriction, including 7706f2543Smrg *without limitation the rights to use, copy, modify, merge, publish, 8706f2543Smrg *distribute, sublicense, and/or sell copies of the Software, and to 9706f2543Smrg *permit persons to whom the Software is furnished to do so, subject to 10706f2543Smrg *the following conditions: 11706f2543Smrg * 12706f2543Smrg *The above copyright notice and this permission notice shall be 13706f2543Smrg *included in all copies or substantial portions of the Software. 14706f2543Smrg * 15706f2543Smrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16706f2543Smrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17706f2543Smrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18706f2543Smrg *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR 19706f2543Smrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20706f2543Smrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21706f2543Smrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22706f2543Smrg * 23706f2543Smrg *Except as contained in this notice, the name of the XFree86 Project 24706f2543Smrg *shall not be used in advertising or otherwise to promote the sale, use 25706f2543Smrg *or other dealings in this Software without prior written authorization 26706f2543Smrg *from the XFree86 Project. 27706f2543Smrg * 28706f2543Smrg * Authors: Dakshinamurthy Karra 29706f2543Smrg * Suhaib M Siddiqi 30706f2543Smrg * Peter Busch 31706f2543Smrg * Harold L Hunt II 32706f2543Smrg * MATSUZAKI Kensuke 33706f2543Smrg */ 34706f2543Smrg 35706f2543Smrg#ifdef HAVE_XWIN_CONFIG_H 36706f2543Smrg#include <xwin-config.h> 37706f2543Smrg#endif 38706f2543Smrg#include "win.h" 39706f2543Smrg#include <commctrl.h> 40706f2543Smrg#include "winprefs.h" 41706f2543Smrg#include "winconfig.h" 42706f2543Smrg#include "winmsg.h" 43706f2543Smrg#include "winmonitors.h" 44706f2543Smrg#include "inputstr.h" 45706f2543Smrg 46706f2543Smrg/* 47706f2543Smrg * Global variables 48706f2543Smrg */ 49706f2543Smrg 50706f2543SmrgBool g_fCursor = TRUE; 51706f2543SmrgBool g_fButton[3] = { FALSE, FALSE, FALSE }; 52706f2543Smrg 53706f2543Smrg 54706f2543Smrg/* 55706f2543Smrg * Called by winWakeupHandler 56706f2543Smrg * Processes current Windows message 57706f2543Smrg */ 58706f2543Smrg 59706f2543SmrgLRESULT CALLBACK 60706f2543SmrgwinWindowProc (HWND hwnd, UINT message, 61706f2543Smrg WPARAM wParam, LPARAM lParam) 62706f2543Smrg{ 63706f2543Smrg static winPrivScreenPtr s_pScreenPriv = NULL; 64706f2543Smrg static winScreenInfo *s_pScreenInfo = NULL; 65706f2543Smrg static ScreenPtr s_pScreen = NULL; 66706f2543Smrg static HWND s_hwndLastPrivates = NULL; 67706f2543Smrg static HINSTANCE s_hInstance; 68706f2543Smrg static Bool s_fTracking = FALSE; 69706f2543Smrg static unsigned long s_ulServerGeneration = 0; 70706f2543Smrg static UINT s_uTaskbarRestart = 0; 71706f2543Smrg int iScanCode; 72706f2543Smrg int i; 73706f2543Smrg 74706f2543Smrg#if CYGDEBUG 75706f2543Smrg winDebugWin32Message("winWindowProc", hwnd, message, wParam, lParam); 76706f2543Smrg#endif 77706f2543Smrg 78706f2543Smrg /* Watch for server regeneration */ 79706f2543Smrg if (g_ulServerGeneration != s_ulServerGeneration) 80706f2543Smrg { 81706f2543Smrg /* Store new server generation */ 82706f2543Smrg s_ulServerGeneration = g_ulServerGeneration; 83706f2543Smrg } 84706f2543Smrg 85706f2543Smrg /* Only retrieve new privates pointers if window handle is null or changed */ 86706f2543Smrg if ((s_pScreenPriv == NULL || hwnd != s_hwndLastPrivates) 87706f2543Smrg && (s_pScreenPriv = GetProp (hwnd, WIN_SCR_PROP)) != NULL) 88706f2543Smrg { 89706f2543Smrg#if CYGDEBUG 90706f2543Smrg winDebug ("winWindowProc - Setting privates handle\n"); 91706f2543Smrg#endif 92706f2543Smrg s_pScreenInfo = s_pScreenPriv->pScreenInfo; 93706f2543Smrg s_pScreen = s_pScreenInfo->pScreen; 94706f2543Smrg s_hwndLastPrivates = hwnd; 95706f2543Smrg } 96706f2543Smrg else if (s_pScreenPriv == NULL) 97706f2543Smrg { 98706f2543Smrg /* For safety, handle case that should never happen */ 99706f2543Smrg s_pScreenInfo = NULL; 100706f2543Smrg s_pScreen = NULL; 101706f2543Smrg s_hwndLastPrivates = NULL; 102706f2543Smrg } 103706f2543Smrg 104706f2543Smrg /* Branch on message type */ 105706f2543Smrg switch (message) 106706f2543Smrg { 107706f2543Smrg case WM_TRAYICON: 108706f2543Smrg return winHandleIconMessage (hwnd, message, wParam, lParam, 109706f2543Smrg s_pScreenPriv); 110706f2543Smrg 111706f2543Smrg case WM_CREATE: 112706f2543Smrg#if CYGDEBUG 113706f2543Smrg winDebug ("winWindowProc - WM_CREATE\n"); 114706f2543Smrg#endif 115706f2543Smrg 116706f2543Smrg /* 117706f2543Smrg * Add a property to our display window that references 118706f2543Smrg * this screens' privates. 119706f2543Smrg * 120706f2543Smrg * This allows the window procedure to refer to the 121706f2543Smrg * appropriate window DC and shadow DC for the window that 122706f2543Smrg * it is processing. We use this to repaint exposed 123706f2543Smrg * areas of our display window. 124706f2543Smrg */ 125706f2543Smrg s_pScreenPriv = ((LPCREATESTRUCT) lParam)->lpCreateParams; 126706f2543Smrg s_hInstance = ((LPCREATESTRUCT) lParam)->hInstance; 127706f2543Smrg s_pScreenInfo = s_pScreenPriv->pScreenInfo; 128706f2543Smrg s_pScreen = s_pScreenInfo->pScreen; 129706f2543Smrg s_hwndLastPrivates = hwnd; 130706f2543Smrg s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); 131706f2543Smrg SetProp (hwnd, WIN_SCR_PROP, s_pScreenPriv); 132706f2543Smrg 133706f2543Smrg /* Setup tray icon */ 134706f2543Smrg if (!s_pScreenInfo->fNoTrayIcon) 135706f2543Smrg { 136706f2543Smrg /* 137706f2543Smrg * NOTE: The WM_CREATE message is processed before CreateWindowEx 138706f2543Smrg * returns, so s_pScreenPriv->hwndScreen is invalid at this point. 139706f2543Smrg * We go ahead and copy our hwnd parameter over top of the screen 140706f2543Smrg * privates hwndScreen so that we have a valid value for 141706f2543Smrg * that member. Otherwise, the tray icon will disappear 142706f2543Smrg * the first time you move the mouse over top of it. 143706f2543Smrg */ 144706f2543Smrg 145706f2543Smrg s_pScreenPriv->hwndScreen = hwnd; 146706f2543Smrg 147706f2543Smrg winInitNotifyIcon (s_pScreenPriv); 148706f2543Smrg } 149706f2543Smrg return 0; 150706f2543Smrg 151706f2543Smrg case WM_DISPLAYCHANGE: 152706f2543Smrg /* 153706f2543Smrg WM_DISPLAYCHANGE seems to be sent when the monitor layout or 154706f2543Smrg any monitor's resolution or depth changes, but it's lParam and 155706f2543Smrg wParam always indicate the resolution and bpp for the primary 156706f2543Smrg monitor (so ignore that as we could be on any monitor...) 157706f2543Smrg */ 158706f2543Smrg 159706f2543Smrg /* We cannot handle a display mode change during initialization */ 160706f2543Smrg if (s_pScreenInfo == NULL) 161706f2543Smrg FatalError ("winWindowProc - WM_DISPLAYCHANGE - The display " 162706f2543Smrg "mode changed while we were intializing. This is " 163706f2543Smrg "very bad and unexpected. Exiting.\n"); 164706f2543Smrg 165706f2543Smrg /* 166706f2543Smrg * We do not care about display changes with 167706f2543Smrg * fullscreen DirectDraw engines, because those engines set 168706f2543Smrg * their own mode when they become active. 169706f2543Smrg */ 170706f2543Smrg if (s_pScreenInfo->fFullScreen 171706f2543Smrg && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD 172706f2543Smrg || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL 173706f2543Smrg#ifdef XWIN_PRIMARYFB 174706f2543Smrg || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD 175706f2543Smrg#endif 176706f2543Smrg )) 177706f2543Smrg { 178706f2543Smrg break; 179706f2543Smrg } 180706f2543Smrg 181706f2543Smrg ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new width: %d " 182706f2543Smrg "new height: %d new bpp: %d\n", 183706f2543Smrg LOWORD (lParam), HIWORD (lParam), wParam); 184706f2543Smrg 185706f2543Smrg /* 186706f2543Smrg * Check for a disruptive change in depth. 187706f2543Smrg * We can only display a message for a disruptive depth change, 188706f2543Smrg * we cannot do anything to correct the situation. 189706f2543Smrg */ 190706f2543Smrg /* 191706f2543Smrg XXX: maybe we need to check if GetSystemMetrics(SM_SAMEDISPLAYFORMAT) 192706f2543Smrg has changed as well... 193706f2543Smrg */ 194706f2543Smrg if (s_pScreenInfo->dwBPP != GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL)) 195706f2543Smrg { 196706f2543Smrg if ((s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD 197706f2543Smrg || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL 198706f2543Smrg#ifdef XWIN_PRIMARYFB 199706f2543Smrg || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD 200706f2543Smrg#endif 201706f2543Smrg )) 202706f2543Smrg { 203706f2543Smrg /* Cannot display the visual until the depth is restored */ 204706f2543Smrg ErrorF ("winWindowProc - Disruptive change in depth\n"); 205706f2543Smrg 206706f2543Smrg /* Display depth change dialog */ 207706f2543Smrg winDisplayDepthChangeDialog (s_pScreenPriv); 208706f2543Smrg 209706f2543Smrg /* Flag that we have an invalid screen depth */ 210706f2543Smrg s_pScreenPriv->fBadDepth = TRUE; 211706f2543Smrg 212706f2543Smrg /* Minimize the display window */ 213706f2543Smrg ShowWindow (hwnd, SW_MINIMIZE); 214706f2543Smrg } 215706f2543Smrg else 216706f2543Smrg { 217706f2543Smrg /* For GDI, performance may suffer until original depth is restored */ 218706f2543Smrg ErrorF ("winWindowProc - Performance may be non-optimal after change in depth\n"); 219706f2543Smrg } 220706f2543Smrg } 221706f2543Smrg else 222706f2543Smrg { 223706f2543Smrg /* Flag that we have a valid screen depth */ 224706f2543Smrg s_pScreenPriv->fBadDepth = FALSE; 225706f2543Smrg } 226706f2543Smrg 227706f2543Smrg /* 228706f2543Smrg If we could cheaply check if this WM_DISPLAYCHANGE change 229706f2543Smrg affects the monitor(s) which this X screen is displayed on 230706f2543Smrg then we should do so here. For the moment, assume it does. 231706f2543Smrg (this is probably usually the case so that might be an 232706f2543Smrg overoptimization) 233706f2543Smrg */ 234706f2543Smrg { 235706f2543Smrg /* 236706f2543Smrg In rootless modes which are monitor or virtual desktop size 237706f2543Smrg use RandR to resize the X screen 238706f2543Smrg */ 239706f2543Smrg if ((!s_pScreenInfo->fUserGaveHeightAndWidth) && 240706f2543Smrg (s_pScreenInfo->iResizeMode == resizeWithRandr) && 241706f2543Smrg (FALSE 242706f2543Smrg#ifdef XWIN_MULTIWINDOWEXTWM 243706f2543Smrg || s_pScreenInfo->fMWExtWM 244706f2543Smrg#endif 245706f2543Smrg || s_pScreenInfo->fRootless 246706f2543Smrg#ifdef XWIN_MULTIWINDOW 247706f2543Smrg || s_pScreenInfo->fMultiWindow 248706f2543Smrg#endif 249706f2543Smrg )) 250706f2543Smrg { 251706f2543Smrg DWORD dwWidth, dwHeight; 252706f2543Smrg 253706f2543Smrg if (s_pScreenInfo->fMultipleMonitors) 254706f2543Smrg { 255706f2543Smrg /* resize to new virtual desktop size */ 256706f2543Smrg dwWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN); 257706f2543Smrg dwHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN); 258706f2543Smrg } 259706f2543Smrg else 260706f2543Smrg { 261706f2543Smrg /* resize to new size of specified monitor */ 262706f2543Smrg struct GetMonitorInfoData data; 263706f2543Smrg if (QueryMonitor(s_pScreenInfo->iMonitor, &data)) 264706f2543Smrg { 265706f2543Smrg if (data.bMonitorSpecifiedExists == TRUE) 266706f2543Smrg { 267706f2543Smrg dwWidth = data.monitorWidth; 268706f2543Smrg dwHeight = data.monitorHeight; 269706f2543Smrg /* 270706f2543Smrg XXX: monitor may have changed position, 271706f2543Smrg so we might need to update xinerama data 272706f2543Smrg */ 273706f2543Smrg } 274706f2543Smrg else 275706f2543Smrg { 276706f2543Smrg ErrorF ("Monitor number %d no longer exists!\n", s_pScreenInfo->iMonitor); 277706f2543Smrg } 278706f2543Smrg } 279706f2543Smrg } 280706f2543Smrg 281706f2543Smrg /* 282706f2543Smrg XXX: probably a small bug here: we don't compute the work area 283706f2543Smrg and allow for task bar 284706f2543Smrg 285706f2543Smrg XXX: generally, we don't allow for the task bar being moved after 286706f2543Smrg the server is started 287706f2543Smrg */ 288706f2543Smrg 289706f2543Smrg /* Set screen size to match new size, if it is different to current */ 290706f2543Smrg if ((s_pScreenInfo->dwWidth != dwWidth) || 291706f2543Smrg (s_pScreenInfo->dwHeight != dwHeight)) 292706f2543Smrg { 293706f2543Smrg winDoRandRScreenSetSize(s_pScreen, 294706f2543Smrg dwWidth, 295706f2543Smrg dwHeight, 296706f2543Smrg (dwWidth * 25.4) / monitorResolution, 297706f2543Smrg (dwHeight * 25.4) / monitorResolution); 298706f2543Smrg } 299706f2543Smrg } 300706f2543Smrg else 301706f2543Smrg { 302706f2543Smrg /* 303706f2543Smrg * We can simply recreate the same-sized primary surface when 304706f2543Smrg * the display dimensions change. 305706f2543Smrg */ 306706f2543Smrg 307706f2543Smrg /* 308706f2543Smrg * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface 309706f2543Smrg * and CreatePrimarySurface function pointers to point 310706f2543Smrg * to the no operation function, NoopDDA. This allows us 311706f2543Smrg * to blindly call these functions, even if they are not 312706f2543Smrg * relevant to the current engine (e.g., Shadow GDI). 313706f2543Smrg */ 314706f2543Smrg 315706f2543Smrg winDebug ("winWindowProc - WM_DISPLAYCHANGE - Releasing and recreating primary surface\n"); 316706f2543Smrg 317706f2543Smrg /* Release the old primary surface */ 318706f2543Smrg (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen); 319706f2543Smrg 320706f2543Smrg /* Create the new primary surface */ 321706f2543Smrg (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen); 322706f2543Smrg } 323706f2543Smrg } 324706f2543Smrg 325706f2543Smrg break; 326706f2543Smrg 327706f2543Smrg case WM_SIZE: 328706f2543Smrg { 329706f2543Smrg SCROLLINFO si; 330706f2543Smrg RECT rcWindow; 331706f2543Smrg int iWidth, iHeight; 332706f2543Smrg 333706f2543Smrg#if CYGDEBUG 334706f2543Smrg winDebug ("winWindowProc - WM_SIZE\n"); 335706f2543Smrg#endif 336706f2543Smrg 337706f2543Smrg /* Break if we do not allow resizing */ 338706f2543Smrg if ((s_pScreenInfo->iResizeMode == notAllowed) 339706f2543Smrg || !s_pScreenInfo->fDecoration 340706f2543Smrg#ifdef XWIN_MULTIWINDOWEXTWM 341706f2543Smrg || s_pScreenInfo->fMWExtWM 342706f2543Smrg#endif 343706f2543Smrg || s_pScreenInfo->fRootless 344706f2543Smrg#ifdef XWIN_MULTIWINDOW 345706f2543Smrg || s_pScreenInfo->fMultiWindow 346706f2543Smrg#endif 347706f2543Smrg || s_pScreenInfo->fFullScreen) 348706f2543Smrg break; 349706f2543Smrg 350706f2543Smrg /* No need to resize if we get minimized */ 351706f2543Smrg if (wParam == SIZE_MINIMIZED) 352706f2543Smrg return 0; 353706f2543Smrg 354706f2543Smrg ErrorF ("winWindowProc - WM_SIZE - new client area w: %d h: %d\n", 355706f2543Smrg LOWORD (lParam), HIWORD (lParam)); 356706f2543Smrg 357706f2543Smrg if (s_pScreenInfo->iResizeMode == resizeWithRandr) 358706f2543Smrg { 359706f2543Smrg /* Actual resizing is done on WM_EXITSIZEMOVE */ 360706f2543Smrg return 0; 361706f2543Smrg } 362706f2543Smrg 363706f2543Smrg /* Otherwise iResizeMode == resizeWithScrollbars */ 364706f2543Smrg 365706f2543Smrg /* 366706f2543Smrg * Get the size of the whole window, including client area, 367706f2543Smrg * scrollbars, and non-client area decorations (caption, borders). 368706f2543Smrg * We do this because we need to check if the client area 369706f2543Smrg * without scrollbars is large enough to display the whole visual. 370706f2543Smrg * The new client area size passed by lParam already subtracts 371706f2543Smrg * the size of the scrollbars if they are currently displayed. 372706f2543Smrg * So checking is LOWORD(lParam) == visual_width and 373706f2543Smrg * HIWORD(lParam) == visual_height will never tell us to hide 374706f2543Smrg * the scrollbars because the client area would always be too small. 375706f2543Smrg * GetClientRect returns the same sizes given by lParam, so we 376706f2543Smrg * cannot use GetClientRect either. 377706f2543Smrg */ 378706f2543Smrg GetWindowRect (hwnd, &rcWindow); 379706f2543Smrg iWidth = rcWindow.right - rcWindow.left; 380706f2543Smrg iHeight = rcWindow.bottom - rcWindow.top; 381706f2543Smrg 382706f2543Smrg /* Subtract the frame size from the window size. */ 383706f2543Smrg iWidth -= 2 * GetSystemMetrics (SM_CXSIZEFRAME); 384706f2543Smrg iHeight -= (2 * GetSystemMetrics (SM_CYSIZEFRAME) 385706f2543Smrg + GetSystemMetrics (SM_CYCAPTION)); 386706f2543Smrg 387706f2543Smrg /* 388706f2543Smrg * Update scrollbar page sizes. 389706f2543Smrg * NOTE: If page size == range, then the scrollbar is 390706f2543Smrg * automatically hidden. 391706f2543Smrg */ 392706f2543Smrg 393706f2543Smrg /* Is the naked client area large enough to show the whole visual? */ 394706f2543Smrg if (iWidth < s_pScreenInfo->dwWidth 395706f2543Smrg || iHeight < s_pScreenInfo->dwHeight) 396706f2543Smrg { 397706f2543Smrg /* Client area too small to display visual, use scrollbars */ 398706f2543Smrg iWidth -= GetSystemMetrics (SM_CXVSCROLL); 399706f2543Smrg iHeight -= GetSystemMetrics (SM_CYHSCROLL); 400706f2543Smrg } 401706f2543Smrg 402706f2543Smrg /* Set the horizontal scrollbar page size */ 403706f2543Smrg si.cbSize = sizeof (si); 404706f2543Smrg si.fMask = SIF_PAGE | SIF_RANGE; 405706f2543Smrg si.nMin = 0; 406706f2543Smrg si.nMax = s_pScreenInfo->dwWidth - 1; 407706f2543Smrg si.nPage = iWidth; 408706f2543Smrg SetScrollInfo (hwnd, SB_HORZ, &si, TRUE); 409706f2543Smrg 410706f2543Smrg /* Set the vertical scrollbar page size */ 411706f2543Smrg si.cbSize = sizeof (si); 412706f2543Smrg si.fMask = SIF_PAGE | SIF_RANGE; 413706f2543Smrg si.nMin = 0; 414706f2543Smrg si.nMax = s_pScreenInfo->dwHeight - 1; 415706f2543Smrg si.nPage = iHeight; 416706f2543Smrg SetScrollInfo (hwnd, SB_VERT, &si, TRUE); 417706f2543Smrg 418706f2543Smrg /* 419706f2543Smrg * NOTE: Scrollbars may have moved if they were at the 420706f2543Smrg * far right/bottom, so we query their current position. 421706f2543Smrg */ 422706f2543Smrg 423706f2543Smrg /* Get the horizontal scrollbar position and set the offset */ 424706f2543Smrg si.cbSize = sizeof (si); 425706f2543Smrg si.fMask = SIF_POS; 426706f2543Smrg GetScrollInfo (hwnd, SB_HORZ, &si); 427706f2543Smrg s_pScreenInfo->dwXOffset = -si.nPos; 428706f2543Smrg 429706f2543Smrg /* Get the vertical scrollbar position and set the offset */ 430706f2543Smrg si.cbSize = sizeof (si); 431706f2543Smrg si.fMask = SIF_POS; 432706f2543Smrg GetScrollInfo (hwnd, SB_VERT, &si); 433706f2543Smrg s_pScreenInfo->dwYOffset = -si.nPos; 434706f2543Smrg } 435706f2543Smrg return 0; 436706f2543Smrg 437706f2543Smrg case WM_ENTERSIZEMOVE: 438706f2543Smrg ErrorF("winWindowProc - WM_ENTERSIZEMOVE\n"); 439706f2543Smrg break; 440706f2543Smrg 441706f2543Smrg case WM_EXITSIZEMOVE: 442706f2543Smrg ErrorF("winWindowProc - WM_EXITSIZEMOVE\n"); 443706f2543Smrg 444706f2543Smrg if (s_pScreenInfo->iResizeMode == resizeWithRandr) 445706f2543Smrg { 446706f2543Smrg /* Set screen size to match new client area, if it is different to current */ 447706f2543Smrg RECT rcClient; 448706f2543Smrg DWORD dwWidth, dwHeight; 449706f2543Smrg 450706f2543Smrg GetClientRect (hwnd, &rcClient); 451706f2543Smrg dwWidth = rcClient.right - rcClient.left; 452706f2543Smrg dwHeight = rcClient.bottom - rcClient.top; 453706f2543Smrg 454706f2543Smrg if ((s_pScreenInfo->dwWidth != dwWidth) || 455706f2543Smrg (s_pScreenInfo->dwHeight != dwHeight)) 456706f2543Smrg { 457706f2543Smrg /* mm = dots * (25.4 mm / inch) / (dots / inch) */ 458706f2543Smrg winDoRandRScreenSetSize(s_pScreen, 459706f2543Smrg dwWidth, 460706f2543Smrg dwHeight, 461706f2543Smrg (dwWidth * 25.4) / monitorResolution, 462706f2543Smrg (dwHeight * 25.4) / monitorResolution); 463706f2543Smrg } 464706f2543Smrg } 465706f2543Smrg 466706f2543Smrg break; 467706f2543Smrg 468706f2543Smrg case WM_VSCROLL: 469706f2543Smrg { 470706f2543Smrg SCROLLINFO si; 471706f2543Smrg int iVertPos; 472706f2543Smrg 473706f2543Smrg#if CYGDEBUG 474706f2543Smrg winDebug ("winWindowProc - WM_VSCROLL\n"); 475706f2543Smrg#endif 476706f2543Smrg 477706f2543Smrg /* Get vertical scroll bar info */ 478706f2543Smrg si.cbSize = sizeof (si); 479706f2543Smrg si.fMask = SIF_ALL; 480706f2543Smrg GetScrollInfo (hwnd, SB_VERT, &si); 481706f2543Smrg 482706f2543Smrg /* Save the vertical position for comparison later */ 483706f2543Smrg iVertPos = si.nPos; 484706f2543Smrg 485706f2543Smrg /* 486706f2543Smrg * Don't forget: 487706f2543Smrg * moving the scrollbar to the DOWN, scroll the content UP 488706f2543Smrg */ 489706f2543Smrg switch (LOWORD(wParam)) 490706f2543Smrg { 491706f2543Smrg case SB_TOP: 492706f2543Smrg si.nPos = si.nMin; 493706f2543Smrg break; 494706f2543Smrg 495706f2543Smrg case SB_BOTTOM: 496706f2543Smrg si.nPos = si.nMax - si.nPage + 1; 497706f2543Smrg break; 498706f2543Smrg 499706f2543Smrg case SB_LINEUP: 500706f2543Smrg si.nPos -= 1; 501706f2543Smrg break; 502706f2543Smrg 503706f2543Smrg case SB_LINEDOWN: 504706f2543Smrg si.nPos += 1; 505706f2543Smrg break; 506706f2543Smrg 507706f2543Smrg case SB_PAGEUP: 508706f2543Smrg si.nPos -= si.nPage; 509706f2543Smrg break; 510706f2543Smrg 511706f2543Smrg case SB_PAGEDOWN: 512706f2543Smrg si.nPos += si.nPage; 513706f2543Smrg break; 514706f2543Smrg 515706f2543Smrg case SB_THUMBTRACK: 516706f2543Smrg si.nPos = si.nTrackPos; 517706f2543Smrg break; 518706f2543Smrg 519706f2543Smrg default: 520706f2543Smrg break; 521706f2543Smrg } 522706f2543Smrg 523706f2543Smrg /* 524706f2543Smrg * We retrieve the position after setting it, 525706f2543Smrg * because Windows may adjust it. 526706f2543Smrg */ 527706f2543Smrg si.fMask = SIF_POS; 528706f2543Smrg SetScrollInfo (hwnd, SB_VERT, &si, TRUE); 529706f2543Smrg GetScrollInfo (hwnd, SB_VERT, &si); 530706f2543Smrg 531706f2543Smrg /* Scroll the window if the position has changed */ 532706f2543Smrg if (si.nPos != iVertPos) 533706f2543Smrg { 534706f2543Smrg /* Save the new offset for bit block transfers, etc. */ 535706f2543Smrg s_pScreenInfo->dwYOffset = -si.nPos; 536706f2543Smrg 537706f2543Smrg /* Change displayed region in the window */ 538706f2543Smrg ScrollWindowEx (hwnd, 539706f2543Smrg 0, 540706f2543Smrg iVertPos - si.nPos, 541706f2543Smrg NULL, 542706f2543Smrg NULL, 543706f2543Smrg NULL, 544706f2543Smrg NULL, 545706f2543Smrg SW_INVALIDATE); 546706f2543Smrg 547706f2543Smrg /* Redraw the window contents */ 548706f2543Smrg UpdateWindow (hwnd); 549706f2543Smrg } 550706f2543Smrg } 551706f2543Smrg return 0; 552706f2543Smrg 553706f2543Smrg case WM_HSCROLL: 554706f2543Smrg { 555706f2543Smrg SCROLLINFO si; 556706f2543Smrg int iHorzPos; 557706f2543Smrg 558706f2543Smrg#if CYGDEBUG 559706f2543Smrg winDebug ("winWindowProc - WM_HSCROLL\n"); 560706f2543Smrg#endif 561706f2543Smrg 562706f2543Smrg /* Get horizontal scroll bar info */ 563706f2543Smrg si.cbSize = sizeof (si); 564706f2543Smrg si.fMask = SIF_ALL; 565706f2543Smrg GetScrollInfo (hwnd, SB_HORZ, &si); 566706f2543Smrg 567706f2543Smrg /* Save the horizontal position for comparison later */ 568706f2543Smrg iHorzPos = si.nPos; 569706f2543Smrg 570706f2543Smrg /* 571706f2543Smrg * Don't forget: 572706f2543Smrg * moving the scrollbar to the RIGHT, scroll the content LEFT 573706f2543Smrg */ 574706f2543Smrg switch (LOWORD(wParam)) 575706f2543Smrg { 576706f2543Smrg case SB_LEFT: 577706f2543Smrg si.nPos = si.nMin; 578706f2543Smrg break; 579706f2543Smrg 580706f2543Smrg case SB_RIGHT: 581706f2543Smrg si.nPos = si.nMax - si.nPage + 1; 582706f2543Smrg break; 583706f2543Smrg 584706f2543Smrg case SB_LINELEFT: 585706f2543Smrg si.nPos -= 1; 586706f2543Smrg break; 587706f2543Smrg 588706f2543Smrg case SB_LINERIGHT: 589706f2543Smrg si.nPos += 1; 590706f2543Smrg break; 591706f2543Smrg 592706f2543Smrg case SB_PAGELEFT: 593706f2543Smrg si.nPos -= si.nPage; 594706f2543Smrg break; 595706f2543Smrg 596706f2543Smrg case SB_PAGERIGHT: 597706f2543Smrg si.nPos += si.nPage; 598706f2543Smrg break; 599706f2543Smrg 600706f2543Smrg case SB_THUMBTRACK: 601706f2543Smrg si.nPos = si.nTrackPos; 602706f2543Smrg break; 603706f2543Smrg 604706f2543Smrg default: 605706f2543Smrg break; 606706f2543Smrg } 607706f2543Smrg 608706f2543Smrg /* 609706f2543Smrg * We retrieve the position after setting it, 610706f2543Smrg * because Windows may adjust it. 611706f2543Smrg */ 612706f2543Smrg si.fMask = SIF_POS; 613706f2543Smrg SetScrollInfo (hwnd, SB_HORZ, &si, TRUE); 614706f2543Smrg GetScrollInfo (hwnd, SB_HORZ, &si); 615706f2543Smrg 616706f2543Smrg /* Scroll the window if the position has changed */ 617706f2543Smrg if (si.nPos != iHorzPos) 618706f2543Smrg { 619706f2543Smrg /* Save the new offset for bit block transfers, etc. */ 620706f2543Smrg s_pScreenInfo->dwXOffset = -si.nPos; 621706f2543Smrg 622706f2543Smrg /* Change displayed region in the window */ 623706f2543Smrg ScrollWindowEx (hwnd, 624706f2543Smrg iHorzPos - si.nPos, 625706f2543Smrg 0, 626706f2543Smrg NULL, 627706f2543Smrg NULL, 628706f2543Smrg NULL, 629706f2543Smrg NULL, 630706f2543Smrg SW_INVALIDATE); 631706f2543Smrg 632706f2543Smrg /* Redraw the window contents */ 633706f2543Smrg UpdateWindow (hwnd); 634706f2543Smrg } 635706f2543Smrg } 636706f2543Smrg return 0; 637706f2543Smrg 638706f2543Smrg case WM_GETMINMAXINFO: 639706f2543Smrg { 640706f2543Smrg MINMAXINFO *pMinMaxInfo = (MINMAXINFO *) lParam; 641706f2543Smrg int iCaptionHeight; 642706f2543Smrg int iBorderHeight, iBorderWidth; 643706f2543Smrg 644706f2543Smrg#if CYGDEBUG 645706f2543Smrg winDebug ("winWindowProc - WM_GETMINMAXINFO - pScreenInfo: %08x\n", 646706f2543Smrg s_pScreenInfo); 647706f2543Smrg#endif 648706f2543Smrg 649706f2543Smrg /* Can't do anything without screen info */ 650706f2543Smrg if (s_pScreenInfo == NULL 651706f2543Smrg || (s_pScreenInfo->iResizeMode != resizeWithScrollbars) 652706f2543Smrg || s_pScreenInfo->fFullScreen 653706f2543Smrg || !s_pScreenInfo->fDecoration 654706f2543Smrg#ifdef XWIN_MULTIWINDOWEXTWM 655706f2543Smrg || s_pScreenInfo->fMWExtWM 656706f2543Smrg#endif 657706f2543Smrg || s_pScreenInfo->fRootless 658706f2543Smrg#ifdef XWIN_MULTIWINDOW 659706f2543Smrg || s_pScreenInfo->fMultiWindow 660706f2543Smrg#endif 661706f2543Smrg ) 662706f2543Smrg break; 663706f2543Smrg 664706f2543Smrg /* 665706f2543Smrg * Here we can override the maximum tracking size, which 666706f2543Smrg * is the largest size that can be assigned to our window 667706f2543Smrg * via the sizing border. 668706f2543Smrg */ 669706f2543Smrg 670706f2543Smrg /* 671706f2543Smrg * FIXME: Do we only need to do this once, since our visual size 672706f2543Smrg * does not change? Does Windows store this value statically 673706f2543Smrg * once we have set it once? 674706f2543Smrg */ 675706f2543Smrg 676706f2543Smrg /* Get the border and caption sizes */ 677706f2543Smrg iCaptionHeight = GetSystemMetrics (SM_CYCAPTION); 678706f2543Smrg iBorderWidth = 2 * GetSystemMetrics (SM_CXSIZEFRAME); 679706f2543Smrg iBorderHeight = 2 * GetSystemMetrics (SM_CYSIZEFRAME); 680706f2543Smrg 681706f2543Smrg /* Allow the full visual to be displayed */ 682706f2543Smrg pMinMaxInfo->ptMaxTrackSize.x 683706f2543Smrg = s_pScreenInfo->dwWidth + iBorderWidth; 684706f2543Smrg pMinMaxInfo->ptMaxTrackSize.y 685706f2543Smrg = s_pScreenInfo->dwHeight + iBorderHeight + iCaptionHeight; 686706f2543Smrg } 687706f2543Smrg return 0; 688706f2543Smrg 689706f2543Smrg case WM_ERASEBKGND: 690706f2543Smrg#if CYGDEBUG 691706f2543Smrg winDebug ("winWindowProc - WM_ERASEBKGND\n"); 692706f2543Smrg#endif 693706f2543Smrg /* 694706f2543Smrg * Pretend that we did erase the background but we don't care, 695706f2543Smrg * the application uses the full window estate. This avoids some 696706f2543Smrg * flickering when resizing. 697706f2543Smrg */ 698706f2543Smrg return TRUE; 699706f2543Smrg 700706f2543Smrg case WM_PAINT: 701706f2543Smrg#if CYGDEBUG 702706f2543Smrg winDebug ("winWindowProc - WM_PAINT\n"); 703706f2543Smrg#endif 704706f2543Smrg /* Only paint if we have privates and the server is enabled */ 705706f2543Smrg if (s_pScreenPriv == NULL 706706f2543Smrg || !s_pScreenPriv->fEnabled 707706f2543Smrg || (s_pScreenInfo->fFullScreen && !s_pScreenPriv->fActive) 708706f2543Smrg || s_pScreenPriv->fBadDepth) 709706f2543Smrg { 710706f2543Smrg /* We don't want to paint */ 711706f2543Smrg break; 712706f2543Smrg } 713706f2543Smrg 714706f2543Smrg /* Break out here if we don't have a valid paint routine */ 715706f2543Smrg if (s_pScreenPriv->pwinBltExposedRegions == NULL) 716706f2543Smrg break; 717706f2543Smrg 718706f2543Smrg /* Call the engine dependent repainter */ 719706f2543Smrg (*s_pScreenPriv->pwinBltExposedRegions) (s_pScreen); 720706f2543Smrg return 0; 721706f2543Smrg 722706f2543Smrg case WM_PALETTECHANGED: 723706f2543Smrg { 724706f2543Smrg#if CYGDEBUG 725706f2543Smrg winDebug ("winWindowProc - WM_PALETTECHANGED\n"); 726706f2543Smrg#endif 727706f2543Smrg /* 728706f2543Smrg * Don't process if we don't have privates or a colormap, 729706f2543Smrg * or if we have an invalid depth. 730706f2543Smrg */ 731706f2543Smrg if (s_pScreenPriv == NULL 732706f2543Smrg || s_pScreenPriv->pcmapInstalled == NULL 733706f2543Smrg || s_pScreenPriv->fBadDepth) 734706f2543Smrg break; 735706f2543Smrg 736706f2543Smrg /* Return if we caused the palette to change */ 737706f2543Smrg if ((HWND) wParam == hwnd) 738706f2543Smrg { 739706f2543Smrg /* Redraw the screen */ 740706f2543Smrg (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen); 741706f2543Smrg return 0; 742706f2543Smrg } 743706f2543Smrg 744706f2543Smrg /* Reinstall the windows palette */ 745706f2543Smrg (*s_pScreenPriv->pwinRealizeInstalledPalette) (s_pScreen); 746706f2543Smrg 747706f2543Smrg /* Redraw the screen */ 748706f2543Smrg (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen); 749706f2543Smrg return 0; 750706f2543Smrg } 751706f2543Smrg 752706f2543Smrg case WM_MOUSEMOVE: 753706f2543Smrg /* We can't do anything without privates */ 754706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 755706f2543Smrg break; 756706f2543Smrg 757706f2543Smrg /* We can't do anything without g_pwinPointer */ 758706f2543Smrg if (g_pwinPointer == NULL) 759706f2543Smrg break; 760706f2543Smrg 761706f2543Smrg /* Has the mouse pointer crossed screens? */ 762706f2543Smrg if (s_pScreen != miPointerGetScreen(g_pwinPointer)) 763706f2543Smrg miPointerSetScreen (g_pwinPointer, s_pScreenInfo->dwScreen, 764706f2543Smrg GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset, 765706f2543Smrg GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset); 766706f2543Smrg 767706f2543Smrg /* Are we tracking yet? */ 768706f2543Smrg if (!s_fTracking) 769706f2543Smrg { 770706f2543Smrg TRACKMOUSEEVENT tme; 771706f2543Smrg 772706f2543Smrg /* Setup data structure */ 773706f2543Smrg ZeroMemory (&tme, sizeof (tme)); 774706f2543Smrg tme.cbSize = sizeof (tme); 775706f2543Smrg tme.dwFlags = TME_LEAVE; 776706f2543Smrg tme.hwndTrack = hwnd; 777706f2543Smrg 778706f2543Smrg /* Call the tracking function */ 779706f2543Smrg if (!(*g_fpTrackMouseEvent) (&tme)) 780706f2543Smrg ErrorF ("winWindowProc - _TrackMouseEvent failed\n"); 781706f2543Smrg 782706f2543Smrg /* Flag that we are tracking now */ 783706f2543Smrg s_fTracking = TRUE; 784706f2543Smrg } 785706f2543Smrg 786706f2543Smrg /* Hide or show the Windows mouse cursor */ 787706f2543Smrg if (g_fSoftwareCursor && g_fCursor && (s_pScreenPriv->fActive || s_pScreenInfo->fLessPointer)) 788706f2543Smrg { 789706f2543Smrg /* Hide Windows cursor */ 790706f2543Smrg g_fCursor = FALSE; 791706f2543Smrg ShowCursor (FALSE); 792706f2543Smrg } 793706f2543Smrg else if (g_fSoftwareCursor && !g_fCursor && !s_pScreenPriv->fActive 794706f2543Smrg && !s_pScreenInfo->fLessPointer) 795706f2543Smrg { 796706f2543Smrg /* Show Windows cursor */ 797706f2543Smrg g_fCursor = TRUE; 798706f2543Smrg ShowCursor (TRUE); 799706f2543Smrg } 800706f2543Smrg 801706f2543Smrg /* Deliver absolute cursor position to X Server */ 802706f2543Smrg winEnqueueMotion(GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset, 803706f2543Smrg GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset); 804706f2543Smrg return 0; 805706f2543Smrg 806706f2543Smrg case WM_NCMOUSEMOVE: 807706f2543Smrg /* 808706f2543Smrg * We break instead of returning 0 since we need to call 809706f2543Smrg * DefWindowProc to get the mouse cursor changes 810706f2543Smrg * and min/max/close button highlighting in Windows XP. 811706f2543Smrg * The Platform SDK says that you should return 0 if you 812706f2543Smrg * process this message, but it fails to mention that you 813706f2543Smrg * will give up any default functionality if you do return 0. 814706f2543Smrg */ 815706f2543Smrg 816706f2543Smrg /* We can't do anything without privates */ 817706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 818706f2543Smrg break; 819706f2543Smrg 820706f2543Smrg /* Non-client mouse movement, show Windows cursor */ 821706f2543Smrg if (g_fSoftwareCursor && !g_fCursor) 822706f2543Smrg { 823706f2543Smrg g_fCursor = TRUE; 824706f2543Smrg ShowCursor (TRUE); 825706f2543Smrg } 826706f2543Smrg break; 827706f2543Smrg 828706f2543Smrg case WM_MOUSELEAVE: 829706f2543Smrg /* Mouse has left our client area */ 830706f2543Smrg 831706f2543Smrg /* Flag that we are no longer tracking */ 832706f2543Smrg s_fTracking = FALSE; 833706f2543Smrg 834706f2543Smrg /* Show the mouse cursor, if necessary */ 835706f2543Smrg if (g_fSoftwareCursor && !g_fCursor) 836706f2543Smrg { 837706f2543Smrg g_fCursor = TRUE; 838706f2543Smrg ShowCursor (TRUE); 839706f2543Smrg } 840706f2543Smrg return 0; 841706f2543Smrg 842706f2543Smrg case WM_LBUTTONDBLCLK: 843706f2543Smrg case WM_LBUTTONDOWN: 844706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 845706f2543Smrg break; 846706f2543Smrg if (s_pScreenInfo->fRootless 847706f2543Smrg#ifdef XWIN_MULTIWINDOWEXTWM 848706f2543Smrg || s_pScreenInfo->fMWExtWM 849706f2543Smrg#endif 850706f2543Smrg ) 851706f2543Smrg SetCapture (hwnd); 852706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam); 853706f2543Smrg 854706f2543Smrg case WM_LBUTTONUP: 855706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 856706f2543Smrg break; 857706f2543Smrg if (s_pScreenInfo->fRootless 858706f2543Smrg#ifdef XWIN_MULTIWINDOWEXTWM 859706f2543Smrg || s_pScreenInfo->fMWExtWM 860706f2543Smrg#endif 861706f2543Smrg ) 862706f2543Smrg ReleaseCapture (); 863706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam); 864706f2543Smrg 865706f2543Smrg case WM_MBUTTONDBLCLK: 866706f2543Smrg case WM_MBUTTONDOWN: 867706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 868706f2543Smrg break; 869706f2543Smrg if (s_pScreenInfo->fRootless 870706f2543Smrg#ifdef XWIN_MULTIWINDOWEXTWM 871706f2543Smrg || s_pScreenInfo->fMWExtWM 872706f2543Smrg#endif 873706f2543Smrg ) 874706f2543Smrg SetCapture (hwnd); 875706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam); 876706f2543Smrg 877706f2543Smrg case WM_MBUTTONUP: 878706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 879706f2543Smrg break; 880706f2543Smrg if (s_pScreenInfo->fRootless 881706f2543Smrg#ifdef XWIN_MULTIWINDOWEXTWM 882706f2543Smrg || s_pScreenInfo->fMWExtWM 883706f2543Smrg#endif 884706f2543Smrg ) 885706f2543Smrg ReleaseCapture (); 886706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam); 887706f2543Smrg 888706f2543Smrg case WM_RBUTTONDBLCLK: 889706f2543Smrg case WM_RBUTTONDOWN: 890706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 891706f2543Smrg break; 892706f2543Smrg if (s_pScreenInfo->fRootless 893706f2543Smrg#ifdef XWIN_MULTIWINDOWEXTWM 894706f2543Smrg || s_pScreenInfo->fMWExtWM 895706f2543Smrg#endif 896706f2543Smrg ) 897706f2543Smrg SetCapture (hwnd); 898706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam); 899706f2543Smrg 900706f2543Smrg case WM_RBUTTONUP: 901706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 902706f2543Smrg break; 903706f2543Smrg if (s_pScreenInfo->fRootless 904706f2543Smrg#ifdef XWIN_MULTIWINDOWEXTWM 905706f2543Smrg || s_pScreenInfo->fMWExtWM 906706f2543Smrg#endif 907706f2543Smrg ) 908706f2543Smrg ReleaseCapture (); 909706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam); 910706f2543Smrg 911706f2543Smrg case WM_XBUTTONDBLCLK: 912706f2543Smrg case WM_XBUTTONDOWN: 913706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 914706f2543Smrg break; 915706f2543Smrg if (s_pScreenInfo->fRootless 916706f2543Smrg#ifdef XWIN_MULTIWINDOWEXTWM 917706f2543Smrg || s_pScreenInfo->fMWExtWM 918706f2543Smrg#endif 919706f2543Smrg ) 920706f2543Smrg SetCapture (hwnd); 921706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonPress, HIWORD(wParam) + 5, wParam); 922706f2543Smrg case WM_XBUTTONUP: 923706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 924706f2543Smrg break; 925706f2543Smrg if (s_pScreenInfo->fRootless 926706f2543Smrg#ifdef XWIN_MULTIWINDOWEXTWM 927706f2543Smrg || s_pScreenInfo->fMWExtWM 928706f2543Smrg#endif 929706f2543Smrg ) 930706f2543Smrg ReleaseCapture (); 931706f2543Smrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam); 932706f2543Smrg 933706f2543Smrg case WM_TIMER: 934706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 935706f2543Smrg break; 936706f2543Smrg 937706f2543Smrg /* Branch on the timer id */ 938706f2543Smrg switch (wParam) 939706f2543Smrg { 940706f2543Smrg case WIN_E3B_TIMER_ID: 941706f2543Smrg /* Send delayed button press */ 942706f2543Smrg winMouseButtonsSendEvent (ButtonPress, 943706f2543Smrg s_pScreenPriv->iE3BCachedPress); 944706f2543Smrg 945706f2543Smrg /* Kill this timer */ 946706f2543Smrg KillTimer (s_pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID); 947706f2543Smrg 948706f2543Smrg /* Clear screen privates flags */ 949706f2543Smrg s_pScreenPriv->iE3BCachedPress = 0; 950706f2543Smrg break; 951706f2543Smrg 952706f2543Smrg case WIN_POLLING_MOUSE_TIMER_ID: 953706f2543Smrg { 954706f2543Smrg POINT point; 955706f2543Smrg WPARAM wL, wM, wR, wShift, wCtrl; 956706f2543Smrg LPARAM lPos; 957706f2543Smrg 958706f2543Smrg /* Get the current position of the mouse cursor */ 959706f2543Smrg GetCursorPos (&point); 960706f2543Smrg 961706f2543Smrg /* Map from screen (-X, -Y) to root (0, 0) */ 962706f2543Smrg point.x -= GetSystemMetrics (SM_XVIRTUALSCREEN); 963706f2543Smrg point.y -= GetSystemMetrics (SM_YVIRTUALSCREEN); 964706f2543Smrg 965706f2543Smrg /* Deliver absolute cursor position to X Server */ 966706f2543Smrg winEnqueueMotion(point.x , point.y); 967706f2543Smrg 968706f2543Smrg /* Check if a button was released but we didn't see it */ 969706f2543Smrg GetCursorPos (&point); 970706f2543Smrg wL = (GetKeyState (VK_LBUTTON) & 0x8000)?MK_LBUTTON:0; 971706f2543Smrg wM = (GetKeyState (VK_MBUTTON) & 0x8000)?MK_MBUTTON:0; 972706f2543Smrg wR = (GetKeyState (VK_RBUTTON) & 0x8000)?MK_RBUTTON:0; 973706f2543Smrg wShift = (GetKeyState (VK_SHIFT) & 0x8000)?MK_SHIFT:0; 974706f2543Smrg wCtrl = (GetKeyState (VK_CONTROL) & 0x8000)?MK_CONTROL:0; 975706f2543Smrg lPos = MAKELPARAM(point.x, point.y); 976706f2543Smrg if (g_fButton[0] & !wL) 977706f2543Smrg PostMessage (hwnd, WM_LBUTTONUP, wCtrl|wM|wR|wShift, lPos); 978706f2543Smrg if (g_fButton[1] & !wM) 979706f2543Smrg PostMessage (hwnd, WM_MBUTTONUP, wCtrl|wL|wR|wShift, lPos); 980706f2543Smrg if (g_fButton[2] & !wR) 981706f2543Smrg PostMessage (hwnd, WM_RBUTTONUP, wCtrl|wL|wM|wShift, lPos); 982706f2543Smrg } 983706f2543Smrg } 984706f2543Smrg return 0; 985706f2543Smrg 986706f2543Smrg case WM_CTLCOLORSCROLLBAR: 987706f2543Smrg FatalError ("winWindowProc - WM_CTLCOLORSCROLLBAR - We are not " 988706f2543Smrg "supposed to get this message. Exiting.\n"); 989706f2543Smrg return 0; 990706f2543Smrg 991706f2543Smrg case WM_MOUSEWHEEL: 992706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 993706f2543Smrg break; 994706f2543Smrg#if CYGDEBUG 995706f2543Smrg winDebug ("winWindowProc - WM_MOUSEWHEEL\n"); 996706f2543Smrg#endif 997706f2543Smrg winMouseWheel (s_pScreen, GET_WHEEL_DELTA_WPARAM(wParam)); 998706f2543Smrg break; 999706f2543Smrg 1000706f2543Smrg case WM_SETFOCUS: 1001706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 1002706f2543Smrg break; 1003706f2543Smrg 1004706f2543Smrg /* Restore the state of all mode keys */ 1005706f2543Smrg winRestoreModeKeyStates (); 1006706f2543Smrg 1007706f2543Smrg /* Add the keyboard hook if possible */ 1008706f2543Smrg if (g_fKeyboardHookLL) 1009706f2543Smrg g_fKeyboardHookLL = winInstallKeyboardHookLL (); 1010706f2543Smrg return 0; 1011706f2543Smrg 1012706f2543Smrg case WM_KILLFOCUS: 1013706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 1014706f2543Smrg break; 1015706f2543Smrg 1016706f2543Smrg /* Release any pressed keys */ 1017706f2543Smrg winKeybdReleaseKeys (); 1018706f2543Smrg 1019706f2543Smrg /* Remove our keyboard hook if it is installed */ 1020706f2543Smrg winRemoveKeyboardHookLL (); 1021706f2543Smrg return 0; 1022706f2543Smrg 1023706f2543Smrg case WM_SYSKEYDOWN: 1024706f2543Smrg case WM_KEYDOWN: 1025706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 1026706f2543Smrg break; 1027706f2543Smrg 1028706f2543Smrg /* 1029706f2543Smrg * FIXME: Catching Alt-F4 like this is really terrible. This should 1030706f2543Smrg * be generalized to handle other Windows keyboard signals. Actually, 1031706f2543Smrg * the list keys to catch and the actions to perform when caught should 1032706f2543Smrg * be configurable; that way user's can customize the keys that they 1033706f2543Smrg * need to have passed through to their window manager or apps, or they 1034706f2543Smrg * can remap certain actions to new key codes that do not conflict 1035706f2543Smrg * with the X apps that they are using. Yeah, that'll take awhile. 1036706f2543Smrg */ 1037706f2543Smrg if ((s_pScreenInfo->fUseWinKillKey && wParam == VK_F4 1038706f2543Smrg && (GetKeyState (VK_MENU) & 0x8000)) 1039706f2543Smrg || (s_pScreenInfo->fUseUnixKillKey && wParam == VK_BACK 1040706f2543Smrg && (GetKeyState (VK_MENU) & 0x8000) 1041706f2543Smrg && (GetKeyState (VK_CONTROL) & 0x8000))) 1042706f2543Smrg { 1043706f2543Smrg /* 1044706f2543Smrg * Better leave this message here, just in case some unsuspecting 1045706f2543Smrg * user enters Alt + F4 and is surprised when the application 1046706f2543Smrg * quits. 1047706f2543Smrg */ 1048706f2543Smrg ErrorF ("winWindowProc - WM_*KEYDOWN - Closekey hit, quitting\n"); 1049706f2543Smrg 1050706f2543Smrg /* Display Exit dialog */ 1051706f2543Smrg winDisplayExitDialog (s_pScreenPriv); 1052706f2543Smrg return 0; 1053706f2543Smrg } 1054706f2543Smrg 1055706f2543Smrg /* 1056706f2543Smrg * Don't do anything for the Windows keys, as focus will soon 1057706f2543Smrg * be returned to Windows. We may be able to trap the Windows keys, 1058706f2543Smrg * but we should determine if that is desirable before doing so. 1059706f2543Smrg */ 1060706f2543Smrg if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL) 1061706f2543Smrg break; 1062706f2543Smrg 1063706f2543Smrg /* 1064706f2543Smrg * Discard presses generated from Windows auto-repeat 1065706f2543Smrg */ 1066706f2543Smrg if (lParam & (1<<30)) 1067706f2543Smrg { 1068706f2543Smrg switch (wParam) 1069706f2543Smrg { 1070706f2543Smrg /* ago: Pressing LControl while RControl is pressed is 1071706f2543Smrg * Indicated as repeat. Fix this! 1072706f2543Smrg */ 1073706f2543Smrg case VK_CONTROL: 1074706f2543Smrg case VK_SHIFT: 1075706f2543Smrg if (winCheckKeyPressed(wParam, lParam)) 1076706f2543Smrg return 0; 1077706f2543Smrg break; 1078706f2543Smrg default: 1079706f2543Smrg return 0; 1080706f2543Smrg } 1081706f2543Smrg } 1082706f2543Smrg 1083706f2543Smrg /* Discard fake Ctrl_L presses that precede AltGR on non-US keyboards */ 1084706f2543Smrg if (winIsFakeCtrl_L (message, wParam, lParam)) 1085706f2543Smrg return 0; 1086706f2543Smrg 1087706f2543Smrg /* Translate Windows key code to X scan code */ 1088706f2543Smrg winTranslateKey (wParam, lParam, &iScanCode); 1089706f2543Smrg 1090706f2543Smrg /* Ignore repeats for CapsLock */ 1091706f2543Smrg if (wParam == VK_CAPITAL) 1092706f2543Smrg lParam = 1; 1093706f2543Smrg 1094706f2543Smrg /* Send the key event(s) */ 1095706f2543Smrg for (i = 0; i < LOWORD(lParam); ++i) 1096706f2543Smrg winSendKeyEvent (iScanCode, TRUE); 1097706f2543Smrg return 0; 1098706f2543Smrg 1099706f2543Smrg case WM_SYSKEYUP: 1100706f2543Smrg case WM_KEYUP: 1101706f2543Smrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 1102706f2543Smrg break; 1103706f2543Smrg 1104706f2543Smrg /* 1105706f2543Smrg * Don't do anything for the Windows keys, as focus will soon 1106706f2543Smrg * be returned to Windows. We may be able to trap the Windows keys, 1107706f2543Smrg * but we should determine if that is desirable before doing so. 1108706f2543Smrg */ 1109706f2543Smrg if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL) 1110706f2543Smrg break; 1111706f2543Smrg 1112706f2543Smrg /* Ignore the fake Ctrl_L that follows an AltGr release */ 1113706f2543Smrg if (winIsFakeCtrl_L (message, wParam, lParam)) 1114706f2543Smrg return 0; 1115706f2543Smrg 1116706f2543Smrg /* Enqueue a keyup event */ 1117706f2543Smrg winTranslateKey (wParam, lParam, &iScanCode); 1118706f2543Smrg winSendKeyEvent (iScanCode, FALSE); 1119706f2543Smrg 1120706f2543Smrg /* Release all pressed shift keys */ 1121706f2543Smrg if (wParam == VK_SHIFT) 1122706f2543Smrg winFixShiftKeys (iScanCode); 1123706f2543Smrg return 0; 1124706f2543Smrg 1125706f2543Smrg case WM_HOTKEY: 1126706f2543Smrg if (s_pScreenPriv == NULL) 1127706f2543Smrg break; 1128706f2543Smrg 1129706f2543Smrg /* Call the engine-specific hot key handler */ 1130706f2543Smrg (*s_pScreenPriv->pwinHotKeyAltTab) (s_pScreen); 1131706f2543Smrg return 0; 1132706f2543Smrg 1133706f2543Smrg case WM_ACTIVATE: 1134706f2543Smrg if (s_pScreenPriv == NULL 1135706f2543Smrg || s_pScreenInfo->fIgnoreInput) 1136706f2543Smrg break; 1137706f2543Smrg 1138706f2543Smrg /* TODO: Override display of window when we have a bad depth */ 1139706f2543Smrg if (LOWORD(wParam) != WA_INACTIVE && s_pScreenPriv->fBadDepth) 1140706f2543Smrg { 1141706f2543Smrg ErrorF ("winWindowProc - WM_ACTIVATE - Bad depth, trying " 1142706f2543Smrg "to override window activation\n"); 1143706f2543Smrg 1144706f2543Smrg /* Minimize the window */ 1145706f2543Smrg ShowWindow (hwnd, SW_MINIMIZE); 1146706f2543Smrg 1147706f2543Smrg /* Display dialog box */ 1148706f2543Smrg if (g_hDlgDepthChange != NULL) 1149706f2543Smrg { 1150706f2543Smrg /* Make the existing dialog box active */ 1151706f2543Smrg SetActiveWindow (g_hDlgDepthChange); 1152706f2543Smrg } 1153706f2543Smrg else 1154706f2543Smrg { 1155706f2543Smrg /* TODO: Recreate the dialog box and bring to the top */ 1156706f2543Smrg ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT); 1157706f2543Smrg } 1158706f2543Smrg 1159706f2543Smrg /* Don't do any other processing of this message */ 1160706f2543Smrg return 0; 1161706f2543Smrg } 1162706f2543Smrg 1163706f2543Smrg#if CYGDEBUG 1164706f2543Smrg winDebug ("winWindowProc - WM_ACTIVATE\n"); 1165706f2543Smrg#endif 1166706f2543Smrg 1167706f2543Smrg /* 1168706f2543Smrg * Focus is being changed to another window. 1169706f2543Smrg * The other window may or may not belong to 1170706f2543Smrg * our process. 1171706f2543Smrg */ 1172706f2543Smrg 1173706f2543Smrg /* Clear any lingering wheel delta */ 1174706f2543Smrg s_pScreenPriv->iDeltaZ = 0; 1175706f2543Smrg 1176706f2543Smrg /* Reshow the Windows mouse cursor if we are being deactivated */ 1177706f2543Smrg if (g_fSoftwareCursor && LOWORD(wParam) == WA_INACTIVE 1178706f2543Smrg && !g_fCursor) 1179706f2543Smrg { 1180706f2543Smrg /* Show Windows cursor */ 1181706f2543Smrg g_fCursor = TRUE; 1182706f2543Smrg ShowCursor (TRUE); 1183706f2543Smrg } 1184706f2543Smrg return 0; 1185706f2543Smrg 1186706f2543Smrg case WM_ACTIVATEAPP: 1187706f2543Smrg if (s_pScreenPriv == NULL 1188706f2543Smrg || s_pScreenInfo->fIgnoreInput) 1189706f2543Smrg break; 1190706f2543Smrg 1191706f2543Smrg#if CYGDEBUG || TRUE 1192706f2543Smrg winDebug ("winWindowProc - WM_ACTIVATEAPP\n"); 1193706f2543Smrg#endif 1194706f2543Smrg 1195706f2543Smrg /* Activate or deactivate */ 1196706f2543Smrg s_pScreenPriv->fActive = wParam; 1197706f2543Smrg 1198706f2543Smrg /* Reshow the Windows mouse cursor if we are being deactivated */ 1199706f2543Smrg if (g_fSoftwareCursor && !s_pScreenPriv->fActive 1200706f2543Smrg && !g_fCursor) 1201706f2543Smrg { 1202706f2543Smrg /* Show Windows cursor */ 1203706f2543Smrg g_fCursor = TRUE; 1204706f2543Smrg ShowCursor (TRUE); 1205706f2543Smrg } 1206706f2543Smrg 1207706f2543Smrg#ifdef XWIN_CLIPBOARD 1208706f2543Smrg /* Make sure the clipboard chain is ok. */ 1209706f2543Smrg winFixClipboardChain (); 1210706f2543Smrg#endif 1211706f2543Smrg 1212706f2543Smrg /* Call engine specific screen activation/deactivation function */ 1213706f2543Smrg (*s_pScreenPriv->pwinActivateApp) (s_pScreen); 1214706f2543Smrg 1215706f2543Smrg#ifdef XWIN_MULTIWINDOWEXTWM 1216706f2543Smrg if (s_pScreenPriv->fActive) 1217706f2543Smrg { 1218706f2543Smrg /* Restack all window unless using built-in wm. */ 1219706f2543Smrg if (s_pScreenInfo->fInternalWM && s_pScreenInfo->fAnotherWMRunning) 1220706f2543Smrg winMWExtWMRestackWindows (s_pScreen); 1221706f2543Smrg } 1222706f2543Smrg#endif 1223706f2543Smrg 1224706f2543Smrg return 0; 1225706f2543Smrg 1226706f2543Smrg case WM_COMMAND: 1227706f2543Smrg switch (LOWORD (wParam)) 1228706f2543Smrg { 1229706f2543Smrg case ID_APP_EXIT: 1230706f2543Smrg /* Display Exit dialog */ 1231706f2543Smrg winDisplayExitDialog (s_pScreenPriv); 1232706f2543Smrg return 0; 1233706f2543Smrg 1234706f2543Smrg#ifdef XWIN_MULTIWINDOW 1235706f2543Smrg case ID_APP_HIDE_ROOT: 1236706f2543Smrg if (s_pScreenPriv->fRootWindowShown) 1237706f2543Smrg ShowWindow (s_pScreenPriv->hwndScreen, SW_HIDE); 1238706f2543Smrg else 1239706f2543Smrg ShowWindow (s_pScreenPriv->hwndScreen, SW_SHOW); 1240706f2543Smrg s_pScreenPriv->fRootWindowShown = !s_pScreenPriv->fRootWindowShown; 1241706f2543Smrg return 0; 1242706f2543Smrg#endif 1243706f2543Smrg 1244706f2543Smrg case ID_APP_ABOUT: 1245706f2543Smrg /* Display the About box */ 1246706f2543Smrg winDisplayAboutDialog (s_pScreenPriv); 1247706f2543Smrg return 0; 1248706f2543Smrg 1249706f2543Smrg default: 1250706f2543Smrg /* It's probably one of the custom menus... */ 1251706f2543Smrg if (HandleCustomWM_COMMAND (0, LOWORD (wParam))) 1252706f2543Smrg return 0; 1253706f2543Smrg } 1254706f2543Smrg break; 1255706f2543Smrg 1256706f2543Smrg case WM_ENDSESSION: 1257706f2543Smrg case WM_GIVEUP: 1258706f2543Smrg /* Tell X that we are giving up */ 1259706f2543Smrg#ifdef XWIN_MULTIWINDOW 1260706f2543Smrg if (s_pScreenInfo->fMultiWindow) 1261706f2543Smrg winDeinitMultiWindowWM (); 1262706f2543Smrg#endif 1263706f2543Smrg GiveUp (0); 1264706f2543Smrg return 0; 1265706f2543Smrg 1266706f2543Smrg case WM_CLOSE: 1267706f2543Smrg /* Display Exit dialog */ 1268706f2543Smrg winDisplayExitDialog (s_pScreenPriv); 1269706f2543Smrg return 0; 1270706f2543Smrg 1271706f2543Smrg case WM_SETCURSOR: 1272706f2543Smrg if (LOWORD(lParam) == HTCLIENT) 1273706f2543Smrg { 1274706f2543Smrg if (!g_fSoftwareCursor) SetCursor (s_pScreenPriv->cursor.handle); 1275706f2543Smrg return TRUE; 1276706f2543Smrg } 1277706f2543Smrg break; 1278706f2543Smrg 1279706f2543Smrg#ifdef XWIN_MULTIWINDOWEXTWM 1280706f2543Smrg case WM_MANAGE: 1281706f2543Smrg ErrorF ("winWindowProc - WM_MANAGE\n"); 1282706f2543Smrg s_pScreenInfo->fAnotherWMRunning = FALSE; 1283706f2543Smrg 1284706f2543Smrg if (s_pScreenInfo->fInternalWM) 1285706f2543Smrg { 1286706f2543Smrg EnumThreadWindows (g_dwCurrentThreadID, winMWExtWMDecorateWindow, 0); 1287706f2543Smrg //RootlessRepositionWindows (s_pScreen); 1288706f2543Smrg } 1289706f2543Smrg break; 1290706f2543Smrg 1291706f2543Smrg case WM_UNMANAGE: 1292706f2543Smrg ErrorF ("winWindowProc - WM_UNMANAGE\n"); 1293706f2543Smrg s_pScreenInfo->fAnotherWMRunning = TRUE; 1294706f2543Smrg 1295706f2543Smrg if (s_pScreenInfo->fInternalWM) 1296706f2543Smrg { 1297706f2543Smrg EnumThreadWindows (g_dwCurrentThreadID, winMWExtWMDecorateWindow, 0); 1298706f2543Smrg winMWExtWMRestackWindows (s_pScreen); 1299706f2543Smrg } 1300706f2543Smrg break; 1301706f2543Smrg#endif 1302706f2543Smrg 1303706f2543Smrg default: 1304706f2543Smrg if(message == s_uTaskbarRestart) 1305706f2543Smrg { 1306706f2543Smrg winInitNotifyIcon (s_pScreenPriv); 1307706f2543Smrg } 1308706f2543Smrg break; 1309706f2543Smrg } 1310706f2543Smrg 1311706f2543Smrg return DefWindowProc (hwnd, message, wParam, lParam); 1312706f2543Smrg} 1313