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