winwndproc.c revision 05b261ec
105b261ecSmrg/* 205b261ecSmrg *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 305b261ecSmrg * 405b261ecSmrg *Permission is hereby granted, free of charge, to any person obtaining 505b261ecSmrg * a copy of this software and associated documentation files (the 605b261ecSmrg *"Software"), to deal in the Software without restriction, including 705b261ecSmrg *without limitation the rights to use, copy, modify, merge, publish, 805b261ecSmrg *distribute, sublicense, and/or sell copies of the Software, and to 905b261ecSmrg *permit persons to whom the Software is furnished to do so, subject to 1005b261ecSmrg *the following conditions: 1105b261ecSmrg * 1205b261ecSmrg *The above copyright notice and this permission notice shall be 1305b261ecSmrg *included in all copies or substantial portions of the Software. 1405b261ecSmrg * 1505b261ecSmrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1605b261ecSmrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1705b261ecSmrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1805b261ecSmrg *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR 1905b261ecSmrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 2005b261ecSmrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 2105b261ecSmrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2205b261ecSmrg * 2305b261ecSmrg *Except as contained in this notice, the name of the XFree86 Project 2405b261ecSmrg *shall not be used in advertising or otherwise to promote the sale, use 2505b261ecSmrg *or other dealings in this Software without prior written authorization 2605b261ecSmrg *from the XFree86 Project. 2705b261ecSmrg * 2805b261ecSmrg * Authors: Dakshinamurthy Karra 2905b261ecSmrg * Suhaib M Siddiqi 3005b261ecSmrg * Peter Busch 3105b261ecSmrg * Harold L Hunt II 3205b261ecSmrg * MATSUZAKI Kensuke 3305b261ecSmrg */ 3405b261ecSmrg 3505b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H 3605b261ecSmrg#include <xwin-config.h> 3705b261ecSmrg#endif 3805b261ecSmrg#include "win.h" 3905b261ecSmrg#include <commctrl.h> 4005b261ecSmrg#include "winprefs.h" 4105b261ecSmrg#include "winconfig.h" 4205b261ecSmrg#include "winmsg.h" 4305b261ecSmrg#include "inputstr.h" 4405b261ecSmrg 4505b261ecSmrg#ifdef XKB 4605b261ecSmrgextern BOOL winCheckKeyPressed(WPARAM wParam, LPARAM lParam); 4705b261ecSmrg#endif 4805b261ecSmrgextern void winFixShiftKeys (int iScanCode); 4905b261ecSmrg 5005b261ecSmrg 5105b261ecSmrg/* 5205b261ecSmrg * Global variables 5305b261ecSmrg */ 5405b261ecSmrg 5505b261ecSmrgBool g_fCursor = TRUE; 5605b261ecSmrgBool g_fButton[3] = { FALSE, FALSE, FALSE }; 5705b261ecSmrg 5805b261ecSmrg 5905b261ecSmrg/* 6005b261ecSmrg * References to external symbols 6105b261ecSmrg */ 6205b261ecSmrg 6305b261ecSmrgextern Bool g_fClipboard; 6405b261ecSmrgextern HWND g_hDlgDepthChange; 6505b261ecSmrgextern Bool g_fKeyboardHookLL; 6605b261ecSmrgextern HWND g_hwndKeyboardFocus; 6705b261ecSmrgextern Bool g_fSoftwareCursor; 6805b261ecSmrgextern DWORD g_dwCurrentThreadID; 6905b261ecSmrg 7005b261ecSmrg 7105b261ecSmrg/* 7205b261ecSmrg * Called by winWakeupHandler 7305b261ecSmrg * Processes current Windows message 7405b261ecSmrg */ 7505b261ecSmrg 7605b261ecSmrgLRESULT CALLBACK 7705b261ecSmrgwinWindowProc (HWND hwnd, UINT message, 7805b261ecSmrg WPARAM wParam, LPARAM lParam) 7905b261ecSmrg{ 8005b261ecSmrg static winPrivScreenPtr s_pScreenPriv = NULL; 8105b261ecSmrg static winScreenInfo *s_pScreenInfo = NULL; 8205b261ecSmrg static ScreenPtr s_pScreen = NULL; 8305b261ecSmrg static HWND s_hwndLastPrivates = NULL; 8405b261ecSmrg static HINSTANCE s_hInstance; 8505b261ecSmrg static Bool s_fTracking = FALSE; 8605b261ecSmrg static unsigned long s_ulServerGeneration = 0; 8705b261ecSmrg static UINT s_uTaskbarRestart = 0; 8805b261ecSmrg int iScanCode; 8905b261ecSmrg int i; 9005b261ecSmrg 9105b261ecSmrg#if CYGDEBUG 9205b261ecSmrg winDebugWin32Message("winWindowProc", hwnd, message, wParam, lParam); 9305b261ecSmrg#endif 9405b261ecSmrg 9505b261ecSmrg /* Watch for server regeneration */ 9605b261ecSmrg if (g_ulServerGeneration != s_ulServerGeneration) 9705b261ecSmrg { 9805b261ecSmrg /* Store new server generation */ 9905b261ecSmrg s_ulServerGeneration = g_ulServerGeneration; 10005b261ecSmrg } 10105b261ecSmrg 10205b261ecSmrg /* Only retrieve new privates pointers if window handle is null or changed */ 10305b261ecSmrg if ((s_pScreenPriv == NULL || hwnd != s_hwndLastPrivates) 10405b261ecSmrg && (s_pScreenPriv = GetProp (hwnd, WIN_SCR_PROP)) != NULL) 10505b261ecSmrg { 10605b261ecSmrg#if CYGDEBUG 10705b261ecSmrg winDebug ("winWindowProc - Setting privates handle\n"); 10805b261ecSmrg#endif 10905b261ecSmrg s_pScreenInfo = s_pScreenPriv->pScreenInfo; 11005b261ecSmrg s_pScreen = s_pScreenInfo->pScreen; 11105b261ecSmrg s_hwndLastPrivates = hwnd; 11205b261ecSmrg } 11305b261ecSmrg else if (s_pScreenPriv == NULL) 11405b261ecSmrg { 11505b261ecSmrg /* For safety, handle case that should never happen */ 11605b261ecSmrg s_pScreenInfo = NULL; 11705b261ecSmrg s_pScreen = NULL; 11805b261ecSmrg s_hwndLastPrivates = NULL; 11905b261ecSmrg } 12005b261ecSmrg 12105b261ecSmrg /* Branch on message type */ 12205b261ecSmrg switch (message) 12305b261ecSmrg { 12405b261ecSmrg case WM_TRAYICON: 12505b261ecSmrg return winHandleIconMessage (hwnd, message, wParam, lParam, 12605b261ecSmrg s_pScreenPriv); 12705b261ecSmrg 12805b261ecSmrg case WM_CREATE: 12905b261ecSmrg#if CYGDEBUG 13005b261ecSmrg winDebug ("winWindowProc - WM_CREATE\n"); 13105b261ecSmrg#endif 13205b261ecSmrg 13305b261ecSmrg /* 13405b261ecSmrg * Add a property to our display window that references 13505b261ecSmrg * this screens' privates. 13605b261ecSmrg * 13705b261ecSmrg * This allows the window procedure to refer to the 13805b261ecSmrg * appropriate window DC and shadow DC for the window that 13905b261ecSmrg * it is processing. We use this to repaint exposed 14005b261ecSmrg * areas of our display window. 14105b261ecSmrg */ 14205b261ecSmrg s_pScreenPriv = ((LPCREATESTRUCT) lParam)->lpCreateParams; 14305b261ecSmrg s_hInstance = ((LPCREATESTRUCT) lParam)->hInstance; 14405b261ecSmrg s_pScreenInfo = s_pScreenPriv->pScreenInfo; 14505b261ecSmrg s_pScreen = s_pScreenInfo->pScreen; 14605b261ecSmrg s_hwndLastPrivates = hwnd; 14705b261ecSmrg s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); 14805b261ecSmrg SetProp (hwnd, WIN_SCR_PROP, s_pScreenPriv); 14905b261ecSmrg 15005b261ecSmrg /* Setup tray icon */ 15105b261ecSmrg if (!s_pScreenInfo->fNoTrayIcon) 15205b261ecSmrg { 15305b261ecSmrg /* 15405b261ecSmrg * NOTE: The WM_CREATE message is processed before CreateWindowEx 15505b261ecSmrg * returns, so s_pScreenPriv->hwndScreen is invalid at this point. 15605b261ecSmrg * We go ahead and copy our hwnd parameter over top of the screen 15705b261ecSmrg * privates hwndScreen so that we have a valid value for 15805b261ecSmrg * that member. Otherwise, the tray icon will disappear 15905b261ecSmrg * the first time you move the mouse over top of it. 16005b261ecSmrg */ 16105b261ecSmrg 16205b261ecSmrg s_pScreenPriv->hwndScreen = hwnd; 16305b261ecSmrg 16405b261ecSmrg winInitNotifyIcon (s_pScreenPriv); 16505b261ecSmrg } 16605b261ecSmrg return 0; 16705b261ecSmrg 16805b261ecSmrg case WM_DISPLAYCHANGE: 16905b261ecSmrg /* We cannot handle a display mode change during initialization */ 17005b261ecSmrg if (s_pScreenInfo == NULL) 17105b261ecSmrg FatalError ("winWindowProc - WM_DISPLAYCHANGE - The display " 17205b261ecSmrg "mode changed while we were intializing. This is " 17305b261ecSmrg "very bad and unexpected. Exiting.\n"); 17405b261ecSmrg 17505b261ecSmrg /* 17605b261ecSmrg * We do not care about display changes with 17705b261ecSmrg * fullscreen DirectDraw engines, because those engines set 17805b261ecSmrg * their own mode when they become active. 17905b261ecSmrg */ 18005b261ecSmrg if (s_pScreenInfo->fFullScreen 18105b261ecSmrg && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD 18205b261ecSmrg || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL 18305b261ecSmrg#ifdef XWIN_PRIMARYFB 18405b261ecSmrg || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD 18505b261ecSmrg#endif 18605b261ecSmrg )) 18705b261ecSmrg { 18805b261ecSmrg /* 18905b261ecSmrg * Store the new display dimensions and depth. 19005b261ecSmrg * We do this here for future compatibility in case we 19105b261ecSmrg * ever allow switching from fullscreen to windowed mode. 19205b261ecSmrg */ 19305b261ecSmrg s_pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN); 19405b261ecSmrg s_pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN); 19505b261ecSmrg s_pScreenPriv->dwLastWindowsBitsPixel 19605b261ecSmrg = GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL); 19705b261ecSmrg break; 19805b261ecSmrg } 19905b261ecSmrg 20005b261ecSmrg ErrorF ("winWindowProc - WM_DISPLAYCHANGE - orig bpp: %d, last bpp: %d, " 20105b261ecSmrg "new bpp: %d\n", 20205b261ecSmrg (int) s_pScreenInfo->dwBPP, 20305b261ecSmrg (int) s_pScreenPriv->dwLastWindowsBitsPixel, 20405b261ecSmrg wParam); 20505b261ecSmrg 20605b261ecSmrg ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new width: %d " 20705b261ecSmrg "new height: %d\n", 20805b261ecSmrg LOWORD (lParam), HIWORD (lParam)); 20905b261ecSmrg 21005b261ecSmrg /* 21105b261ecSmrg * TrueColor --> TrueColor depth changes are disruptive for: 21205b261ecSmrg * Windowed: 21305b261ecSmrg * Shadow DirectDraw 21405b261ecSmrg * Shadow DirectDraw Non-Locking 21505b261ecSmrg * Primary DirectDraw 21605b261ecSmrg * 21705b261ecSmrg * TrueColor --> TrueColor depth changes are non-optimal for: 21805b261ecSmrg * Windowed: 21905b261ecSmrg * Shadow GDI 22005b261ecSmrg * 22105b261ecSmrg * FullScreen: 22205b261ecSmrg * Shadow GDI 22305b261ecSmrg * 22405b261ecSmrg * TrueColor --> PseudoColor or vice versa are disruptive for: 22505b261ecSmrg * Windowed: 22605b261ecSmrg * Shadow DirectDraw 22705b261ecSmrg * Shadow DirectDraw Non-Locking 22805b261ecSmrg * Primary DirectDraw 22905b261ecSmrg * Shadow GDI 23005b261ecSmrg */ 23105b261ecSmrg 23205b261ecSmrg /* 23305b261ecSmrg * Check for a disruptive change in depth. 23405b261ecSmrg * We can only display a message for a disruptive depth change, 23505b261ecSmrg * we cannot do anything to correct the situation. 23605b261ecSmrg */ 23705b261ecSmrg if ((s_pScreenInfo->dwBPP != wParam) 23805b261ecSmrg && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD 23905b261ecSmrg || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL 24005b261ecSmrg#ifdef XWIN_PRIMARYFB 24105b261ecSmrg || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD 24205b261ecSmrg#endif 24305b261ecSmrg )) 24405b261ecSmrg { 24505b261ecSmrg /* Cannot display the visual until the depth is restored */ 24605b261ecSmrg ErrorF ("winWindowProc - Disruptive change in depth\n"); 24705b261ecSmrg 24805b261ecSmrg /* Display Exit dialog */ 24905b261ecSmrg winDisplayDepthChangeDialog (s_pScreenPriv); 25005b261ecSmrg 25105b261ecSmrg /* Flag that we have an invalid screen depth */ 25205b261ecSmrg s_pScreenPriv->fBadDepth = TRUE; 25305b261ecSmrg 25405b261ecSmrg /* Minimize the display window */ 25505b261ecSmrg ShowWindow (hwnd, SW_MINIMIZE); 25605b261ecSmrg } 25705b261ecSmrg else 25805b261ecSmrg { 25905b261ecSmrg /* Flag that we have a valid screen depth */ 26005b261ecSmrg s_pScreenPriv->fBadDepth = FALSE; 26105b261ecSmrg } 26205b261ecSmrg 26305b261ecSmrg /* 26405b261ecSmrg * Check for a change in display dimensions. 26505b261ecSmrg * We can simply recreate the same-sized primary surface when 26605b261ecSmrg * the display dimensions change. 26705b261ecSmrg */ 26805b261ecSmrg if (s_pScreenPriv->dwLastWindowsWidth != LOWORD (lParam) 26905b261ecSmrg || s_pScreenPriv->dwLastWindowsHeight != HIWORD (lParam)) 27005b261ecSmrg { 27105b261ecSmrg /* 27205b261ecSmrg * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface 27305b261ecSmrg * and CreatePrimarySurface function pointers to point 27405b261ecSmrg * to the no operation function, NoopDDA. This allows us 27505b261ecSmrg * to blindly call these functions, even if they are not 27605b261ecSmrg * relevant to the current engine (e.g., Shadow GDI). 27705b261ecSmrg */ 27805b261ecSmrg 27905b261ecSmrg#if CYGDEBUG 28005b261ecSmrg winDebug ("winWindowProc - WM_DISPLAYCHANGE - Dimensions changed\n"); 28105b261ecSmrg#endif 28205b261ecSmrg 28305b261ecSmrg /* Release the old primary surface */ 28405b261ecSmrg (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen); 28505b261ecSmrg 28605b261ecSmrg#if CYGDEBUG 28705b261ecSmrg winDebug ("winWindowProc - WM_DISPLAYCHANGE - Released " 28805b261ecSmrg "primary surface\n"); 28905b261ecSmrg#endif 29005b261ecSmrg 29105b261ecSmrg /* Create the new primary surface */ 29205b261ecSmrg (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen); 29305b261ecSmrg 29405b261ecSmrg#if CYGDEBUG 29505b261ecSmrg winDebug ("winWindowProc - WM_DISPLAYCHANGE - Recreated " 29605b261ecSmrg "primary surface\n"); 29705b261ecSmrg#endif 29805b261ecSmrg 29905b261ecSmrg#if 0 30005b261ecSmrg /* Multi-Window mode uses RandR for resizes */ 30105b261ecSmrg if (s_pScreenInfo->fMultiWindow) 30205b261ecSmrg { 30305b261ecSmrg RRSetScreenConfig (); 30405b261ecSmrg } 30505b261ecSmrg#endif 30605b261ecSmrg } 30705b261ecSmrg else 30805b261ecSmrg { 30905b261ecSmrg#if CYGDEBUG 31005b261ecSmrg winDebug ("winWindowProc - WM_DISPLAYCHANGE - Dimensions did not " 31105b261ecSmrg "change\n"); 31205b261ecSmrg#endif 31305b261ecSmrg } 31405b261ecSmrg 31505b261ecSmrg /* Store the new display dimensions and depth */ 31605b261ecSmrg if (s_pScreenInfo->fMultipleMonitors) 31705b261ecSmrg { 31805b261ecSmrg s_pScreenPriv->dwLastWindowsWidth 31905b261ecSmrg = GetSystemMetrics (SM_CXVIRTUALSCREEN); 32005b261ecSmrg s_pScreenPriv->dwLastWindowsHeight 32105b261ecSmrg = GetSystemMetrics (SM_CYVIRTUALSCREEN); 32205b261ecSmrg } 32305b261ecSmrg else 32405b261ecSmrg { 32505b261ecSmrg s_pScreenPriv->dwLastWindowsWidth 32605b261ecSmrg = GetSystemMetrics (SM_CXSCREEN); 32705b261ecSmrg s_pScreenPriv->dwLastWindowsHeight 32805b261ecSmrg = GetSystemMetrics (SM_CYSCREEN); 32905b261ecSmrg } 33005b261ecSmrg s_pScreenPriv->dwLastWindowsBitsPixel 33105b261ecSmrg = GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL); 33205b261ecSmrg break; 33305b261ecSmrg 33405b261ecSmrg case WM_SIZE: 33505b261ecSmrg { 33605b261ecSmrg SCROLLINFO si; 33705b261ecSmrg RECT rcWindow; 33805b261ecSmrg int iWidth, iHeight; 33905b261ecSmrg 34005b261ecSmrg#if CYGDEBUG 34105b261ecSmrg winDebug ("winWindowProc - WM_SIZE\n"); 34205b261ecSmrg#endif 34305b261ecSmrg 34405b261ecSmrg /* Break if we do not use scrollbars */ 34505b261ecSmrg if (!s_pScreenInfo->fScrollbars 34605b261ecSmrg || !s_pScreenInfo->fDecoration 34705b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM 34805b261ecSmrg || s_pScreenInfo->fMWExtWM 34905b261ecSmrg#endif 35005b261ecSmrg || s_pScreenInfo->fRootless 35105b261ecSmrg#ifdef XWIN_MULTIWINDOW 35205b261ecSmrg || s_pScreenInfo->fMultiWindow 35305b261ecSmrg#endif 35405b261ecSmrg || s_pScreenInfo->fFullScreen) 35505b261ecSmrg break; 35605b261ecSmrg 35705b261ecSmrg /* No need to resize if we get minimized */ 35805b261ecSmrg if (wParam == SIZE_MINIMIZED) 35905b261ecSmrg return 0; 36005b261ecSmrg 36105b261ecSmrg /* 36205b261ecSmrg * Get the size of the whole window, including client area, 36305b261ecSmrg * scrollbars, and non-client area decorations (caption, borders). 36405b261ecSmrg * We do this because we need to check if the client area 36505b261ecSmrg * without scrollbars is large enough to display the whole visual. 36605b261ecSmrg * The new client area size passed by lParam already subtracts 36705b261ecSmrg * the size of the scrollbars if they are currently displayed. 36805b261ecSmrg * So checking is LOWORD(lParam) == visual_width and 36905b261ecSmrg * HIWORD(lParam) == visual_height will never tell us to hide 37005b261ecSmrg * the scrollbars because the client area would always be too small. 37105b261ecSmrg * GetClientRect returns the same sizes given by lParam, so we 37205b261ecSmrg * cannot use GetClientRect either. 37305b261ecSmrg */ 37405b261ecSmrg GetWindowRect (hwnd, &rcWindow); 37505b261ecSmrg iWidth = rcWindow.right - rcWindow.left; 37605b261ecSmrg iHeight = rcWindow.bottom - rcWindow.top; 37705b261ecSmrg 37805b261ecSmrg ErrorF ("winWindowProc - WM_SIZE - window w: %d h: %d, " 37905b261ecSmrg "new client area w: %d h: %d\n", 38005b261ecSmrg iWidth, iHeight, LOWORD (lParam), HIWORD (lParam)); 38105b261ecSmrg 38205b261ecSmrg /* Subtract the frame size from the window size. */ 38305b261ecSmrg iWidth -= 2 * GetSystemMetrics (SM_CXSIZEFRAME); 38405b261ecSmrg iHeight -= (2 * GetSystemMetrics (SM_CYSIZEFRAME) 38505b261ecSmrg + GetSystemMetrics (SM_CYCAPTION)); 38605b261ecSmrg 38705b261ecSmrg /* 38805b261ecSmrg * Update scrollbar page sizes. 38905b261ecSmrg * NOTE: If page size == range, then the scrollbar is 39005b261ecSmrg * automatically hidden. 39105b261ecSmrg */ 39205b261ecSmrg 39305b261ecSmrg /* Is the naked client area large enough to show the whole visual? */ 39405b261ecSmrg if (iWidth < s_pScreenInfo->dwWidth 39505b261ecSmrg || iHeight < s_pScreenInfo->dwHeight) 39605b261ecSmrg { 39705b261ecSmrg /* Client area too small to display visual, use scrollbars */ 39805b261ecSmrg iWidth -= GetSystemMetrics (SM_CXVSCROLL); 39905b261ecSmrg iHeight -= GetSystemMetrics (SM_CYHSCROLL); 40005b261ecSmrg } 40105b261ecSmrg 40205b261ecSmrg /* Set the horizontal scrollbar page size */ 40305b261ecSmrg si.cbSize = sizeof (si); 40405b261ecSmrg si.fMask = SIF_PAGE | SIF_RANGE; 40505b261ecSmrg si.nMin = 0; 40605b261ecSmrg si.nMax = s_pScreenInfo->dwWidth - 1; 40705b261ecSmrg si.nPage = iWidth; 40805b261ecSmrg SetScrollInfo (hwnd, SB_HORZ, &si, TRUE); 40905b261ecSmrg 41005b261ecSmrg /* Set the vertical scrollbar page size */ 41105b261ecSmrg si.cbSize = sizeof (si); 41205b261ecSmrg si.fMask = SIF_PAGE | SIF_RANGE; 41305b261ecSmrg si.nMin = 0; 41405b261ecSmrg si.nMax = s_pScreenInfo->dwHeight - 1; 41505b261ecSmrg si.nPage = iHeight; 41605b261ecSmrg SetScrollInfo (hwnd, SB_VERT, &si, TRUE); 41705b261ecSmrg 41805b261ecSmrg /* 41905b261ecSmrg * NOTE: Scrollbars may have moved if they were at the 42005b261ecSmrg * far right/bottom, so we query their current position. 42105b261ecSmrg */ 42205b261ecSmrg 42305b261ecSmrg /* Get the horizontal scrollbar position and set the offset */ 42405b261ecSmrg si.cbSize = sizeof (si); 42505b261ecSmrg si.fMask = SIF_POS; 42605b261ecSmrg GetScrollInfo (hwnd, SB_HORZ, &si); 42705b261ecSmrg s_pScreenInfo->dwXOffset = -si.nPos; 42805b261ecSmrg 42905b261ecSmrg /* Get the vertical scrollbar position and set the offset */ 43005b261ecSmrg si.cbSize = sizeof (si); 43105b261ecSmrg si.fMask = SIF_POS; 43205b261ecSmrg GetScrollInfo (hwnd, SB_VERT, &si); 43305b261ecSmrg s_pScreenInfo->dwYOffset = -si.nPos; 43405b261ecSmrg } 43505b261ecSmrg return 0; 43605b261ecSmrg 43705b261ecSmrg case WM_VSCROLL: 43805b261ecSmrg { 43905b261ecSmrg SCROLLINFO si; 44005b261ecSmrg int iVertPos; 44105b261ecSmrg 44205b261ecSmrg#if CYGDEBUG 44305b261ecSmrg winDebug ("winWindowProc - WM_VSCROLL\n"); 44405b261ecSmrg#endif 44505b261ecSmrg 44605b261ecSmrg /* Get vertical scroll bar info */ 44705b261ecSmrg si.cbSize = sizeof (si); 44805b261ecSmrg si.fMask = SIF_ALL; 44905b261ecSmrg GetScrollInfo (hwnd, SB_VERT, &si); 45005b261ecSmrg 45105b261ecSmrg /* Save the vertical position for comparison later */ 45205b261ecSmrg iVertPos = si.nPos; 45305b261ecSmrg 45405b261ecSmrg /* 45505b261ecSmrg * Don't forget: 45605b261ecSmrg * moving the scrollbar to the DOWN, scroll the content UP 45705b261ecSmrg */ 45805b261ecSmrg switch (LOWORD(wParam)) 45905b261ecSmrg { 46005b261ecSmrg case SB_TOP: 46105b261ecSmrg si.nPos = si.nMin; 46205b261ecSmrg break; 46305b261ecSmrg 46405b261ecSmrg case SB_BOTTOM: 46505b261ecSmrg si.nPos = si.nMax - si.nPage + 1; 46605b261ecSmrg break; 46705b261ecSmrg 46805b261ecSmrg case SB_LINEUP: 46905b261ecSmrg si.nPos -= 1; 47005b261ecSmrg break; 47105b261ecSmrg 47205b261ecSmrg case SB_LINEDOWN: 47305b261ecSmrg si.nPos += 1; 47405b261ecSmrg break; 47505b261ecSmrg 47605b261ecSmrg case SB_PAGEUP: 47705b261ecSmrg si.nPos -= si.nPage; 47805b261ecSmrg break; 47905b261ecSmrg 48005b261ecSmrg case SB_PAGEDOWN: 48105b261ecSmrg si.nPos += si.nPage; 48205b261ecSmrg break; 48305b261ecSmrg 48405b261ecSmrg case SB_THUMBTRACK: 48505b261ecSmrg si.nPos = si.nTrackPos; 48605b261ecSmrg break; 48705b261ecSmrg 48805b261ecSmrg default: 48905b261ecSmrg break; 49005b261ecSmrg } 49105b261ecSmrg 49205b261ecSmrg /* 49305b261ecSmrg * We retrieve the position after setting it, 49405b261ecSmrg * because Windows may adjust it. 49505b261ecSmrg */ 49605b261ecSmrg si.fMask = SIF_POS; 49705b261ecSmrg SetScrollInfo (hwnd, SB_VERT, &si, TRUE); 49805b261ecSmrg GetScrollInfo (hwnd, SB_VERT, &si); 49905b261ecSmrg 50005b261ecSmrg /* Scroll the window if the position has changed */ 50105b261ecSmrg if (si.nPos != iVertPos) 50205b261ecSmrg { 50305b261ecSmrg /* Save the new offset for bit block transfers, etc. */ 50405b261ecSmrg s_pScreenInfo->dwYOffset = -si.nPos; 50505b261ecSmrg 50605b261ecSmrg /* Change displayed region in the window */ 50705b261ecSmrg ScrollWindowEx (hwnd, 50805b261ecSmrg 0, 50905b261ecSmrg iVertPos - si.nPos, 51005b261ecSmrg NULL, 51105b261ecSmrg NULL, 51205b261ecSmrg NULL, 51305b261ecSmrg NULL, 51405b261ecSmrg SW_INVALIDATE); 51505b261ecSmrg 51605b261ecSmrg /* Redraw the window contents */ 51705b261ecSmrg UpdateWindow (hwnd); 51805b261ecSmrg } 51905b261ecSmrg } 52005b261ecSmrg return 0; 52105b261ecSmrg 52205b261ecSmrg case WM_HSCROLL: 52305b261ecSmrg { 52405b261ecSmrg SCROLLINFO si; 52505b261ecSmrg int iHorzPos; 52605b261ecSmrg 52705b261ecSmrg#if CYGDEBUG 52805b261ecSmrg winDebug ("winWindowProc - WM_HSCROLL\n"); 52905b261ecSmrg#endif 53005b261ecSmrg 53105b261ecSmrg /* Get horizontal scroll bar info */ 53205b261ecSmrg si.cbSize = sizeof (si); 53305b261ecSmrg si.fMask = SIF_ALL; 53405b261ecSmrg GetScrollInfo (hwnd, SB_HORZ, &si); 53505b261ecSmrg 53605b261ecSmrg /* Save the horizontal position for comparison later */ 53705b261ecSmrg iHorzPos = si.nPos; 53805b261ecSmrg 53905b261ecSmrg /* 54005b261ecSmrg * Don't forget: 54105b261ecSmrg * moving the scrollbar to the RIGHT, scroll the content LEFT 54205b261ecSmrg */ 54305b261ecSmrg switch (LOWORD(wParam)) 54405b261ecSmrg { 54505b261ecSmrg case SB_LEFT: 54605b261ecSmrg si.nPos = si.nMin; 54705b261ecSmrg break; 54805b261ecSmrg 54905b261ecSmrg case SB_RIGHT: 55005b261ecSmrg si.nPos = si.nMax - si.nPage + 1; 55105b261ecSmrg break; 55205b261ecSmrg 55305b261ecSmrg case SB_LINELEFT: 55405b261ecSmrg si.nPos -= 1; 55505b261ecSmrg break; 55605b261ecSmrg 55705b261ecSmrg case SB_LINERIGHT: 55805b261ecSmrg si.nPos += 1; 55905b261ecSmrg break; 56005b261ecSmrg 56105b261ecSmrg case SB_PAGELEFT: 56205b261ecSmrg si.nPos -= si.nPage; 56305b261ecSmrg break; 56405b261ecSmrg 56505b261ecSmrg case SB_PAGERIGHT: 56605b261ecSmrg si.nPos += si.nPage; 56705b261ecSmrg break; 56805b261ecSmrg 56905b261ecSmrg case SB_THUMBTRACK: 57005b261ecSmrg si.nPos = si.nTrackPos; 57105b261ecSmrg break; 57205b261ecSmrg 57305b261ecSmrg default: 57405b261ecSmrg break; 57505b261ecSmrg } 57605b261ecSmrg 57705b261ecSmrg /* 57805b261ecSmrg * We retrieve the position after setting it, 57905b261ecSmrg * because Windows may adjust it. 58005b261ecSmrg */ 58105b261ecSmrg si.fMask = SIF_POS; 58205b261ecSmrg SetScrollInfo (hwnd, SB_HORZ, &si, TRUE); 58305b261ecSmrg GetScrollInfo (hwnd, SB_HORZ, &si); 58405b261ecSmrg 58505b261ecSmrg /* Scroll the window if the position has changed */ 58605b261ecSmrg if (si.nPos != iHorzPos) 58705b261ecSmrg { 58805b261ecSmrg /* Save the new offset for bit block transfers, etc. */ 58905b261ecSmrg s_pScreenInfo->dwXOffset = -si.nPos; 59005b261ecSmrg 59105b261ecSmrg /* Change displayed region in the window */ 59205b261ecSmrg ScrollWindowEx (hwnd, 59305b261ecSmrg iHorzPos - si.nPos, 59405b261ecSmrg 0, 59505b261ecSmrg NULL, 59605b261ecSmrg NULL, 59705b261ecSmrg NULL, 59805b261ecSmrg NULL, 59905b261ecSmrg SW_INVALIDATE); 60005b261ecSmrg 60105b261ecSmrg /* Redraw the window contents */ 60205b261ecSmrg UpdateWindow (hwnd); 60305b261ecSmrg } 60405b261ecSmrg } 60505b261ecSmrg return 0; 60605b261ecSmrg 60705b261ecSmrg case WM_GETMINMAXINFO: 60805b261ecSmrg { 60905b261ecSmrg MINMAXINFO *pMinMaxInfo = (MINMAXINFO *) lParam; 61005b261ecSmrg int iCaptionHeight; 61105b261ecSmrg int iBorderHeight, iBorderWidth; 61205b261ecSmrg 61305b261ecSmrg#if CYGDEBUG 61405b261ecSmrg winDebug ("winWindowProc - WM_GETMINMAXINFO - pScreenInfo: %08x\n", 61505b261ecSmrg s_pScreenInfo); 61605b261ecSmrg#endif 61705b261ecSmrg 61805b261ecSmrg /* Can't do anything without screen info */ 61905b261ecSmrg if (s_pScreenInfo == NULL 62005b261ecSmrg || !s_pScreenInfo->fScrollbars 62105b261ecSmrg || s_pScreenInfo->fFullScreen 62205b261ecSmrg || !s_pScreenInfo->fDecoration 62305b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM 62405b261ecSmrg || s_pScreenInfo->fMWExtWM 62505b261ecSmrg#endif 62605b261ecSmrg || s_pScreenInfo->fRootless 62705b261ecSmrg#ifdef XWIN_MULTIWINDOW 62805b261ecSmrg || s_pScreenInfo->fMultiWindow 62905b261ecSmrg#endif 63005b261ecSmrg ) 63105b261ecSmrg break; 63205b261ecSmrg 63305b261ecSmrg /* 63405b261ecSmrg * Here we can override the maximum tracking size, which 63505b261ecSmrg * is the largest size that can be assigned to our window 63605b261ecSmrg * via the sizing border. 63705b261ecSmrg */ 63805b261ecSmrg 63905b261ecSmrg /* 64005b261ecSmrg * FIXME: Do we only need to do this once, since our visual size 64105b261ecSmrg * does not change? Does Windows store this value statically 64205b261ecSmrg * once we have set it once? 64305b261ecSmrg */ 64405b261ecSmrg 64505b261ecSmrg /* Get the border and caption sizes */ 64605b261ecSmrg iCaptionHeight = GetSystemMetrics (SM_CYCAPTION); 64705b261ecSmrg iBorderWidth = 2 * GetSystemMetrics (SM_CXSIZEFRAME); 64805b261ecSmrg iBorderHeight = 2 * GetSystemMetrics (SM_CYSIZEFRAME); 64905b261ecSmrg 65005b261ecSmrg /* Allow the full visual to be displayed */ 65105b261ecSmrg pMinMaxInfo->ptMaxTrackSize.x 65205b261ecSmrg = s_pScreenInfo->dwWidth + iBorderWidth; 65305b261ecSmrg pMinMaxInfo->ptMaxTrackSize.y 65405b261ecSmrg = s_pScreenInfo->dwHeight + iBorderHeight + iCaptionHeight; 65505b261ecSmrg } 65605b261ecSmrg return 0; 65705b261ecSmrg 65805b261ecSmrg case WM_ERASEBKGND: 65905b261ecSmrg#if CYGDEBUG 66005b261ecSmrg winDebug ("winWindowProc - WM_ERASEBKGND\n"); 66105b261ecSmrg#endif 66205b261ecSmrg /* 66305b261ecSmrg * Pretend that we did erase the background but we don't care, 66405b261ecSmrg * the application uses the full window estate. This avoids some 66505b261ecSmrg * flickering when resizing. 66605b261ecSmrg */ 66705b261ecSmrg return TRUE; 66805b261ecSmrg 66905b261ecSmrg case WM_PAINT: 67005b261ecSmrg#if CYGDEBUG 67105b261ecSmrg winDebug ("winWindowProc - WM_PAINT\n"); 67205b261ecSmrg#endif 67305b261ecSmrg /* Only paint if we have privates and the server is enabled */ 67405b261ecSmrg if (s_pScreenPriv == NULL 67505b261ecSmrg || !s_pScreenPriv->fEnabled 67605b261ecSmrg || (s_pScreenInfo->fFullScreen && !s_pScreenPriv->fActive) 67705b261ecSmrg || s_pScreenPriv->fBadDepth) 67805b261ecSmrg { 67905b261ecSmrg /* We don't want to paint */ 68005b261ecSmrg break; 68105b261ecSmrg } 68205b261ecSmrg 68305b261ecSmrg /* Break out here if we don't have a valid paint routine */ 68405b261ecSmrg if (s_pScreenPriv->pwinBltExposedRegions == NULL) 68505b261ecSmrg break; 68605b261ecSmrg 68705b261ecSmrg /* Call the engine dependent repainter */ 68805b261ecSmrg (*s_pScreenPriv->pwinBltExposedRegions) (s_pScreen); 68905b261ecSmrg return 0; 69005b261ecSmrg 69105b261ecSmrg case WM_PALETTECHANGED: 69205b261ecSmrg { 69305b261ecSmrg#if CYGDEBUG 69405b261ecSmrg winDebug ("winWindowProc - WM_PALETTECHANGED\n"); 69505b261ecSmrg#endif 69605b261ecSmrg /* 69705b261ecSmrg * Don't process if we don't have privates or a colormap, 69805b261ecSmrg * or if we have an invalid depth. 69905b261ecSmrg */ 70005b261ecSmrg if (s_pScreenPriv == NULL 70105b261ecSmrg || s_pScreenPriv->pcmapInstalled == NULL 70205b261ecSmrg || s_pScreenPriv->fBadDepth) 70305b261ecSmrg break; 70405b261ecSmrg 70505b261ecSmrg /* Return if we caused the palette to change */ 70605b261ecSmrg if ((HWND) wParam == hwnd) 70705b261ecSmrg { 70805b261ecSmrg /* Redraw the screen */ 70905b261ecSmrg (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen); 71005b261ecSmrg return 0; 71105b261ecSmrg } 71205b261ecSmrg 71305b261ecSmrg /* Reinstall the windows palette */ 71405b261ecSmrg (*s_pScreenPriv->pwinRealizeInstalledPalette) (s_pScreen); 71505b261ecSmrg 71605b261ecSmrg /* Redraw the screen */ 71705b261ecSmrg (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen); 71805b261ecSmrg return 0; 71905b261ecSmrg } 72005b261ecSmrg 72105b261ecSmrg case WM_MOUSEMOVE: 72205b261ecSmrg /* We can't do anything without privates */ 72305b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 72405b261ecSmrg break; 72505b261ecSmrg 72605b261ecSmrg /* Has the mouse pointer crossed screens? */ 72705b261ecSmrg if (s_pScreen != miPointerGetScreen(inputInfo.pointer)) 72805b261ecSmrg miPointerSetScreen (inputInfo.pointer, s_pScreenInfo->dwScreen, 72905b261ecSmrg GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset, 73005b261ecSmrg GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset); 73105b261ecSmrg 73205b261ecSmrg /* Are we tracking yet? */ 73305b261ecSmrg if (!s_fTracking) 73405b261ecSmrg { 73505b261ecSmrg TRACKMOUSEEVENT tme; 73605b261ecSmrg 73705b261ecSmrg /* Setup data structure */ 73805b261ecSmrg ZeroMemory (&tme, sizeof (tme)); 73905b261ecSmrg tme.cbSize = sizeof (tme); 74005b261ecSmrg tme.dwFlags = TME_LEAVE; 74105b261ecSmrg tme.hwndTrack = hwnd; 74205b261ecSmrg 74305b261ecSmrg /* Call the tracking function */ 74405b261ecSmrg if (!(*g_fpTrackMouseEvent) (&tme)) 74505b261ecSmrg ErrorF ("winWindowProc - _TrackMouseEvent failed\n"); 74605b261ecSmrg 74705b261ecSmrg /* Flag that we are tracking now */ 74805b261ecSmrg s_fTracking = TRUE; 74905b261ecSmrg } 75005b261ecSmrg 75105b261ecSmrg /* Hide or show the Windows mouse cursor */ 75205b261ecSmrg if (g_fSoftwareCursor && g_fCursor && (s_pScreenPriv->fActive || s_pScreenInfo->fLessPointer)) 75305b261ecSmrg { 75405b261ecSmrg /* Hide Windows cursor */ 75505b261ecSmrg g_fCursor = FALSE; 75605b261ecSmrg ShowCursor (FALSE); 75705b261ecSmrg } 75805b261ecSmrg else if (g_fSoftwareCursor && !g_fCursor && !s_pScreenPriv->fActive 75905b261ecSmrg && !s_pScreenInfo->fLessPointer) 76005b261ecSmrg { 76105b261ecSmrg /* Show Windows cursor */ 76205b261ecSmrg g_fCursor = TRUE; 76305b261ecSmrg ShowCursor (TRUE); 76405b261ecSmrg } 76505b261ecSmrg 76605b261ecSmrg /* Deliver absolute cursor position to X Server */ 76705b261ecSmrg miPointerAbsoluteCursor (GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset, 76805b261ecSmrg GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset, 76905b261ecSmrg g_c32LastInputEventTime = GetTickCount ()); 77005b261ecSmrg return 0; 77105b261ecSmrg 77205b261ecSmrg case WM_NCMOUSEMOVE: 77305b261ecSmrg /* 77405b261ecSmrg * We break instead of returning 0 since we need to call 77505b261ecSmrg * DefWindowProc to get the mouse cursor changes 77605b261ecSmrg * and min/max/close button highlighting in Windows XP. 77705b261ecSmrg * The Platform SDK says that you should return 0 if you 77805b261ecSmrg * process this message, but it fails to mention that you 77905b261ecSmrg * will give up any default functionality if you do return 0. 78005b261ecSmrg */ 78105b261ecSmrg 78205b261ecSmrg /* We can't do anything without privates */ 78305b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 78405b261ecSmrg break; 78505b261ecSmrg 78605b261ecSmrg /* Non-client mouse movement, show Windows cursor */ 78705b261ecSmrg if (g_fSoftwareCursor && !g_fCursor) 78805b261ecSmrg { 78905b261ecSmrg g_fCursor = TRUE; 79005b261ecSmrg ShowCursor (TRUE); 79105b261ecSmrg } 79205b261ecSmrg break; 79305b261ecSmrg 79405b261ecSmrg case WM_MOUSELEAVE: 79505b261ecSmrg /* Mouse has left our client area */ 79605b261ecSmrg 79705b261ecSmrg /* Flag that we are no longer tracking */ 79805b261ecSmrg s_fTracking = FALSE; 79905b261ecSmrg 80005b261ecSmrg /* Show the mouse cursor, if necessary */ 80105b261ecSmrg if (g_fSoftwareCursor && !g_fCursor) 80205b261ecSmrg { 80305b261ecSmrg g_fCursor = TRUE; 80405b261ecSmrg ShowCursor (TRUE); 80505b261ecSmrg } 80605b261ecSmrg return 0; 80705b261ecSmrg 80805b261ecSmrg case WM_LBUTTONDBLCLK: 80905b261ecSmrg case WM_LBUTTONDOWN: 81005b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 81105b261ecSmrg break; 81205b261ecSmrg if (s_pScreenInfo->fRootless 81305b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM 81405b261ecSmrg || s_pScreenInfo->fMWExtWM 81505b261ecSmrg#endif 81605b261ecSmrg ) 81705b261ecSmrg SetCapture (hwnd); 81805b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam); 81905b261ecSmrg 82005b261ecSmrg case WM_LBUTTONUP: 82105b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 82205b261ecSmrg break; 82305b261ecSmrg if (s_pScreenInfo->fRootless 82405b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM 82505b261ecSmrg || s_pScreenInfo->fMWExtWM 82605b261ecSmrg#endif 82705b261ecSmrg ) 82805b261ecSmrg ReleaseCapture (); 82905b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam); 83005b261ecSmrg 83105b261ecSmrg case WM_MBUTTONDBLCLK: 83205b261ecSmrg case WM_MBUTTONDOWN: 83305b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 83405b261ecSmrg break; 83505b261ecSmrg if (s_pScreenInfo->fRootless 83605b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM 83705b261ecSmrg || s_pScreenInfo->fMWExtWM 83805b261ecSmrg#endif 83905b261ecSmrg ) 84005b261ecSmrg SetCapture (hwnd); 84105b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam); 84205b261ecSmrg 84305b261ecSmrg case WM_MBUTTONUP: 84405b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 84505b261ecSmrg break; 84605b261ecSmrg if (s_pScreenInfo->fRootless 84705b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM 84805b261ecSmrg || s_pScreenInfo->fMWExtWM 84905b261ecSmrg#endif 85005b261ecSmrg ) 85105b261ecSmrg ReleaseCapture (); 85205b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam); 85305b261ecSmrg 85405b261ecSmrg case WM_RBUTTONDBLCLK: 85505b261ecSmrg case WM_RBUTTONDOWN: 85605b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 85705b261ecSmrg break; 85805b261ecSmrg if (s_pScreenInfo->fRootless 85905b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM 86005b261ecSmrg || s_pScreenInfo->fMWExtWM 86105b261ecSmrg#endif 86205b261ecSmrg ) 86305b261ecSmrg SetCapture (hwnd); 86405b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam); 86505b261ecSmrg 86605b261ecSmrg case WM_RBUTTONUP: 86705b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 86805b261ecSmrg break; 86905b261ecSmrg if (s_pScreenInfo->fRootless 87005b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM 87105b261ecSmrg || s_pScreenInfo->fMWExtWM 87205b261ecSmrg#endif 87305b261ecSmrg ) 87405b261ecSmrg ReleaseCapture (); 87505b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam); 87605b261ecSmrg 87705b261ecSmrg case WM_XBUTTONDBLCLK: 87805b261ecSmrg case WM_XBUTTONDOWN: 87905b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 88005b261ecSmrg break; 88105b261ecSmrg if (s_pScreenInfo->fRootless 88205b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM 88305b261ecSmrg || s_pScreenInfo->fMWExtWM 88405b261ecSmrg#endif 88505b261ecSmrg ) 88605b261ecSmrg SetCapture (hwnd); 88705b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonPress, HIWORD(wParam) + 5, wParam); 88805b261ecSmrg case WM_XBUTTONUP: 88905b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 89005b261ecSmrg break; 89105b261ecSmrg if (s_pScreenInfo->fRootless 89205b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM 89305b261ecSmrg || s_pScreenInfo->fMWExtWM 89405b261ecSmrg#endif 89505b261ecSmrg ) 89605b261ecSmrg ReleaseCapture (); 89705b261ecSmrg return winMouseButtonsHandle (s_pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam); 89805b261ecSmrg 89905b261ecSmrg case WM_TIMER: 90005b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 90105b261ecSmrg break; 90205b261ecSmrg 90305b261ecSmrg /* Branch on the timer id */ 90405b261ecSmrg switch (wParam) 90505b261ecSmrg { 90605b261ecSmrg case WIN_E3B_TIMER_ID: 90705b261ecSmrg /* Send delayed button press */ 90805b261ecSmrg winMouseButtonsSendEvent (ButtonPress, 90905b261ecSmrg s_pScreenPriv->iE3BCachedPress); 91005b261ecSmrg 91105b261ecSmrg /* Kill this timer */ 91205b261ecSmrg KillTimer (s_pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID); 91305b261ecSmrg 91405b261ecSmrg /* Clear screen privates flags */ 91505b261ecSmrg s_pScreenPriv->iE3BCachedPress = 0; 91605b261ecSmrg break; 91705b261ecSmrg 91805b261ecSmrg case WIN_POLLING_MOUSE_TIMER_ID: 91905b261ecSmrg { 92005b261ecSmrg POINT point; 92105b261ecSmrg WPARAM wL, wM, wR, wShift, wCtrl; 92205b261ecSmrg LPARAM lPos; 92305b261ecSmrg 92405b261ecSmrg /* Get the current position of the mouse cursor */ 92505b261ecSmrg GetCursorPos (&point); 92605b261ecSmrg 92705b261ecSmrg /* Map from screen (-X, -Y) to root (0, 0) */ 92805b261ecSmrg point.x -= GetSystemMetrics (SM_XVIRTUALSCREEN); 92905b261ecSmrg point.y -= GetSystemMetrics (SM_YVIRTUALSCREEN); 93005b261ecSmrg 93105b261ecSmrg /* Deliver absolute cursor position to X Server */ 93205b261ecSmrg miPointerAbsoluteCursor (point.x, point.y, 93305b261ecSmrg g_c32LastInputEventTime = GetTickCount()); 93405b261ecSmrg 93505b261ecSmrg /* Check if a button was released but we didn't see it */ 93605b261ecSmrg GetCursorPos (&point); 93705b261ecSmrg wL = (GetKeyState (VK_LBUTTON) & 0x8000)?MK_LBUTTON:0; 93805b261ecSmrg wM = (GetKeyState (VK_MBUTTON) & 0x8000)?MK_MBUTTON:0; 93905b261ecSmrg wR = (GetKeyState (VK_RBUTTON) & 0x8000)?MK_RBUTTON:0; 94005b261ecSmrg wShift = (GetKeyState (VK_SHIFT) & 0x8000)?MK_SHIFT:0; 94105b261ecSmrg wCtrl = (GetKeyState (VK_CONTROL) & 0x8000)?MK_CONTROL:0; 94205b261ecSmrg lPos = MAKELPARAM(point.x, point.y); 94305b261ecSmrg if (g_fButton[0] & !wL) 94405b261ecSmrg PostMessage (hwnd, WM_LBUTTONUP, wCtrl|wM|wR|wShift, lPos); 94505b261ecSmrg if (g_fButton[1] & !wM) 94605b261ecSmrg PostMessage (hwnd, WM_MBUTTONUP, wCtrl|wL|wR|wShift, lPos); 94705b261ecSmrg if (g_fButton[2] & !wR) 94805b261ecSmrg PostMessage (hwnd, WM_RBUTTONUP, wCtrl|wL|wM|wShift, lPos); 94905b261ecSmrg } 95005b261ecSmrg } 95105b261ecSmrg return 0; 95205b261ecSmrg 95305b261ecSmrg case WM_CTLCOLORSCROLLBAR: 95405b261ecSmrg FatalError ("winWindowProc - WM_CTLCOLORSCROLLBAR - We are not " 95505b261ecSmrg "supposed to get this message. Exiting.\n"); 95605b261ecSmrg return 0; 95705b261ecSmrg 95805b261ecSmrg case WM_MOUSEWHEEL: 95905b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 96005b261ecSmrg break; 96105b261ecSmrg#if CYGDEBUG 96205b261ecSmrg winDebug ("winWindowProc - WM_MOUSEWHEEL\n"); 96305b261ecSmrg#endif 96405b261ecSmrg winMouseWheel (s_pScreen, GET_WHEEL_DELTA_WPARAM(wParam)); 96505b261ecSmrg break; 96605b261ecSmrg 96705b261ecSmrg case WM_SETFOCUS: 96805b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 96905b261ecSmrg break; 97005b261ecSmrg 97105b261ecSmrg /* Save handle of our main window that last received focus */ 97205b261ecSmrg g_hwndKeyboardFocus = hwnd; 97305b261ecSmrg 97405b261ecSmrg /* Restore the state of all mode keys */ 97505b261ecSmrg winRestoreModeKeyStates (); 97605b261ecSmrg 97705b261ecSmrg /* Add the keyboard hook if possible */ 97805b261ecSmrg if (g_fKeyboardHookLL) 97905b261ecSmrg g_fKeyboardHookLL = winInstallKeyboardHookLL (); 98005b261ecSmrg return 0; 98105b261ecSmrg 98205b261ecSmrg case WM_KILLFOCUS: 98305b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 98405b261ecSmrg break; 98505b261ecSmrg 98605b261ecSmrg /* Clear handle of our main window that last received focus */ 98705b261ecSmrg g_hwndKeyboardFocus = NULL; 98805b261ecSmrg 98905b261ecSmrg /* Release any pressed keys */ 99005b261ecSmrg winKeybdReleaseKeys (); 99105b261ecSmrg 99205b261ecSmrg /* Remove our keyboard hook if it is installed */ 99305b261ecSmrg winRemoveKeyboardHookLL (); 99405b261ecSmrg return 0; 99505b261ecSmrg 99605b261ecSmrg case WM_SYSKEYDOWN: 99705b261ecSmrg case WM_KEYDOWN: 99805b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 99905b261ecSmrg break; 100005b261ecSmrg 100105b261ecSmrg /* 100205b261ecSmrg * FIXME: Catching Alt-F4 like this is really terrible. This should 100305b261ecSmrg * be generalized to handle other Windows keyboard signals. Actually, 100405b261ecSmrg * the list keys to catch and the actions to perform when caught should 100505b261ecSmrg * be configurable; that way user's can customize the keys that they 100605b261ecSmrg * need to have passed through to their window manager or apps, or they 100705b261ecSmrg * can remap certain actions to new key codes that do not conflict 100805b261ecSmrg * with the X apps that they are using. Yeah, that'll take awhile. 100905b261ecSmrg */ 101005b261ecSmrg if ((s_pScreenInfo->fUseWinKillKey && wParam == VK_F4 101105b261ecSmrg && (GetKeyState (VK_MENU) & 0x8000)) 101205b261ecSmrg || (s_pScreenInfo->fUseUnixKillKey && wParam == VK_BACK 101305b261ecSmrg && (GetKeyState (VK_MENU) & 0x8000) 101405b261ecSmrg && (GetKeyState (VK_CONTROL) & 0x8000))) 101505b261ecSmrg { 101605b261ecSmrg /* 101705b261ecSmrg * Better leave this message here, just in case some unsuspecting 101805b261ecSmrg * user enters Alt + F4 and is surprised when the application 101905b261ecSmrg * quits. 102005b261ecSmrg */ 102105b261ecSmrg ErrorF ("winWindowProc - WM_*KEYDOWN - Closekey hit, quitting\n"); 102205b261ecSmrg 102305b261ecSmrg /* Display Exit dialog */ 102405b261ecSmrg winDisplayExitDialog (s_pScreenPriv); 102505b261ecSmrg return 0; 102605b261ecSmrg } 102705b261ecSmrg 102805b261ecSmrg /* 102905b261ecSmrg * Don't do anything for the Windows keys, as focus will soon 103005b261ecSmrg * be returned to Windows. We may be able to trap the Windows keys, 103105b261ecSmrg * but we should determine if that is desirable before doing so. 103205b261ecSmrg */ 103305b261ecSmrg if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL) 103405b261ecSmrg break; 103505b261ecSmrg 103605b261ecSmrg#ifdef XKB 103705b261ecSmrg /* 103805b261ecSmrg * Discard presses generated from Windows auto-repeat 103905b261ecSmrg * ago: Only discard them if XKB is not disabled 104005b261ecSmrg */ 104105b261ecSmrg if (!g_winInfo.xkb.disable && (lParam & (1<<30))) 104205b261ecSmrg { 104305b261ecSmrg switch (wParam) 104405b261ecSmrg { 104505b261ecSmrg /* ago: Pressing LControl while RControl is pressed is 104605b261ecSmrg * Indicated as repeat. Fix this! 104705b261ecSmrg */ 104805b261ecSmrg case VK_CONTROL: 104905b261ecSmrg case VK_SHIFT: 105005b261ecSmrg if (winCheckKeyPressed(wParam, lParam)) 105105b261ecSmrg return 0; 105205b261ecSmrg break; 105305b261ecSmrg default: 105405b261ecSmrg return 0; 105505b261ecSmrg } 105605b261ecSmrg } 105705b261ecSmrg#endif 105805b261ecSmrg 105905b261ecSmrg /* Discard fake Ctrl_L presses that precede AltGR on non-US keyboards */ 106005b261ecSmrg if (winIsFakeCtrl_L (message, wParam, lParam)) 106105b261ecSmrg return 0; 106205b261ecSmrg 106305b261ecSmrg /* Translate Windows key code to X scan code */ 106405b261ecSmrg winTranslateKey (wParam, lParam, &iScanCode); 106505b261ecSmrg 106605b261ecSmrg /* Ignore repeats for CapsLock */ 106705b261ecSmrg if (wParam == VK_CAPITAL) 106805b261ecSmrg lParam = 1; 106905b261ecSmrg 107005b261ecSmrg /* Send the key event(s) */ 107105b261ecSmrg for (i = 0; i < LOWORD(lParam); ++i) 107205b261ecSmrg winSendKeyEvent (iScanCode, TRUE); 107305b261ecSmrg return 0; 107405b261ecSmrg 107505b261ecSmrg case WM_SYSKEYUP: 107605b261ecSmrg case WM_KEYUP: 107705b261ecSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 107805b261ecSmrg break; 107905b261ecSmrg 108005b261ecSmrg /* 108105b261ecSmrg * Don't do anything for the Windows keys, as focus will soon 108205b261ecSmrg * be returned to Windows. We may be able to trap the Windows keys, 108305b261ecSmrg * but we should determine if that is desirable before doing so. 108405b261ecSmrg */ 108505b261ecSmrg if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL) 108605b261ecSmrg break; 108705b261ecSmrg 108805b261ecSmrg /* Ignore the fake Ctrl_L that follows an AltGr release */ 108905b261ecSmrg if (winIsFakeCtrl_L (message, wParam, lParam)) 109005b261ecSmrg return 0; 109105b261ecSmrg 109205b261ecSmrg /* Enqueue a keyup event */ 109305b261ecSmrg winTranslateKey (wParam, lParam, &iScanCode); 109405b261ecSmrg winSendKeyEvent (iScanCode, FALSE); 109505b261ecSmrg 109605b261ecSmrg /* Release all pressed shift keys */ 109705b261ecSmrg if (wParam == VK_SHIFT) 109805b261ecSmrg winFixShiftKeys (iScanCode); 109905b261ecSmrg return 0; 110005b261ecSmrg 110105b261ecSmrg case WM_HOTKEY: 110205b261ecSmrg if (s_pScreenPriv == NULL) 110305b261ecSmrg break; 110405b261ecSmrg 110505b261ecSmrg /* Call the engine-specific hot key handler */ 110605b261ecSmrg (*s_pScreenPriv->pwinHotKeyAltTab) (s_pScreen); 110705b261ecSmrg return 0; 110805b261ecSmrg 110905b261ecSmrg case WM_ACTIVATE: 111005b261ecSmrg if (s_pScreenPriv == NULL 111105b261ecSmrg || s_pScreenInfo->fIgnoreInput) 111205b261ecSmrg break; 111305b261ecSmrg 111405b261ecSmrg /* TODO: Override display of window when we have a bad depth */ 111505b261ecSmrg if (LOWORD(wParam) != WA_INACTIVE && s_pScreenPriv->fBadDepth) 111605b261ecSmrg { 111705b261ecSmrg ErrorF ("winWindowProc - WM_ACTIVATE - Bad depth, trying " 111805b261ecSmrg "to override window activation\n"); 111905b261ecSmrg 112005b261ecSmrg /* Minimize the window */ 112105b261ecSmrg ShowWindow (hwnd, SW_MINIMIZE); 112205b261ecSmrg 112305b261ecSmrg /* Display dialog box */ 112405b261ecSmrg if (g_hDlgDepthChange != NULL) 112505b261ecSmrg { 112605b261ecSmrg /* Make the existing dialog box active */ 112705b261ecSmrg SetActiveWindow (g_hDlgDepthChange); 112805b261ecSmrg } 112905b261ecSmrg else 113005b261ecSmrg { 113105b261ecSmrg /* TODO: Recreate the dialog box and bring to the top */ 113205b261ecSmrg ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT); 113305b261ecSmrg } 113405b261ecSmrg 113505b261ecSmrg /* Don't do any other processing of this message */ 113605b261ecSmrg return 0; 113705b261ecSmrg } 113805b261ecSmrg 113905b261ecSmrg#if CYGDEBUG 114005b261ecSmrg winDebug ("winWindowProc - WM_ACTIVATE\n"); 114105b261ecSmrg#endif 114205b261ecSmrg 114305b261ecSmrg /* 114405b261ecSmrg * Focus is being changed to another window. 114505b261ecSmrg * The other window may or may not belong to 114605b261ecSmrg * our process. 114705b261ecSmrg */ 114805b261ecSmrg 114905b261ecSmrg /* Clear any lingering wheel delta */ 115005b261ecSmrg s_pScreenPriv->iDeltaZ = 0; 115105b261ecSmrg 115205b261ecSmrg /* Reshow the Windows mouse cursor if we are being deactivated */ 115305b261ecSmrg if (g_fSoftwareCursor && LOWORD(wParam) == WA_INACTIVE 115405b261ecSmrg && !g_fCursor) 115505b261ecSmrg { 115605b261ecSmrg /* Show Windows cursor */ 115705b261ecSmrg g_fCursor = TRUE; 115805b261ecSmrg ShowCursor (TRUE); 115905b261ecSmrg } 116005b261ecSmrg return 0; 116105b261ecSmrg 116205b261ecSmrg case WM_ACTIVATEAPP: 116305b261ecSmrg if (s_pScreenPriv == NULL 116405b261ecSmrg || s_pScreenInfo->fIgnoreInput) 116505b261ecSmrg break; 116605b261ecSmrg 116705b261ecSmrg#if CYGDEBUG || TRUE 116805b261ecSmrg winDebug ("winWindowProc - WM_ACTIVATEAPP\n"); 116905b261ecSmrg#endif 117005b261ecSmrg 117105b261ecSmrg /* Activate or deactivate */ 117205b261ecSmrg s_pScreenPriv->fActive = wParam; 117305b261ecSmrg 117405b261ecSmrg /* Reshow the Windows mouse cursor if we are being deactivated */ 117505b261ecSmrg if (g_fSoftwareCursor && !s_pScreenPriv->fActive 117605b261ecSmrg && !g_fCursor) 117705b261ecSmrg { 117805b261ecSmrg /* Show Windows cursor */ 117905b261ecSmrg g_fCursor = TRUE; 118005b261ecSmrg ShowCursor (TRUE); 118105b261ecSmrg } 118205b261ecSmrg 118305b261ecSmrg#ifdef XWIN_CLIPBOARD 118405b261ecSmrg /* Make sure the clipboard chain is ok. */ 118505b261ecSmrg winFixClipboardChain (); 118605b261ecSmrg#endif 118705b261ecSmrg 118805b261ecSmrg /* Call engine specific screen activation/deactivation function */ 118905b261ecSmrg (*s_pScreenPriv->pwinActivateApp) (s_pScreen); 119005b261ecSmrg 119105b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM 119205b261ecSmrg if (s_pScreenPriv->fActive) 119305b261ecSmrg { 119405b261ecSmrg /* Restack all window unless using built-in wm. */ 119505b261ecSmrg if (s_pScreenInfo->fInternalWM && s_pScreenInfo->fAnotherWMRunning) 119605b261ecSmrg winMWExtWMRestackWindows (s_pScreen); 119705b261ecSmrg } 119805b261ecSmrg#endif 119905b261ecSmrg 120005b261ecSmrg return 0; 120105b261ecSmrg 120205b261ecSmrg case WM_COMMAND: 120305b261ecSmrg switch (LOWORD (wParam)) 120405b261ecSmrg { 120505b261ecSmrg case ID_APP_EXIT: 120605b261ecSmrg /* Display Exit dialog */ 120705b261ecSmrg winDisplayExitDialog (s_pScreenPriv); 120805b261ecSmrg return 0; 120905b261ecSmrg 121005b261ecSmrg#ifdef XWIN_MULTIWINDOW 121105b261ecSmrg case ID_APP_HIDE_ROOT: 121205b261ecSmrg if (s_pScreenPriv->fRootWindowShown) 121305b261ecSmrg ShowWindow (s_pScreenPriv->hwndScreen, SW_HIDE); 121405b261ecSmrg else 121505b261ecSmrg ShowWindow (s_pScreenPriv->hwndScreen, SW_SHOW); 121605b261ecSmrg s_pScreenPriv->fRootWindowShown = !s_pScreenPriv->fRootWindowShown; 121705b261ecSmrg return 0; 121805b261ecSmrg#endif 121905b261ecSmrg 122005b261ecSmrg case ID_APP_ABOUT: 122105b261ecSmrg /* Display the About box */ 122205b261ecSmrg winDisplayAboutDialog (s_pScreenPriv); 122305b261ecSmrg return 0; 122405b261ecSmrg 122505b261ecSmrg default: 122605b261ecSmrg /* It's probably one of the custom menus... */ 122705b261ecSmrg if (HandleCustomWM_COMMAND (0, LOWORD (wParam))) 122805b261ecSmrg return 0; 122905b261ecSmrg } 123005b261ecSmrg break; 123105b261ecSmrg 123205b261ecSmrg case WM_ENDSESSION: 123305b261ecSmrg case WM_GIVEUP: 123405b261ecSmrg /* Tell X that we are giving up */ 123505b261ecSmrg#ifdef XWIN_MULTIWINDOW 123605b261ecSmrg if (s_pScreenInfo->fMultiWindow) 123705b261ecSmrg winDeinitMultiWindowWM (); 123805b261ecSmrg#endif 123905b261ecSmrg GiveUp (0); 124005b261ecSmrg return 0; 124105b261ecSmrg 124205b261ecSmrg case WM_CLOSE: 124305b261ecSmrg /* Display Exit dialog */ 124405b261ecSmrg winDisplayExitDialog (s_pScreenPriv); 124505b261ecSmrg return 0; 124605b261ecSmrg 124705b261ecSmrg case WM_SETCURSOR: 124805b261ecSmrg if (LOWORD(lParam) == HTCLIENT) 124905b261ecSmrg { 125005b261ecSmrg if (!g_fSoftwareCursor) SetCursor (s_pScreenPriv->cursor.handle); 125105b261ecSmrg return TRUE; 125205b261ecSmrg } 125305b261ecSmrg break; 125405b261ecSmrg 125505b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM 125605b261ecSmrg case WM_MANAGE: 125705b261ecSmrg ErrorF ("winWindowProc - WM_MANAGE\n"); 125805b261ecSmrg s_pScreenInfo->fAnotherWMRunning = FALSE; 125905b261ecSmrg 126005b261ecSmrg if (s_pScreenInfo->fInternalWM) 126105b261ecSmrg { 126205b261ecSmrg EnumThreadWindows (g_dwCurrentThreadID, winMWExtWMDecorateWindow, 0); 126305b261ecSmrg //RootlessRepositionWindows (s_pScreen); 126405b261ecSmrg } 126505b261ecSmrg break; 126605b261ecSmrg 126705b261ecSmrg case WM_UNMANAGE: 126805b261ecSmrg ErrorF ("winWindowProc - WM_UNMANAGE\n"); 126905b261ecSmrg s_pScreenInfo->fAnotherWMRunning = TRUE; 127005b261ecSmrg 127105b261ecSmrg if (s_pScreenInfo->fInternalWM) 127205b261ecSmrg { 127305b261ecSmrg EnumThreadWindows (g_dwCurrentThreadID, winMWExtWMDecorateWindow, 0); 127405b261ecSmrg winMWExtWMRestackWindows (s_pScreen); 127505b261ecSmrg } 127605b261ecSmrg break; 127705b261ecSmrg#endif 127805b261ecSmrg 127905b261ecSmrg default: 128005b261ecSmrg if(message == s_uTaskbarRestart) 128105b261ecSmrg { 128205b261ecSmrg winInitNotifyIcon (s_pScreenPriv); 128305b261ecSmrg } 128405b261ecSmrg break; 128505b261ecSmrg } 128605b261ecSmrg 128705b261ecSmrg return DefWindowProc (hwnd, message, wParam, lParam); 128805b261ecSmrg} 1289