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" 439ace9065Smrg#include "winmonitors.h" 4405b261ecSmrg#include "inputstr.h" 4535c4bbdfSmrg#include "winclipboard/winclipboard.h" 4605b261ecSmrg 4705b261ecSmrg/* 4805b261ecSmrg * Global variables 4905b261ecSmrg */ 5005b261ecSmrg 5135c4bbdfSmrgBool g_fCursor = TRUE; 5235c4bbdfSmrgBool g_fButton[3] = { FALSE, FALSE, FALSE }; 5305b261ecSmrg 5405b261ecSmrg/* 5505b261ecSmrg * Called by winWakeupHandler 5605b261ecSmrg * Processes current Windows message 5705b261ecSmrg */ 5805b261ecSmrg 5905b261ecSmrgLRESULT CALLBACK 6035c4bbdfSmrgwinWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 6105b261ecSmrg{ 6235c4bbdfSmrg static winPrivScreenPtr s_pScreenPriv = NULL; 6335c4bbdfSmrg static winScreenInfo *s_pScreenInfo = NULL; 6435c4bbdfSmrg static ScreenPtr s_pScreen = NULL; 6535c4bbdfSmrg static HWND s_hwndLastPrivates = NULL; 6635c4bbdfSmrg static Bool s_fTracking = FALSE; 6735c4bbdfSmrg static unsigned long s_ulServerGeneration = 0; 6835c4bbdfSmrg static UINT s_uTaskbarRestart = 0; 6935c4bbdfSmrg int iScanCode; 7035c4bbdfSmrg int i; 7105b261ecSmrg 7205b261ecSmrg#if CYGDEBUG 7335c4bbdfSmrg winDebugWin32Message("winWindowProc", hwnd, message, wParam, lParam); 7405b261ecSmrg#endif 7535c4bbdfSmrg 7635c4bbdfSmrg /* Watch for server regeneration */ 7735c4bbdfSmrg if (g_ulServerGeneration != s_ulServerGeneration) { 7835c4bbdfSmrg /* Store new server generation */ 7935c4bbdfSmrg s_ulServerGeneration = g_ulServerGeneration; 8005b261ecSmrg } 8105b261ecSmrg 8235c4bbdfSmrg /* Only retrieve new privates pointers if window handle is null or changed */ 8335c4bbdfSmrg if ((s_pScreenPriv == NULL || hwnd != s_hwndLastPrivates) 8435c4bbdfSmrg && (s_pScreenPriv = GetProp(hwnd, WIN_SCR_PROP)) != NULL) { 8505b261ecSmrg#if CYGDEBUG 8635c4bbdfSmrg winDebug("winWindowProc - Setting privates handle\n"); 8705b261ecSmrg#endif 8835c4bbdfSmrg s_pScreenInfo = s_pScreenPriv->pScreenInfo; 8935c4bbdfSmrg s_pScreen = s_pScreenInfo->pScreen; 9035c4bbdfSmrg s_hwndLastPrivates = hwnd; 9105b261ecSmrg } 9235c4bbdfSmrg else if (s_pScreenPriv == NULL) { 9335c4bbdfSmrg /* For safety, handle case that should never happen */ 9435c4bbdfSmrg s_pScreenInfo = NULL; 9535c4bbdfSmrg s_pScreen = NULL; 9635c4bbdfSmrg s_hwndLastPrivates = NULL; 9705b261ecSmrg } 9805b261ecSmrg 9935c4bbdfSmrg /* Branch on message type */ 10035c4bbdfSmrg switch (message) { 10105b261ecSmrg case WM_TRAYICON: 10235c4bbdfSmrg return winHandleIconMessage(hwnd, message, wParam, lParam, 10335c4bbdfSmrg s_pScreenPriv); 10405b261ecSmrg 10505b261ecSmrg case WM_CREATE: 10605b261ecSmrg#if CYGDEBUG 10735c4bbdfSmrg winDebug("winWindowProc - WM_CREATE\n"); 10805b261ecSmrg#endif 10935c4bbdfSmrg 11035c4bbdfSmrg /* 11135c4bbdfSmrg * Add a property to our display window that references 11235c4bbdfSmrg * this screens' privates. 11335c4bbdfSmrg * 11435c4bbdfSmrg * This allows the window procedure to refer to the 11535c4bbdfSmrg * appropriate window DC and shadow DC for the window that 11635c4bbdfSmrg * it is processing. We use this to repaint exposed 11735c4bbdfSmrg * areas of our display window. 11835c4bbdfSmrg */ 11935c4bbdfSmrg s_pScreenPriv = ((LPCREATESTRUCT) lParam)->lpCreateParams; 12035c4bbdfSmrg s_pScreenInfo = s_pScreenPriv->pScreenInfo; 12135c4bbdfSmrg s_pScreen = s_pScreenInfo->pScreen; 12235c4bbdfSmrg s_hwndLastPrivates = hwnd; 12335c4bbdfSmrg s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); 12435c4bbdfSmrg SetProp(hwnd, WIN_SCR_PROP, s_pScreenPriv); 12535c4bbdfSmrg 12635c4bbdfSmrg /* Setup tray icon */ 12735c4bbdfSmrg if (!s_pScreenInfo->fNoTrayIcon) { 12835c4bbdfSmrg /* 12935c4bbdfSmrg * NOTE: The WM_CREATE message is processed before CreateWindowEx 13035c4bbdfSmrg * returns, so s_pScreenPriv->hwndScreen is invalid at this point. 13135c4bbdfSmrg * We go ahead and copy our hwnd parameter over top of the screen 13235c4bbdfSmrg * privates hwndScreen so that we have a valid value for 13335c4bbdfSmrg * that member. Otherwise, the tray icon will disappear 13435c4bbdfSmrg * the first time you move the mouse over top of it. 13535c4bbdfSmrg */ 13635c4bbdfSmrg 13735c4bbdfSmrg s_pScreenPriv->hwndScreen = hwnd; 13835c4bbdfSmrg 13935c4bbdfSmrg winInitNotifyIcon(s_pScreenPriv); 14035c4bbdfSmrg } 14135c4bbdfSmrg return 0; 14205b261ecSmrg 14305b261ecSmrg case WM_DISPLAYCHANGE: 14435c4bbdfSmrg /* 14535c4bbdfSmrg WM_DISPLAYCHANGE seems to be sent when the monitor layout or 146ed6184dfSmrg any monitor's resolution or depth changes, but its lParam and 14735c4bbdfSmrg wParam always indicate the resolution and bpp for the primary 14835c4bbdfSmrg monitor (so ignore that as we could be on any monitor...) 14935c4bbdfSmrg */ 15035c4bbdfSmrg 15135c4bbdfSmrg /* We cannot handle a display mode change during initialization */ 15235c4bbdfSmrg if (s_pScreenInfo == NULL) 15335c4bbdfSmrg FatalError("winWindowProc - WM_DISPLAYCHANGE - The display " 154ed6184dfSmrg "mode changed while we were initializing. This is " 15535c4bbdfSmrg "very bad and unexpected. Exiting.\n"); 15635c4bbdfSmrg 15735c4bbdfSmrg /* 15835c4bbdfSmrg * We do not care about display changes with 15935c4bbdfSmrg * fullscreen DirectDraw engines, because those engines set 16035c4bbdfSmrg * their own mode when they become active. 16135c4bbdfSmrg */ 16235c4bbdfSmrg if (s_pScreenInfo->fFullScreen 1631b5d61b8Smrg && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)) { 16435c4bbdfSmrg break; 16535c4bbdfSmrg } 1669ace9065Smrg 16735c4bbdfSmrg ErrorF("winWindowProc - WM_DISPLAYCHANGE - new width: %d " 16835c4bbdfSmrg "new height: %d new bpp: %d\n", 16935c4bbdfSmrg LOWORD(lParam), HIWORD(lParam), (int)wParam); 1709ace9065Smrg 17135c4bbdfSmrg /* 0 bpp has no defined meaning, ignore this message */ 17235c4bbdfSmrg if (wParam == 0) 17335c4bbdfSmrg break; 1749ace9065Smrg 17535c4bbdfSmrg /* 17635c4bbdfSmrg * Check for a disruptive change in depth. 17735c4bbdfSmrg * We can only display a message for a disruptive depth change, 17835c4bbdfSmrg * we cannot do anything to correct the situation. 17935c4bbdfSmrg */ 18035c4bbdfSmrg /* 18135c4bbdfSmrg XXX: maybe we need to check if GetSystemMetrics(SM_SAMEDISPLAYFORMAT) 18235c4bbdfSmrg has changed as well... 18335c4bbdfSmrg */ 18435c4bbdfSmrg if (s_pScreenInfo->dwBPP != 18535c4bbdfSmrg GetDeviceCaps(s_pScreenPriv->hdcScreen, BITSPIXEL)) { 18635c4bbdfSmrg if (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL) { 18735c4bbdfSmrg /* Cannot display the visual until the depth is restored */ 18835c4bbdfSmrg ErrorF("winWindowProc - Disruptive change in depth\n"); 18935c4bbdfSmrg 19035c4bbdfSmrg /* Display depth change dialog */ 19135c4bbdfSmrg winDisplayDepthChangeDialog(s_pScreenPriv); 19235c4bbdfSmrg 19335c4bbdfSmrg /* Flag that we have an invalid screen depth */ 19435c4bbdfSmrg s_pScreenPriv->fBadDepth = TRUE; 19535c4bbdfSmrg 19635c4bbdfSmrg /* Minimize the display window */ 19735c4bbdfSmrg ShowWindow(hwnd, SW_MINIMIZE); 1989ace9065Smrg } 19935c4bbdfSmrg else { 20035c4bbdfSmrg /* For GDI, performance may suffer until original depth is restored */ 20135c4bbdfSmrg ErrorF 20235c4bbdfSmrg ("winWindowProc - Performance may be non-optimal after change in depth\n"); 2039ace9065Smrg } 2049ace9065Smrg } 20535c4bbdfSmrg else { 20635c4bbdfSmrg /* Flag that we have a valid screen depth */ 20735c4bbdfSmrg s_pScreenPriv->fBadDepth = FALSE; 2089ace9065Smrg } 2099ace9065Smrg 21035c4bbdfSmrg /* 21135c4bbdfSmrg If we could cheaply check if this WM_DISPLAYCHANGE change 21235c4bbdfSmrg affects the monitor(s) which this X screen is displayed on 21335c4bbdfSmrg then we should do so here. For the moment, assume it does. 21435c4bbdfSmrg (this is probably usually the case so that might be an 21535c4bbdfSmrg overoptimization) 21635c4bbdfSmrg */ 21735c4bbdfSmrg { 21835c4bbdfSmrg /* 21935c4bbdfSmrg In rootless modes which are monitor or virtual desktop size 22035c4bbdfSmrg use RandR to resize the X screen 22135c4bbdfSmrg */ 22235c4bbdfSmrg if ((!s_pScreenInfo->fUserGaveHeightAndWidth) && 223ed6184dfSmrg (s_pScreenInfo->iResizeMode == resizeWithRandr) && (s_pScreenInfo-> 22435c4bbdfSmrg fRootless 22535c4bbdfSmrg || 22635c4bbdfSmrg s_pScreenInfo-> 22735c4bbdfSmrg fMultiWindow 22835c4bbdfSmrg )) { 2291b5d61b8Smrg DWORD dwWidth = 0, dwHeight = 0; 23035c4bbdfSmrg 23135c4bbdfSmrg if (s_pScreenInfo->fMultipleMonitors) { 23235c4bbdfSmrg /* resize to new virtual desktop size */ 23335c4bbdfSmrg dwWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN); 23435c4bbdfSmrg dwHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN); 2359ace9065Smrg } 23635c4bbdfSmrg else { 23735c4bbdfSmrg /* resize to new size of specified monitor */ 23835c4bbdfSmrg struct GetMonitorInfoData data; 23935c4bbdfSmrg 24035c4bbdfSmrg if (QueryMonitor(s_pScreenInfo->iMonitor, &data)) { 24135c4bbdfSmrg dwWidth = data.monitorWidth; 24235c4bbdfSmrg dwHeight = data.monitorHeight; 24335c4bbdfSmrg /* 24435c4bbdfSmrg XXX: monitor may have changed position, 24535c4bbdfSmrg so we might need to update xinerama data 24635c4bbdfSmrg */ 2479ace9065Smrg } 24835c4bbdfSmrg else { 24935c4bbdfSmrg ErrorF("Monitor number %d no longer exists!\n", 25035c4bbdfSmrg s_pScreenInfo->iMonitor); 2519ace9065Smrg } 2529ace9065Smrg } 2539ace9065Smrg 25435c4bbdfSmrg /* 25535c4bbdfSmrg XXX: probably a small bug here: we don't compute the work area 25635c4bbdfSmrg and allow for task bar 25735c4bbdfSmrg 25835c4bbdfSmrg XXX: generally, we don't allow for the task bar being moved after 25935c4bbdfSmrg the server is started 26035c4bbdfSmrg */ 26135c4bbdfSmrg 26235c4bbdfSmrg /* Set screen size to match new size, if it is different to current */ 2631b5d61b8Smrg if (((dwWidth != 0) && (dwHeight != 0)) && 2641b5d61b8Smrg ((s_pScreenInfo->dwWidth != dwWidth) || 2651b5d61b8Smrg (s_pScreenInfo->dwHeight != dwHeight))) { 26635c4bbdfSmrg winDoRandRScreenSetSize(s_pScreen, 26735c4bbdfSmrg dwWidth, 26835c4bbdfSmrg dwHeight, 26935c4bbdfSmrg (dwWidth * 25.4) / 27035c4bbdfSmrg monitorResolution, 27135c4bbdfSmrg (dwHeight * 25.4) / 27235c4bbdfSmrg monitorResolution); 2739ace9065Smrg } 2749ace9065Smrg } 27535c4bbdfSmrg else { 27635c4bbdfSmrg /* 27735c4bbdfSmrg * We can simply recreate the same-sized primary surface when 27835c4bbdfSmrg * the display dimensions change. 27935c4bbdfSmrg */ 28035c4bbdfSmrg 28135c4bbdfSmrg winDebug 28235c4bbdfSmrg ("winWindowProc - WM_DISPLAYCHANGE - Releasing and recreating primary surface\n"); 28335c4bbdfSmrg 28435c4bbdfSmrg /* Release the old primary surface */ 2851b5d61b8Smrg if (*s_pScreenPriv->pwinReleasePrimarySurface) 2861b5d61b8Smrg (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen); 28735c4bbdfSmrg 28835c4bbdfSmrg /* Create the new primary surface */ 2891b5d61b8Smrg if (*s_pScreenPriv->pwinCreatePrimarySurface) 2901b5d61b8Smrg (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen); 29135c4bbdfSmrg } 29235c4bbdfSmrg } 29305b261ecSmrg 29435c4bbdfSmrg break; 29505b261ecSmrg 29605b261ecSmrg case WM_SIZE: 29735c4bbdfSmrg { 29835c4bbdfSmrg SCROLLINFO si; 29935c4bbdfSmrg RECT rcWindow; 30035c4bbdfSmrg int iWidth, iHeight; 30105b261ecSmrg 30205b261ecSmrg#if CYGDEBUG 30335c4bbdfSmrg winDebug("winWindowProc - WM_SIZE\n"); 30405b261ecSmrg#endif 30505b261ecSmrg 30635c4bbdfSmrg /* Break if we do not allow resizing */ 3071b5d61b8Smrg if ((s_pScreenInfo->iResizeMode == resizeNotAllowed) 30835c4bbdfSmrg || !s_pScreenInfo->fDecoration 30935c4bbdfSmrg || s_pScreenInfo->fRootless 31035c4bbdfSmrg || s_pScreenInfo->fMultiWindow 31135c4bbdfSmrg || s_pScreenInfo->fFullScreen) 31235c4bbdfSmrg break; 31305b261ecSmrg 31435c4bbdfSmrg /* No need to resize if we get minimized */ 31535c4bbdfSmrg if (wParam == SIZE_MINIMIZED) 31635c4bbdfSmrg return 0; 31705b261ecSmrg 31835c4bbdfSmrg ErrorF("winWindowProc - WM_SIZE - new client area w: %d h: %d\n", 31935c4bbdfSmrg LOWORD(lParam), HIWORD(lParam)); 3209ace9065Smrg 32135c4bbdfSmrg if (s_pScreenInfo->iResizeMode == resizeWithRandr) { 3229ace9065Smrg /* Actual resizing is done on WM_EXITSIZEMOVE */ 3239ace9065Smrg return 0; 32435c4bbdfSmrg } 3259ace9065Smrg 3269ace9065Smrg /* Otherwise iResizeMode == resizeWithScrollbars */ 3279ace9065Smrg 32835c4bbdfSmrg /* 32935c4bbdfSmrg * Get the size of the whole window, including client area, 33035c4bbdfSmrg * scrollbars, and non-client area decorations (caption, borders). 33135c4bbdfSmrg * We do this because we need to check if the client area 33235c4bbdfSmrg * without scrollbars is large enough to display the whole visual. 33335c4bbdfSmrg * The new client area size passed by lParam already subtracts 33435c4bbdfSmrg * the size of the scrollbars if they are currently displayed. 33535c4bbdfSmrg * So checking is LOWORD(lParam) == visual_width and 33635c4bbdfSmrg * HIWORD(lParam) == visual_height will never tell us to hide 33735c4bbdfSmrg * the scrollbars because the client area would always be too small. 33835c4bbdfSmrg * GetClientRect returns the same sizes given by lParam, so we 33935c4bbdfSmrg * cannot use GetClientRect either. 34035c4bbdfSmrg */ 34135c4bbdfSmrg GetWindowRect(hwnd, &rcWindow); 34235c4bbdfSmrg iWidth = rcWindow.right - rcWindow.left; 34335c4bbdfSmrg iHeight = rcWindow.bottom - rcWindow.top; 34435c4bbdfSmrg 34535c4bbdfSmrg /* Subtract the frame size from the window size. */ 34635c4bbdfSmrg iWidth -= 2 * GetSystemMetrics(SM_CXSIZEFRAME); 34735c4bbdfSmrg iHeight -= (2 * GetSystemMetrics(SM_CYSIZEFRAME) 34835c4bbdfSmrg + GetSystemMetrics(SM_CYCAPTION)); 34935c4bbdfSmrg 35035c4bbdfSmrg /* 35135c4bbdfSmrg * Update scrollbar page sizes. 35235c4bbdfSmrg * NOTE: If page size == range, then the scrollbar is 35335c4bbdfSmrg * automatically hidden. 35435c4bbdfSmrg */ 35535c4bbdfSmrg 35635c4bbdfSmrg /* Is the naked client area large enough to show the whole visual? */ 35735c4bbdfSmrg if (iWidth < s_pScreenInfo->dwWidth 35835c4bbdfSmrg || iHeight < s_pScreenInfo->dwHeight) { 35935c4bbdfSmrg /* Client area too small to display visual, use scrollbars */ 36035c4bbdfSmrg iWidth -= GetSystemMetrics(SM_CXVSCROLL); 36135c4bbdfSmrg iHeight -= GetSystemMetrics(SM_CYHSCROLL); 36235c4bbdfSmrg } 36335c4bbdfSmrg 36435c4bbdfSmrg /* Set the horizontal scrollbar page size */ 36535c4bbdfSmrg si.cbSize = sizeof(si); 36635c4bbdfSmrg si.fMask = SIF_PAGE | SIF_RANGE; 36735c4bbdfSmrg si.nMin = 0; 36835c4bbdfSmrg si.nMax = s_pScreenInfo->dwWidth - 1; 36935c4bbdfSmrg si.nPage = iWidth; 37035c4bbdfSmrg SetScrollInfo(hwnd, SB_HORZ, &si, TRUE); 37135c4bbdfSmrg 37235c4bbdfSmrg /* Set the vertical scrollbar page size */ 37335c4bbdfSmrg si.cbSize = sizeof(si); 37435c4bbdfSmrg si.fMask = SIF_PAGE | SIF_RANGE; 37535c4bbdfSmrg si.nMin = 0; 37635c4bbdfSmrg si.nMax = s_pScreenInfo->dwHeight - 1; 37735c4bbdfSmrg si.nPage = iHeight; 37835c4bbdfSmrg SetScrollInfo(hwnd, SB_VERT, &si, TRUE); 37935c4bbdfSmrg 38035c4bbdfSmrg /* 38135c4bbdfSmrg * NOTE: Scrollbars may have moved if they were at the 38235c4bbdfSmrg * far right/bottom, so we query their current position. 38335c4bbdfSmrg */ 38435c4bbdfSmrg 38535c4bbdfSmrg /* Get the horizontal scrollbar position and set the offset */ 38635c4bbdfSmrg si.cbSize = sizeof(si); 38735c4bbdfSmrg si.fMask = SIF_POS; 38835c4bbdfSmrg GetScrollInfo(hwnd, SB_HORZ, &si); 38935c4bbdfSmrg s_pScreenInfo->dwXOffset = -si.nPos; 39035c4bbdfSmrg 39135c4bbdfSmrg /* Get the vertical scrollbar position and set the offset */ 39235c4bbdfSmrg si.cbSize = sizeof(si); 39335c4bbdfSmrg si.fMask = SIF_POS; 39435c4bbdfSmrg GetScrollInfo(hwnd, SB_VERT, &si); 39535c4bbdfSmrg s_pScreenInfo->dwYOffset = -si.nPos; 39635c4bbdfSmrg } 39735c4bbdfSmrg return 0; 39835c4bbdfSmrg 39935c4bbdfSmrg case WM_SYSCOMMAND: 40035c4bbdfSmrg if (s_pScreenInfo->iResizeMode == resizeWithRandr && 40135c4bbdfSmrg ((wParam & 0xfff0) == SC_MAXIMIZE || 40235c4bbdfSmrg (wParam & 0xfff0) == SC_RESTORE)) 40335c4bbdfSmrg PostMessage(hwnd, WM_EXITSIZEMOVE, 0, 0); 40435c4bbdfSmrg break; 40505b261ecSmrg 4069ace9065Smrg case WM_ENTERSIZEMOVE: 40735c4bbdfSmrg ErrorF("winWindowProc - WM_ENTERSIZEMOVE\n"); 40835c4bbdfSmrg break; 4099ace9065Smrg 4109ace9065Smrg case WM_EXITSIZEMOVE: 41135c4bbdfSmrg ErrorF("winWindowProc - WM_EXITSIZEMOVE\n"); 41235c4bbdfSmrg 41335c4bbdfSmrg if (s_pScreenInfo->iResizeMode == resizeWithRandr) { 41435c4bbdfSmrg /* Set screen size to match new client area, if it is different to current */ 41535c4bbdfSmrg RECT rcClient; 41635c4bbdfSmrg DWORD dwWidth, dwHeight; 41735c4bbdfSmrg 41835c4bbdfSmrg GetClientRect(hwnd, &rcClient); 41935c4bbdfSmrg dwWidth = rcClient.right - rcClient.left; 42035c4bbdfSmrg dwHeight = rcClient.bottom - rcClient.top; 42135c4bbdfSmrg 42235c4bbdfSmrg if ((s_pScreenInfo->dwWidth != dwWidth) || 42335c4bbdfSmrg (s_pScreenInfo->dwHeight != dwHeight)) { 42435c4bbdfSmrg /* mm = dots * (25.4 mm / inch) / (dots / inch) */ 42535c4bbdfSmrg winDoRandRScreenSetSize(s_pScreen, 42635c4bbdfSmrg dwWidth, 42735c4bbdfSmrg dwHeight, 42835c4bbdfSmrg (dwWidth * 25.4) / monitorResolution, 42935c4bbdfSmrg (dwHeight * 25.4) / monitorResolution); 4309ace9065Smrg } 4319ace9065Smrg } 4329ace9065Smrg 43335c4bbdfSmrg break; 4349ace9065Smrg 43505b261ecSmrg case WM_VSCROLL: 43635c4bbdfSmrg { 43735c4bbdfSmrg SCROLLINFO si; 43835c4bbdfSmrg int iVertPos; 43905b261ecSmrg 44005b261ecSmrg#if CYGDEBUG 44135c4bbdfSmrg winDebug("winWindowProc - WM_VSCROLL\n"); 44205b261ecSmrg#endif 44335c4bbdfSmrg 44435c4bbdfSmrg /* Get vertical scroll bar info */ 44535c4bbdfSmrg si.cbSize = sizeof(si); 44635c4bbdfSmrg si.fMask = SIF_ALL; 44735c4bbdfSmrg GetScrollInfo(hwnd, SB_VERT, &si); 44835c4bbdfSmrg 44935c4bbdfSmrg /* Save the vertical position for comparison later */ 45035c4bbdfSmrg iVertPos = si.nPos; 45135c4bbdfSmrg 45235c4bbdfSmrg /* 45335c4bbdfSmrg * Don't forget: 45435c4bbdfSmrg * moving the scrollbar to the DOWN, scroll the content UP 45535c4bbdfSmrg */ 45635c4bbdfSmrg switch (LOWORD(wParam)) { 45735c4bbdfSmrg case SB_TOP: 45835c4bbdfSmrg si.nPos = si.nMin; 45935c4bbdfSmrg break; 46035c4bbdfSmrg 46135c4bbdfSmrg case SB_BOTTOM: 46235c4bbdfSmrg si.nPos = si.nMax - si.nPage + 1; 46335c4bbdfSmrg break; 46435c4bbdfSmrg 46535c4bbdfSmrg case SB_LINEUP: 46635c4bbdfSmrg si.nPos -= 1; 46735c4bbdfSmrg break; 46835c4bbdfSmrg 46935c4bbdfSmrg case SB_LINEDOWN: 47035c4bbdfSmrg si.nPos += 1; 47135c4bbdfSmrg break; 47235c4bbdfSmrg 47335c4bbdfSmrg case SB_PAGEUP: 47435c4bbdfSmrg si.nPos -= si.nPage; 47535c4bbdfSmrg break; 47635c4bbdfSmrg 47735c4bbdfSmrg case SB_PAGEDOWN: 47835c4bbdfSmrg si.nPos += si.nPage; 47935c4bbdfSmrg break; 48035c4bbdfSmrg 48135c4bbdfSmrg case SB_THUMBTRACK: 48235c4bbdfSmrg si.nPos = si.nTrackPos; 48335c4bbdfSmrg break; 48435c4bbdfSmrg 48535c4bbdfSmrg default: 48635c4bbdfSmrg break; 48735c4bbdfSmrg } 48835c4bbdfSmrg 48935c4bbdfSmrg /* 49035c4bbdfSmrg * We retrieve the position after setting it, 49135c4bbdfSmrg * because Windows may adjust it. 49235c4bbdfSmrg */ 49335c4bbdfSmrg si.fMask = SIF_POS; 49435c4bbdfSmrg SetScrollInfo(hwnd, SB_VERT, &si, TRUE); 49535c4bbdfSmrg GetScrollInfo(hwnd, SB_VERT, &si); 49635c4bbdfSmrg 49735c4bbdfSmrg /* Scroll the window if the position has changed */ 49835c4bbdfSmrg if (si.nPos != iVertPos) { 49935c4bbdfSmrg /* Save the new offset for bit block transfers, etc. */ 50035c4bbdfSmrg s_pScreenInfo->dwYOffset = -si.nPos; 50135c4bbdfSmrg 50235c4bbdfSmrg /* Change displayed region in the window */ 50335c4bbdfSmrg ScrollWindowEx(hwnd, 50435c4bbdfSmrg 0, 50535c4bbdfSmrg iVertPos - si.nPos, 50635c4bbdfSmrg NULL, NULL, NULL, NULL, SW_INVALIDATE); 50735c4bbdfSmrg 50835c4bbdfSmrg /* Redraw the window contents */ 50935c4bbdfSmrg UpdateWindow(hwnd); 51035c4bbdfSmrg } 51135c4bbdfSmrg } 51235c4bbdfSmrg return 0; 51305b261ecSmrg 51405b261ecSmrg case WM_HSCROLL: 51535c4bbdfSmrg { 51635c4bbdfSmrg SCROLLINFO si; 51735c4bbdfSmrg int iHorzPos; 51805b261ecSmrg 51905b261ecSmrg#if CYGDEBUG 52035c4bbdfSmrg winDebug("winWindowProc - WM_HSCROLL\n"); 52105b261ecSmrg#endif 52235c4bbdfSmrg 52335c4bbdfSmrg /* Get horizontal scroll bar info */ 52435c4bbdfSmrg si.cbSize = sizeof(si); 52535c4bbdfSmrg si.fMask = SIF_ALL; 52635c4bbdfSmrg GetScrollInfo(hwnd, SB_HORZ, &si); 52735c4bbdfSmrg 52835c4bbdfSmrg /* Save the horizontal position for comparison later */ 52935c4bbdfSmrg iHorzPos = si.nPos; 53035c4bbdfSmrg 53135c4bbdfSmrg /* 53235c4bbdfSmrg * Don't forget: 53335c4bbdfSmrg * moving the scrollbar to the RIGHT, scroll the content LEFT 53435c4bbdfSmrg */ 53535c4bbdfSmrg switch (LOWORD(wParam)) { 53635c4bbdfSmrg case SB_LEFT: 53735c4bbdfSmrg si.nPos = si.nMin; 53835c4bbdfSmrg break; 53935c4bbdfSmrg 54035c4bbdfSmrg case SB_RIGHT: 54135c4bbdfSmrg si.nPos = si.nMax - si.nPage + 1; 54235c4bbdfSmrg break; 54335c4bbdfSmrg 54435c4bbdfSmrg case SB_LINELEFT: 54535c4bbdfSmrg si.nPos -= 1; 54635c4bbdfSmrg break; 54735c4bbdfSmrg 54835c4bbdfSmrg case SB_LINERIGHT: 54935c4bbdfSmrg si.nPos += 1; 55035c4bbdfSmrg break; 55135c4bbdfSmrg 55235c4bbdfSmrg case SB_PAGELEFT: 55335c4bbdfSmrg si.nPos -= si.nPage; 55435c4bbdfSmrg break; 55535c4bbdfSmrg 55635c4bbdfSmrg case SB_PAGERIGHT: 55735c4bbdfSmrg si.nPos += si.nPage; 55835c4bbdfSmrg break; 55935c4bbdfSmrg 56035c4bbdfSmrg case SB_THUMBTRACK: 56135c4bbdfSmrg si.nPos = si.nTrackPos; 56235c4bbdfSmrg break; 56335c4bbdfSmrg 56435c4bbdfSmrg default: 56535c4bbdfSmrg break; 56635c4bbdfSmrg } 56735c4bbdfSmrg 56835c4bbdfSmrg /* 56935c4bbdfSmrg * We retrieve the position after setting it, 57035c4bbdfSmrg * because Windows may adjust it. 57135c4bbdfSmrg */ 57235c4bbdfSmrg si.fMask = SIF_POS; 57335c4bbdfSmrg SetScrollInfo(hwnd, SB_HORZ, &si, TRUE); 57435c4bbdfSmrg GetScrollInfo(hwnd, SB_HORZ, &si); 57535c4bbdfSmrg 57635c4bbdfSmrg /* Scroll the window if the position has changed */ 57735c4bbdfSmrg if (si.nPos != iHorzPos) { 57835c4bbdfSmrg /* Save the new offset for bit block transfers, etc. */ 57935c4bbdfSmrg s_pScreenInfo->dwXOffset = -si.nPos; 58035c4bbdfSmrg 58135c4bbdfSmrg /* Change displayed region in the window */ 58235c4bbdfSmrg ScrollWindowEx(hwnd, 58335c4bbdfSmrg iHorzPos - si.nPos, 58435c4bbdfSmrg 0, NULL, NULL, NULL, NULL, SW_INVALIDATE); 58535c4bbdfSmrg 58635c4bbdfSmrg /* Redraw the window contents */ 58735c4bbdfSmrg UpdateWindow(hwnd); 58835c4bbdfSmrg } 58935c4bbdfSmrg } 59035c4bbdfSmrg return 0; 59105b261ecSmrg 59205b261ecSmrg case WM_GETMINMAXINFO: 59335c4bbdfSmrg { 59435c4bbdfSmrg MINMAXINFO *pMinMaxInfo = (MINMAXINFO *) lParam; 59535c4bbdfSmrg int iCaptionHeight; 59635c4bbdfSmrg int iBorderHeight, iBorderWidth; 59735c4bbdfSmrg 59835c4bbdfSmrg#if CYGDEBUG 59935c4bbdfSmrg winDebug("winWindowProc - WM_GETMINMAXINFO - pScreenInfo: %p\n", 60035c4bbdfSmrg s_pScreenInfo); 60105b261ecSmrg#endif 60205b261ecSmrg 60335c4bbdfSmrg /* Can't do anything without screen info */ 60435c4bbdfSmrg if (s_pScreenInfo == NULL 60535c4bbdfSmrg || (s_pScreenInfo->iResizeMode != resizeWithScrollbars) 60635c4bbdfSmrg || s_pScreenInfo->fFullScreen || !s_pScreenInfo->fDecoration 60735c4bbdfSmrg || s_pScreenInfo->fRootless 60835c4bbdfSmrg || s_pScreenInfo->fMultiWindow 60935c4bbdfSmrg ) 61035c4bbdfSmrg break; 61135c4bbdfSmrg 61235c4bbdfSmrg /* 61335c4bbdfSmrg * Here we can override the maximum tracking size, which 61435c4bbdfSmrg * is the largest size that can be assigned to our window 61535c4bbdfSmrg * via the sizing border. 61635c4bbdfSmrg */ 61735c4bbdfSmrg 61835c4bbdfSmrg /* 61935c4bbdfSmrg * FIXME: Do we only need to do this once, since our visual size 62035c4bbdfSmrg * does not change? Does Windows store this value statically 62135c4bbdfSmrg * once we have set it once? 62235c4bbdfSmrg */ 62335c4bbdfSmrg 62435c4bbdfSmrg /* Get the border and caption sizes */ 62535c4bbdfSmrg iCaptionHeight = GetSystemMetrics(SM_CYCAPTION); 62635c4bbdfSmrg iBorderWidth = 2 * GetSystemMetrics(SM_CXSIZEFRAME); 62735c4bbdfSmrg iBorderHeight = 2 * GetSystemMetrics(SM_CYSIZEFRAME); 62835c4bbdfSmrg 62935c4bbdfSmrg /* Allow the full visual to be displayed */ 63035c4bbdfSmrg pMinMaxInfo->ptMaxTrackSize.x = s_pScreenInfo->dwWidth + iBorderWidth; 63135c4bbdfSmrg pMinMaxInfo->ptMaxTrackSize.y 63235c4bbdfSmrg = s_pScreenInfo->dwHeight + iBorderHeight + iCaptionHeight; 63335c4bbdfSmrg } 63435c4bbdfSmrg return 0; 63505b261ecSmrg 63605b261ecSmrg case WM_ERASEBKGND: 63705b261ecSmrg#if CYGDEBUG 63835c4bbdfSmrg winDebug("winWindowProc - WM_ERASEBKGND\n"); 63905b261ecSmrg#endif 64035c4bbdfSmrg /* 64135c4bbdfSmrg * Pretend that we did erase the background but we don't care, 64235c4bbdfSmrg * the application uses the full window estate. This avoids some 64335c4bbdfSmrg * flickering when resizing. 64435c4bbdfSmrg */ 64535c4bbdfSmrg return TRUE; 64605b261ecSmrg 64705b261ecSmrg case WM_PAINT: 64805b261ecSmrg#if CYGDEBUG 64935c4bbdfSmrg winDebug("winWindowProc - WM_PAINT\n"); 65005b261ecSmrg#endif 65135c4bbdfSmrg /* Only paint if we have privates and the server is enabled */ 65235c4bbdfSmrg if (s_pScreenPriv == NULL 65335c4bbdfSmrg || !s_pScreenPriv->fEnabled 65435c4bbdfSmrg || (s_pScreenInfo->fFullScreen && !s_pScreenPriv->fActive) 65535c4bbdfSmrg || s_pScreenPriv->fBadDepth) { 65635c4bbdfSmrg /* We don't want to paint */ 65735c4bbdfSmrg break; 65835c4bbdfSmrg } 65935c4bbdfSmrg 66035c4bbdfSmrg /* Break out here if we don't have a valid paint routine */ 66135c4bbdfSmrg if (s_pScreenPriv->pwinBltExposedRegions == NULL) 66235c4bbdfSmrg break; 66335c4bbdfSmrg 66435c4bbdfSmrg /* Call the engine dependent repainter */ 66535c4bbdfSmrg (*s_pScreenPriv->pwinBltExposedRegions) (s_pScreen); 66635c4bbdfSmrg return 0; 66705b261ecSmrg 66805b261ecSmrg case WM_PALETTECHANGED: 66935c4bbdfSmrg { 67005b261ecSmrg#if CYGDEBUG 67135c4bbdfSmrg winDebug("winWindowProc - WM_PALETTECHANGED\n"); 67205b261ecSmrg#endif 67335c4bbdfSmrg /* 67435c4bbdfSmrg * Don't process if we don't have privates or a colormap, 67535c4bbdfSmrg * or if we have an invalid depth. 67635c4bbdfSmrg */ 67735c4bbdfSmrg if (s_pScreenPriv == NULL 67835c4bbdfSmrg || s_pScreenPriv->pcmapInstalled == NULL 67935c4bbdfSmrg || s_pScreenPriv->fBadDepth) 68035c4bbdfSmrg break; 68135c4bbdfSmrg 68235c4bbdfSmrg /* Return if we caused the palette to change */ 68335c4bbdfSmrg if ((HWND) wParam == hwnd) { 68435c4bbdfSmrg /* Redraw the screen */ 68535c4bbdfSmrg (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen); 68635c4bbdfSmrg return 0; 68735c4bbdfSmrg } 68835c4bbdfSmrg 68935c4bbdfSmrg /* Reinstall the windows palette */ 69035c4bbdfSmrg (*s_pScreenPriv->pwinRealizeInstalledPalette) (s_pScreen); 69135c4bbdfSmrg 69235c4bbdfSmrg /* Redraw the screen */ 69335c4bbdfSmrg (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen); 69435c4bbdfSmrg return 0; 69535c4bbdfSmrg } 69605b261ecSmrg 69705b261ecSmrg case WM_MOUSEMOVE: 69835c4bbdfSmrg /* We can't do anything without privates */ 69935c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 70035c4bbdfSmrg break; 70105b261ecSmrg 70235c4bbdfSmrg /* We can't do anything without g_pwinPointer */ 70335c4bbdfSmrg if (g_pwinPointer == NULL) 70435c4bbdfSmrg break; 70535c4bbdfSmrg 70635c4bbdfSmrg /* Has the mouse pointer crossed screens? */ 70735c4bbdfSmrg if (s_pScreen != miPointerGetScreen(g_pwinPointer)) 70835c4bbdfSmrg miPointerSetScreen(g_pwinPointer, s_pScreenInfo->dwScreen, 70935c4bbdfSmrg GET_X_LPARAM(lParam) - s_pScreenInfo->dwXOffset, 71035c4bbdfSmrg GET_Y_LPARAM(lParam) - s_pScreenInfo->dwYOffset); 71135c4bbdfSmrg 71235c4bbdfSmrg /* Are we tracking yet? */ 71335c4bbdfSmrg if (!s_fTracking) { 71435c4bbdfSmrg TRACKMOUSEEVENT tme; 71535c4bbdfSmrg 71635c4bbdfSmrg /* Setup data structure */ 71735c4bbdfSmrg ZeroMemory(&tme, sizeof(tme)); 71835c4bbdfSmrg tme.cbSize = sizeof(tme); 71935c4bbdfSmrg tme.dwFlags = TME_LEAVE; 72035c4bbdfSmrg tme.hwndTrack = hwnd; 7216747b715Smrg 72235c4bbdfSmrg /* Call the tracking function */ 72335c4bbdfSmrg if (!TrackMouseEvent(&tme)) 72435c4bbdfSmrg ErrorF("winWindowProc - TrackMouseEvent failed\n"); 72535c4bbdfSmrg 72635c4bbdfSmrg /* Flag that we are tracking now */ 72735c4bbdfSmrg s_fTracking = TRUE; 72835c4bbdfSmrg } 72935c4bbdfSmrg 73035c4bbdfSmrg /* Hide or show the Windows mouse cursor */ 73135c4bbdfSmrg if (g_fSoftwareCursor && g_fCursor && 73235c4bbdfSmrg (s_pScreenPriv->fActive || s_pScreenInfo->fLessPointer)) { 73335c4bbdfSmrg /* Hide Windows cursor */ 73435c4bbdfSmrg g_fCursor = FALSE; 73535c4bbdfSmrg ShowCursor(FALSE); 73635c4bbdfSmrg } 73735c4bbdfSmrg else if (g_fSoftwareCursor && !g_fCursor && !s_pScreenPriv->fActive 73835c4bbdfSmrg && !s_pScreenInfo->fLessPointer) { 73935c4bbdfSmrg /* Show Windows cursor */ 74035c4bbdfSmrg g_fCursor = TRUE; 74135c4bbdfSmrg ShowCursor(TRUE); 74235c4bbdfSmrg } 74335c4bbdfSmrg 74435c4bbdfSmrg /* Deliver absolute cursor position to X Server */ 74535c4bbdfSmrg winEnqueueMotion(GET_X_LPARAM(lParam) - s_pScreenInfo->dwXOffset, 74635c4bbdfSmrg GET_Y_LPARAM(lParam) - s_pScreenInfo->dwYOffset); 74735c4bbdfSmrg return 0; 74805b261ecSmrg 74905b261ecSmrg case WM_NCMOUSEMOVE: 75035c4bbdfSmrg /* 75135c4bbdfSmrg * We break instead of returning 0 since we need to call 75235c4bbdfSmrg * DefWindowProc to get the mouse cursor changes 75335c4bbdfSmrg * and min/max/close button highlighting in Windows XP. 75435c4bbdfSmrg * The Platform SDK says that you should return 0 if you 75535c4bbdfSmrg * process this message, but it fails to mention that you 75635c4bbdfSmrg * will give up any default functionality if you do return 0. 75735c4bbdfSmrg */ 75835c4bbdfSmrg 75935c4bbdfSmrg /* We can't do anything without privates */ 76035c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 76135c4bbdfSmrg break; 76235c4bbdfSmrg 76335c4bbdfSmrg /* Non-client mouse movement, show Windows cursor */ 76435c4bbdfSmrg if (g_fSoftwareCursor && !g_fCursor) { 76535c4bbdfSmrg g_fCursor = TRUE; 76635c4bbdfSmrg ShowCursor(TRUE); 76735c4bbdfSmrg } 76835c4bbdfSmrg break; 76905b261ecSmrg 77005b261ecSmrg case WM_MOUSELEAVE: 77135c4bbdfSmrg /* Mouse has left our client area */ 77205b261ecSmrg 77335c4bbdfSmrg /* Flag that we are no longer tracking */ 77435c4bbdfSmrg s_fTracking = FALSE; 77505b261ecSmrg 77635c4bbdfSmrg /* Show the mouse cursor, if necessary */ 77735c4bbdfSmrg if (g_fSoftwareCursor && !g_fCursor) { 77835c4bbdfSmrg g_fCursor = TRUE; 77935c4bbdfSmrg ShowCursor(TRUE); 78035c4bbdfSmrg } 78135c4bbdfSmrg return 0; 78205b261ecSmrg 78305b261ecSmrg case WM_LBUTTONDBLCLK: 78405b261ecSmrg case WM_LBUTTONDOWN: 78535c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 78635c4bbdfSmrg break; 787ed6184dfSmrg if (s_pScreenInfo->fRootless) 78835c4bbdfSmrg SetCapture(hwnd); 78935c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonPress, Button1, wParam); 79035c4bbdfSmrg 79105b261ecSmrg case WM_LBUTTONUP: 79235c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 79335c4bbdfSmrg break; 794ed6184dfSmrg if (s_pScreenInfo->fRootless) 79535c4bbdfSmrg ReleaseCapture(); 79635c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button1, wParam); 79705b261ecSmrg 79805b261ecSmrg case WM_MBUTTONDBLCLK: 79905b261ecSmrg case WM_MBUTTONDOWN: 80035c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 80135c4bbdfSmrg break; 802ed6184dfSmrg if (s_pScreenInfo->fRootless) 80335c4bbdfSmrg SetCapture(hwnd); 80435c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonPress, Button2, wParam); 80535c4bbdfSmrg 80605b261ecSmrg case WM_MBUTTONUP: 80735c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 80835c4bbdfSmrg break; 809ed6184dfSmrg if (s_pScreenInfo->fRootless) 81035c4bbdfSmrg ReleaseCapture(); 81135c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button2, wParam); 81235c4bbdfSmrg 81305b261ecSmrg case WM_RBUTTONDBLCLK: 81405b261ecSmrg case WM_RBUTTONDOWN: 81535c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 81635c4bbdfSmrg break; 817ed6184dfSmrg if (s_pScreenInfo->fRootless) 81835c4bbdfSmrg SetCapture(hwnd); 81935c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonPress, Button3, wParam); 82035c4bbdfSmrg 82105b261ecSmrg case WM_RBUTTONUP: 82235c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 82335c4bbdfSmrg break; 824ed6184dfSmrg if (s_pScreenInfo->fRootless) 82535c4bbdfSmrg ReleaseCapture(); 82635c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button3, wParam); 82705b261ecSmrg 82805b261ecSmrg case WM_XBUTTONDBLCLK: 82905b261ecSmrg case WM_XBUTTONDOWN: 83035c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 83135c4bbdfSmrg break; 832ed6184dfSmrg if (s_pScreenInfo->fRootless) 83335c4bbdfSmrg SetCapture(hwnd); 83435c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonPress, HIWORD(wParam) + 7, 83535c4bbdfSmrg wParam); 83605b261ecSmrg case WM_XBUTTONUP: 83735c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 83835c4bbdfSmrg break; 839ed6184dfSmrg if (s_pScreenInfo->fRootless) 84035c4bbdfSmrg ReleaseCapture(); 84135c4bbdfSmrg return winMouseButtonsHandle(s_pScreen, ButtonRelease, 84235c4bbdfSmrg HIWORD(wParam) + 7, wParam); 84305b261ecSmrg 84405b261ecSmrg case WM_TIMER: 84535c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 84635c4bbdfSmrg break; 84735c4bbdfSmrg 84835c4bbdfSmrg /* Branch on the timer id */ 84935c4bbdfSmrg switch (wParam) { 85035c4bbdfSmrg case WIN_E3B_TIMER_ID: 85135c4bbdfSmrg /* Send delayed button press */ 85235c4bbdfSmrg winMouseButtonsSendEvent(ButtonPress, 85335c4bbdfSmrg s_pScreenPriv->iE3BCachedPress); 85435c4bbdfSmrg 85535c4bbdfSmrg /* Kill this timer */ 85635c4bbdfSmrg KillTimer(s_pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID); 85735c4bbdfSmrg 85835c4bbdfSmrg /* Clear screen privates flags */ 85935c4bbdfSmrg s_pScreenPriv->iE3BCachedPress = 0; 86035c4bbdfSmrg break; 86135c4bbdfSmrg 86235c4bbdfSmrg case WIN_POLLING_MOUSE_TIMER_ID: 86335c4bbdfSmrg { 86435c4bbdfSmrg static POINT last_point; 86535c4bbdfSmrg POINT point; 86635c4bbdfSmrg WPARAM wL, wM, wR, wShift, wCtrl; 86735c4bbdfSmrg LPARAM lPos; 86835c4bbdfSmrg 86935c4bbdfSmrg /* Get the current position of the mouse cursor */ 87035c4bbdfSmrg GetCursorPos(&point); 87135c4bbdfSmrg 87235c4bbdfSmrg /* Map from screen (-X, -Y) to root (0, 0) */ 87335c4bbdfSmrg point.x -= GetSystemMetrics(SM_XVIRTUALSCREEN); 87435c4bbdfSmrg point.y -= GetSystemMetrics(SM_YVIRTUALSCREEN); 87535c4bbdfSmrg 87635c4bbdfSmrg /* If the mouse pointer has moved, deliver absolute cursor position to X Server */ 87735c4bbdfSmrg if (last_point.x != point.x || last_point.y != point.y) { 87835c4bbdfSmrg winEnqueueMotion(point.x, point.y); 87935c4bbdfSmrg last_point.x = point.x; 88035c4bbdfSmrg last_point.y = point.y; 88135c4bbdfSmrg } 88235c4bbdfSmrg 88335c4bbdfSmrg /* Check if a button was released but we didn't see it */ 88435c4bbdfSmrg GetCursorPos(&point); 88535c4bbdfSmrg wL = (GetKeyState(VK_LBUTTON) & 0x8000) ? MK_LBUTTON : 0; 88635c4bbdfSmrg wM = (GetKeyState(VK_MBUTTON) & 0x8000) ? MK_MBUTTON : 0; 88735c4bbdfSmrg wR = (GetKeyState(VK_RBUTTON) & 0x8000) ? MK_RBUTTON : 0; 88835c4bbdfSmrg wShift = (GetKeyState(VK_SHIFT) & 0x8000) ? MK_SHIFT : 0; 88935c4bbdfSmrg wCtrl = (GetKeyState(VK_CONTROL) & 0x8000) ? MK_CONTROL : 0; 89035c4bbdfSmrg lPos = MAKELPARAM(point.x, point.y); 89135c4bbdfSmrg if (g_fButton[0] && !wL) 89235c4bbdfSmrg PostMessage(hwnd, WM_LBUTTONUP, wCtrl | wM | wR | wShift, lPos); 89335c4bbdfSmrg if (g_fButton[1] && !wM) 89435c4bbdfSmrg PostMessage(hwnd, WM_MBUTTONUP, wCtrl | wL | wR | wShift, lPos); 89535c4bbdfSmrg if (g_fButton[2] && !wR) 89635c4bbdfSmrg PostMessage(hwnd, WM_RBUTTONUP, wCtrl | wL | wM | wShift, lPos); 89735c4bbdfSmrg } 89835c4bbdfSmrg } 89935c4bbdfSmrg return 0; 90005b261ecSmrg 90105b261ecSmrg case WM_CTLCOLORSCROLLBAR: 90235c4bbdfSmrg FatalError("winWindowProc - WM_CTLCOLORSCROLLBAR - We are not " 90335c4bbdfSmrg "supposed to get this message. Exiting.\n"); 90435c4bbdfSmrg return 0; 90505b261ecSmrg 90605b261ecSmrg case WM_MOUSEWHEEL: 90735c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 90835c4bbdfSmrg break; 90935c4bbdfSmrg#if CYGDEBUG 91035c4bbdfSmrg winDebug("winWindowProc - WM_MOUSEWHEEL\n"); 91135c4bbdfSmrg#endif 91235c4bbdfSmrg /* Button4 = WheelUp */ 91335c4bbdfSmrg /* Button5 = WheelDown */ 91435c4bbdfSmrg winMouseWheel(&(s_pScreenPriv->iDeltaZ), GET_WHEEL_DELTA_WPARAM(wParam), Button4, Button5); 91535c4bbdfSmrg break; 91635c4bbdfSmrg 91735c4bbdfSmrg case WM_MOUSEHWHEEL: 91835c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 91935c4bbdfSmrg break; 92005b261ecSmrg#if CYGDEBUG 92135c4bbdfSmrg winDebug("winWindowProc - WM_MOUSEHWHEEL\n"); 92205b261ecSmrg#endif 92335c4bbdfSmrg /* Button7 = TiltRight */ 92435c4bbdfSmrg /* Button6 = TiltLeft */ 92535c4bbdfSmrg winMouseWheel(&(s_pScreenPriv->iDeltaV), GET_WHEEL_DELTA_WPARAM(wParam), 7, 6); 92635c4bbdfSmrg break; 92705b261ecSmrg 92805b261ecSmrg case WM_SETFOCUS: 92935c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 93035c4bbdfSmrg break; 93105b261ecSmrg 93235c4bbdfSmrg /* Restore the state of all mode keys */ 93335c4bbdfSmrg winRestoreModeKeyStates(); 93405b261ecSmrg 93535c4bbdfSmrg /* Add the keyboard hook if possible */ 93635c4bbdfSmrg if (g_fKeyboardHookLL) 93735c4bbdfSmrg g_fKeyboardHookLL = winInstallKeyboardHookLL(); 93835c4bbdfSmrg return 0; 93905b261ecSmrg 94005b261ecSmrg case WM_KILLFOCUS: 94135c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 94235c4bbdfSmrg break; 94305b261ecSmrg 94435c4bbdfSmrg /* Release any pressed keys */ 94535c4bbdfSmrg winKeybdReleaseKeys(); 94605b261ecSmrg 94735c4bbdfSmrg /* Remove our keyboard hook if it is installed */ 94835c4bbdfSmrg winRemoveKeyboardHookLL(); 94935c4bbdfSmrg return 0; 95005b261ecSmrg 95105b261ecSmrg case WM_SYSKEYDOWN: 95205b261ecSmrg case WM_KEYDOWN: 95335c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 95435c4bbdfSmrg break; 95535c4bbdfSmrg 95635c4bbdfSmrg /* 95735c4bbdfSmrg * FIXME: Catching Alt-F4 like this is really terrible. This should 95835c4bbdfSmrg * be generalized to handle other Windows keyboard signals. Actually, 95935c4bbdfSmrg * the list keys to catch and the actions to perform when caught should 96035c4bbdfSmrg * be configurable; that way user's can customize the keys that they 96135c4bbdfSmrg * need to have passed through to their window manager or apps, or they 96235c4bbdfSmrg * can remap certain actions to new key codes that do not conflict 96335c4bbdfSmrg * with the X apps that they are using. Yeah, that'll take awhile. 96435c4bbdfSmrg */ 96535c4bbdfSmrg if ((s_pScreenInfo->fUseWinKillKey && wParam == VK_F4 96635c4bbdfSmrg && (GetKeyState(VK_MENU) & 0x8000)) 96735c4bbdfSmrg || (s_pScreenInfo->fUseUnixKillKey && wParam == VK_BACK 96835c4bbdfSmrg && (GetKeyState(VK_MENU) & 0x8000) 96935c4bbdfSmrg && (GetKeyState(VK_CONTROL) & 0x8000))) { 97035c4bbdfSmrg /* 97135c4bbdfSmrg * Better leave this message here, just in case some unsuspecting 97235c4bbdfSmrg * user enters Alt + F4 and is surprised when the application 97335c4bbdfSmrg * quits. 97435c4bbdfSmrg */ 97535c4bbdfSmrg ErrorF("winWindowProc - WM_*KEYDOWN - Closekey hit, quitting\n"); 97635c4bbdfSmrg 97735c4bbdfSmrg /* Display Exit dialog */ 97835c4bbdfSmrg winDisplayExitDialog(s_pScreenPriv); 97935c4bbdfSmrg return 0; 98035c4bbdfSmrg } 98135c4bbdfSmrg 98235c4bbdfSmrg /* 98335c4bbdfSmrg * Don't do anything for the Windows keys, as focus will soon 98435c4bbdfSmrg * be returned to Windows. We may be able to trap the Windows keys, 98535c4bbdfSmrg * but we should determine if that is desirable before doing so. 98635c4bbdfSmrg */ 98735c4bbdfSmrg if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL) 98805b261ecSmrg break; 98935c4bbdfSmrg 99035c4bbdfSmrg /* Discard fake Ctrl_L events that precede AltGR on non-US keyboards */ 99135c4bbdfSmrg if (winIsFakeCtrl_L(message, wParam, lParam)) 99205b261ecSmrg return 0; 99335c4bbdfSmrg 99435c4bbdfSmrg /* 99535c4bbdfSmrg * Discard presses generated from Windows auto-repeat 99635c4bbdfSmrg */ 99735c4bbdfSmrg if (lParam & (1 << 30)) { 99835c4bbdfSmrg switch (wParam) { 99935c4bbdfSmrg /* ago: Pressing LControl while RControl is pressed is 100035c4bbdfSmrg * Indicated as repeat. Fix this! 100135c4bbdfSmrg */ 100235c4bbdfSmrg case VK_CONTROL: 100335c4bbdfSmrg case VK_SHIFT: 100435c4bbdfSmrg if (winCheckKeyPressed(wParam, lParam)) 100535c4bbdfSmrg return 0; 100635c4bbdfSmrg break; 100735c4bbdfSmrg default: 100835c4bbdfSmrg return 0; 100935c4bbdfSmrg } 101005b261ecSmrg } 101135c4bbdfSmrg 101235c4bbdfSmrg /* Translate Windows key code to X scan code */ 101335c4bbdfSmrg iScanCode = winTranslateKey(wParam, lParam); 101435c4bbdfSmrg 101535c4bbdfSmrg /* Ignore repeats for CapsLock */ 101635c4bbdfSmrg if (wParam == VK_CAPITAL) 101735c4bbdfSmrg lParam = 1; 101835c4bbdfSmrg 101935c4bbdfSmrg /* Send the key event(s) */ 102035c4bbdfSmrg for (i = 0; i < LOWORD(lParam); ++i) 102135c4bbdfSmrg winSendKeyEvent(iScanCode, TRUE); 102235c4bbdfSmrg return 0; 102305b261ecSmrg 102405b261ecSmrg case WM_SYSKEYUP: 102505b261ecSmrg case WM_KEYUP: 102635c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 102735c4bbdfSmrg break; 102835c4bbdfSmrg 102935c4bbdfSmrg /* 103035c4bbdfSmrg * Don't do anything for the Windows keys, as focus will soon 103135c4bbdfSmrg * be returned to Windows. We may be able to trap the Windows keys, 103235c4bbdfSmrg * but we should determine if that is desirable before doing so. 103335c4bbdfSmrg */ 103435c4bbdfSmrg if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL) 103535c4bbdfSmrg break; 103635c4bbdfSmrg 103735c4bbdfSmrg /* Ignore the fake Ctrl_L that follows an AltGr release */ 103835c4bbdfSmrg if (winIsFakeCtrl_L(message, wParam, lParam)) 103935c4bbdfSmrg return 0; 104035c4bbdfSmrg 104135c4bbdfSmrg /* Enqueue a keyup event */ 104235c4bbdfSmrg iScanCode = winTranslateKey(wParam, lParam); 104335c4bbdfSmrg winSendKeyEvent(iScanCode, FALSE); 104435c4bbdfSmrg 104535c4bbdfSmrg /* Release all pressed shift keys */ 104635c4bbdfSmrg if (wParam == VK_SHIFT) 104735c4bbdfSmrg winFixShiftKeys(iScanCode); 104835c4bbdfSmrg return 0; 104905b261ecSmrg 105005b261ecSmrg case WM_ACTIVATE: 105135c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 105235c4bbdfSmrg break; 105335c4bbdfSmrg 105435c4bbdfSmrg /* TODO: Override display of window when we have a bad depth */ 105535c4bbdfSmrg if (LOWORD(wParam) != WA_INACTIVE && s_pScreenPriv->fBadDepth) { 105635c4bbdfSmrg ErrorF("winWindowProc - WM_ACTIVATE - Bad depth, trying " 105735c4bbdfSmrg "to override window activation\n"); 105835c4bbdfSmrg 105935c4bbdfSmrg /* Minimize the window */ 106035c4bbdfSmrg ShowWindow(hwnd, SW_MINIMIZE); 106135c4bbdfSmrg 106235c4bbdfSmrg /* Display dialog box */ 106335c4bbdfSmrg if (g_hDlgDepthChange != NULL) { 106435c4bbdfSmrg /* Make the existing dialog box active */ 106535c4bbdfSmrg SetActiveWindow(g_hDlgDepthChange); 106635c4bbdfSmrg } 106735c4bbdfSmrg else { 106835c4bbdfSmrg /* TODO: Recreate the dialog box and bring to the top */ 106935c4bbdfSmrg ShowWindow(g_hDlgDepthChange, SW_SHOWDEFAULT); 107035c4bbdfSmrg } 107135c4bbdfSmrg 107235c4bbdfSmrg /* Don't do any other processing of this message */ 107335c4bbdfSmrg return 0; 107435c4bbdfSmrg } 107505b261ecSmrg 107605b261ecSmrg#if CYGDEBUG 107735c4bbdfSmrg winDebug("winWindowProc - WM_ACTIVATE\n"); 107805b261ecSmrg#endif 107905b261ecSmrg 108035c4bbdfSmrg /* 108135c4bbdfSmrg * Focus is being changed to another window. 108235c4bbdfSmrg * The other window may or may not belong to 108335c4bbdfSmrg * our process. 108435c4bbdfSmrg */ 108535c4bbdfSmrg 108635c4bbdfSmrg /* Clear any lingering wheel delta */ 108735c4bbdfSmrg s_pScreenPriv->iDeltaZ = 0; 108835c4bbdfSmrg s_pScreenPriv->iDeltaV = 0; 108935c4bbdfSmrg 109035c4bbdfSmrg /* Reshow the Windows mouse cursor if we are being deactivated */ 109135c4bbdfSmrg if (g_fSoftwareCursor && LOWORD(wParam) == WA_INACTIVE && !g_fCursor) { 109235c4bbdfSmrg /* Show Windows cursor */ 109335c4bbdfSmrg g_fCursor = TRUE; 109435c4bbdfSmrg ShowCursor(TRUE); 109535c4bbdfSmrg } 109635c4bbdfSmrg return 0; 109705b261ecSmrg 109805b261ecSmrg case WM_ACTIVATEAPP: 109935c4bbdfSmrg if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) 110035c4bbdfSmrg break; 110105b261ecSmrg 110205b261ecSmrg#if CYGDEBUG || TRUE 110335c4bbdfSmrg winDebug("winWindowProc - WM_ACTIVATEAPP\n"); 110405b261ecSmrg#endif 110505b261ecSmrg 110635c4bbdfSmrg /* Activate or deactivate */ 110735c4bbdfSmrg s_pScreenPriv->fActive = wParam; 110805b261ecSmrg 110935c4bbdfSmrg /* Reshow the Windows mouse cursor if we are being deactivated */ 111035c4bbdfSmrg if (g_fSoftwareCursor && !s_pScreenPriv->fActive && !g_fCursor) { 111135c4bbdfSmrg /* Show Windows cursor */ 111235c4bbdfSmrg g_fCursor = TRUE; 111335c4bbdfSmrg ShowCursor(TRUE); 111435c4bbdfSmrg } 111505b261ecSmrg 111635c4bbdfSmrg /* Call engine specific screen activation/deactivation function */ 111735c4bbdfSmrg (*s_pScreenPriv->pwinActivateApp) (s_pScreen); 111805b261ecSmrg 111935c4bbdfSmrg return 0; 112005b261ecSmrg 112105b261ecSmrg case WM_COMMAND: 112235c4bbdfSmrg switch (LOWORD(wParam)) { 112335c4bbdfSmrg case ID_APP_EXIT: 112435c4bbdfSmrg /* Display Exit dialog */ 112535c4bbdfSmrg winDisplayExitDialog(s_pScreenPriv); 112635c4bbdfSmrg return 0; 112705b261ecSmrg 112835c4bbdfSmrg case ID_APP_HIDE_ROOT: 112935c4bbdfSmrg if (s_pScreenPriv->fRootWindowShown) 113035c4bbdfSmrg ShowWindow(s_pScreenPriv->hwndScreen, SW_HIDE); 113135c4bbdfSmrg else 113235c4bbdfSmrg ShowWindow(s_pScreenPriv->hwndScreen, SW_SHOW); 113335c4bbdfSmrg s_pScreenPriv->fRootWindowShown = !s_pScreenPriv->fRootWindowShown; 113435c4bbdfSmrg return 0; 113535c4bbdfSmrg 113635c4bbdfSmrg case ID_APP_MONITOR_PRIMARY: 113735c4bbdfSmrg fPrimarySelection = !fPrimarySelection; 113835c4bbdfSmrg return 0; 113905b261ecSmrg 114035c4bbdfSmrg case ID_APP_ABOUT: 114135c4bbdfSmrg /* Display the About box */ 114235c4bbdfSmrg winDisplayAboutDialog(s_pScreenPriv); 114335c4bbdfSmrg return 0; 114405b261ecSmrg 114535c4bbdfSmrg default: 114635c4bbdfSmrg /* It's probably one of the custom menus... */ 11471b5d61b8Smrg if (HandleCustomWM_COMMAND(0, LOWORD(wParam), s_pScreenPriv)) 114835c4bbdfSmrg return 0; 114935c4bbdfSmrg } 115035c4bbdfSmrg break; 115105b261ecSmrg 115205b261ecSmrg case WM_GIVEUP: 115335c4bbdfSmrg /* Tell X that we are giving up */ 115435c4bbdfSmrg if (s_pScreenInfo->fMultiWindow) 115535c4bbdfSmrg winDeinitMultiWindowWM(); 115635c4bbdfSmrg GiveUp(0); 115735c4bbdfSmrg return 0; 115805b261ecSmrg 115905b261ecSmrg case WM_CLOSE: 116035c4bbdfSmrg /* Display Exit dialog */ 116135c4bbdfSmrg winDisplayExitDialog(s_pScreenPriv); 116235c4bbdfSmrg return 0; 116305b261ecSmrg 116405b261ecSmrg case WM_SETCURSOR: 116535c4bbdfSmrg if (LOWORD(lParam) == HTCLIENT) { 116635c4bbdfSmrg if (!g_fSoftwareCursor) 116735c4bbdfSmrg SetCursor(s_pScreenPriv->cursor.handle); 116835c4bbdfSmrg return TRUE; 116935c4bbdfSmrg } 117035c4bbdfSmrg break; 117105b261ecSmrg 117205b261ecSmrg default: 1173ed6184dfSmrg if ((message == s_uTaskbarRestart) && !s_pScreenInfo->fNoTrayIcon) { 117435c4bbdfSmrg winInitNotifyIcon(s_pScreenPriv); 117535c4bbdfSmrg } 117635c4bbdfSmrg break; 117705b261ecSmrg } 117805b261ecSmrg 117935c4bbdfSmrg return DefWindowProc(hwnd, message, wParam, lParam); 118005b261ecSmrg} 1181