winwndproc.c revision 9ace9065
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"
4505b261ecSmrg
4605b261ecSmrg/*
4705b261ecSmrg * Global variables
4805b261ecSmrg */
4905b261ecSmrg
5005b261ecSmrgBool				g_fCursor = TRUE;
5105b261ecSmrgBool				g_fButton[3] = { FALSE, FALSE, FALSE };
5205b261ecSmrg
5305b261ecSmrg
5405b261ecSmrg/*
5505b261ecSmrg * Called by winWakeupHandler
5605b261ecSmrg * Processes current Windows message
5705b261ecSmrg */
5805b261ecSmrg
5905b261ecSmrgLRESULT CALLBACK
6005b261ecSmrgwinWindowProc (HWND hwnd, UINT message,
6105b261ecSmrg	       WPARAM wParam, LPARAM lParam)
6205b261ecSmrg{
6305b261ecSmrg  static winPrivScreenPtr	s_pScreenPriv = NULL;
6405b261ecSmrg  static winScreenInfo		*s_pScreenInfo = NULL;
6505b261ecSmrg  static ScreenPtr		s_pScreen = NULL;
6605b261ecSmrg  static HWND			s_hwndLastPrivates = NULL;
6705b261ecSmrg  static HINSTANCE		s_hInstance;
6805b261ecSmrg  static Bool			s_fTracking = FALSE;
6905b261ecSmrg  static unsigned long		s_ulServerGeneration = 0;
7005b261ecSmrg  static UINT			s_uTaskbarRestart = 0;
7105b261ecSmrg  int				iScanCode;
7205b261ecSmrg  int				i;
7305b261ecSmrg
7405b261ecSmrg#if CYGDEBUG
7505b261ecSmrg  winDebugWin32Message("winWindowProc", hwnd, message, wParam, lParam);
7605b261ecSmrg#endif
7705b261ecSmrg
7805b261ecSmrg  /* Watch for server regeneration */
7905b261ecSmrg  if (g_ulServerGeneration != s_ulServerGeneration)
8005b261ecSmrg    {
8105b261ecSmrg      /* Store new server generation */
8205b261ecSmrg      s_ulServerGeneration = g_ulServerGeneration;
8305b261ecSmrg    }
8405b261ecSmrg
8505b261ecSmrg  /* Only retrieve new privates pointers if window handle is null or changed */
8605b261ecSmrg  if ((s_pScreenPriv == NULL || hwnd != s_hwndLastPrivates)
8705b261ecSmrg      && (s_pScreenPriv = GetProp (hwnd, WIN_SCR_PROP)) != NULL)
8805b261ecSmrg    {
8905b261ecSmrg#if CYGDEBUG
9005b261ecSmrg      winDebug ("winWindowProc - Setting privates handle\n");
9105b261ecSmrg#endif
9205b261ecSmrg      s_pScreenInfo = s_pScreenPriv->pScreenInfo;
9305b261ecSmrg      s_pScreen = s_pScreenInfo->pScreen;
9405b261ecSmrg      s_hwndLastPrivates = hwnd;
9505b261ecSmrg    }
9605b261ecSmrg  else if (s_pScreenPriv == NULL)
9705b261ecSmrg    {
9805b261ecSmrg      /* For safety, handle case that should never happen */
9905b261ecSmrg      s_pScreenInfo = NULL;
10005b261ecSmrg      s_pScreen = NULL;
10105b261ecSmrg      s_hwndLastPrivates = NULL;
10205b261ecSmrg    }
10305b261ecSmrg
10405b261ecSmrg  /* Branch on message type */
10505b261ecSmrg  switch (message)
10605b261ecSmrg    {
10705b261ecSmrg    case WM_TRAYICON:
10805b261ecSmrg      return winHandleIconMessage (hwnd, message, wParam, lParam,
10905b261ecSmrg				   s_pScreenPriv);
11005b261ecSmrg
11105b261ecSmrg    case WM_CREATE:
11205b261ecSmrg#if CYGDEBUG
11305b261ecSmrg      winDebug ("winWindowProc - WM_CREATE\n");
11405b261ecSmrg#endif
11505b261ecSmrg
11605b261ecSmrg      /*
11705b261ecSmrg       * Add a property to our display window that references
11805b261ecSmrg       * this screens' privates.
11905b261ecSmrg       *
12005b261ecSmrg       * This allows the window procedure to refer to the
12105b261ecSmrg       * appropriate window DC and shadow DC for the window that
12205b261ecSmrg       * it is processing.  We use this to repaint exposed
12305b261ecSmrg       * areas of our display window.
12405b261ecSmrg       */
12505b261ecSmrg      s_pScreenPriv = ((LPCREATESTRUCT) lParam)->lpCreateParams;
12605b261ecSmrg      s_hInstance = ((LPCREATESTRUCT) lParam)->hInstance;
12705b261ecSmrg      s_pScreenInfo = s_pScreenPriv->pScreenInfo;
12805b261ecSmrg      s_pScreen = s_pScreenInfo->pScreen;
12905b261ecSmrg      s_hwndLastPrivates = hwnd;
13005b261ecSmrg      s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
13105b261ecSmrg      SetProp (hwnd, WIN_SCR_PROP, s_pScreenPriv);
13205b261ecSmrg
13305b261ecSmrg      /* Setup tray icon */
13405b261ecSmrg      if (!s_pScreenInfo->fNoTrayIcon)
13505b261ecSmrg	{
13605b261ecSmrg	  /*
13705b261ecSmrg	   * NOTE: The WM_CREATE message is processed before CreateWindowEx
13805b261ecSmrg	   * returns, so s_pScreenPriv->hwndScreen is invalid at this point.
13905b261ecSmrg	   * We go ahead and copy our hwnd parameter over top of the screen
14005b261ecSmrg	   * privates hwndScreen so that we have a valid value for
14105b261ecSmrg	   * that member.  Otherwise, the tray icon will disappear
14205b261ecSmrg	   * the first time you move the mouse over top of it.
14305b261ecSmrg	   */
14405b261ecSmrg
14505b261ecSmrg	  s_pScreenPriv->hwndScreen = hwnd;
14605b261ecSmrg
14705b261ecSmrg	  winInitNotifyIcon (s_pScreenPriv);
14805b261ecSmrg	}
14905b261ecSmrg      return 0;
15005b261ecSmrg
15105b261ecSmrg    case WM_DISPLAYCHANGE:
1529ace9065Smrg      /*
1539ace9065Smrg        WM_DISPLAYCHANGE seems to be sent when the monitor layout or
1549ace9065Smrg        any monitor's resolution or depth changes, but it's lParam and
1559ace9065Smrg        wParam always indicate the resolution and bpp for the primary
1569ace9065Smrg        monitor (so ignore that as we could be on any monitor...)
1579ace9065Smrg       */
1589ace9065Smrg
15905b261ecSmrg      /* We cannot handle a display mode change during initialization */
16005b261ecSmrg      if (s_pScreenInfo == NULL)
16105b261ecSmrg	FatalError ("winWindowProc - WM_DISPLAYCHANGE - The display "
16205b261ecSmrg		    "mode changed while we were intializing.  This is "
16305b261ecSmrg		    "very bad and unexpected.  Exiting.\n");
16405b261ecSmrg
16505b261ecSmrg      /*
16605b261ecSmrg       * We do not care about display changes with
16705b261ecSmrg       * fullscreen DirectDraw engines, because those engines set
16805b261ecSmrg       * their own mode when they become active.
16905b261ecSmrg       */
17005b261ecSmrg      if (s_pScreenInfo->fFullScreen
17105b261ecSmrg	  && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
17205b261ecSmrg	      || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
17305b261ecSmrg#ifdef XWIN_PRIMARYFB
17405b261ecSmrg	      || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD
17505b261ecSmrg#endif
17605b261ecSmrg	      ))
17705b261ecSmrg	{
17805b261ecSmrg	  break;
17905b261ecSmrg	}
18005b261ecSmrg
18105b261ecSmrg      ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new width: %d "
1829ace9065Smrg	      "new height: %d new bpp: %d\n",
1839ace9065Smrg	      LOWORD (lParam), HIWORD (lParam), wParam);
18405b261ecSmrg
18505b261ecSmrg      /*
18605b261ecSmrg       * Check for a disruptive change in depth.
18705b261ecSmrg       * We can only display a message for a disruptive depth change,
18805b261ecSmrg       * we cannot do anything to correct the situation.
18905b261ecSmrg       */
1909ace9065Smrg      /*
1919ace9065Smrg        XXX: maybe we need to check if GetSystemMetrics(SM_SAMEDISPLAYFORMAT)
1929ace9065Smrg        has changed as well...
1939ace9065Smrg      */
1949ace9065Smrg      if (s_pScreenInfo->dwBPP != GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL))
1959ace9065Smrg        {
1969ace9065Smrg          if ((s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
1979ace9065Smrg               || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
19805b261ecSmrg#ifdef XWIN_PRIMARYFB
1999ace9065Smrg               || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD
20005b261ecSmrg#endif
2019ace9065Smrg               ))
2029ace9065Smrg            {
2039ace9065Smrg              /* Cannot display the visual until the depth is restored */
2049ace9065Smrg              ErrorF ("winWindowProc - Disruptive change in depth\n");
2059ace9065Smrg
2069ace9065Smrg              /* Display depth change dialog */
2079ace9065Smrg              winDisplayDepthChangeDialog (s_pScreenPriv);
2089ace9065Smrg
2099ace9065Smrg              /* Flag that we have an invalid screen depth */
2109ace9065Smrg              s_pScreenPriv->fBadDepth = TRUE;
2119ace9065Smrg
2129ace9065Smrg              /* Minimize the display window */
2139ace9065Smrg              ShowWindow (hwnd, SW_MINIMIZE);
2149ace9065Smrg            }
2159ace9065Smrg          else
2169ace9065Smrg            {
2179ace9065Smrg              /* For GDI, performance may suffer until original depth is restored */
2189ace9065Smrg              ErrorF ("winWindowProc - Performance may be non-optimal after change in depth\n");
2199ace9065Smrg            }
2209ace9065Smrg        }
22105b261ecSmrg      else
2229ace9065Smrg        {
2239ace9065Smrg          /* Flag that we have a valid screen depth */
2249ace9065Smrg          s_pScreenPriv->fBadDepth = FALSE;
2259ace9065Smrg        }
2269ace9065Smrg
22705b261ecSmrg      /*
2289ace9065Smrg        If we could cheaply check if this WM_DISPLAYCHANGE change
2299ace9065Smrg        affects the monitor(s) which this X screen is displayed on
2309ace9065Smrg        then we should do so here.  For the moment, assume it does.
2319ace9065Smrg        (this is probably usually the case so that might be an
2329ace9065Smrg        overoptimization)
2339ace9065Smrg      */
23405b261ecSmrg	{
23505b261ecSmrg	  /*
2369ace9065Smrg             In rootless modes which are monitor or virtual desktop size
2379ace9065Smrg             use RandR to resize the X screen
2389ace9065Smrg          */
2399ace9065Smrg          if ((!s_pScreenInfo->fUserGaveHeightAndWidth) &&
2409ace9065Smrg              (s_pScreenInfo->iResizeMode == resizeWithRandr) &&
2419ace9065Smrg              (FALSE
2429ace9065Smrg#ifdef XWIN_MULTIWINDOWEXTWM
2439ace9065Smrg               || s_pScreenInfo->fMWExtWM
24405b261ecSmrg#endif
2459ace9065Smrg               || s_pScreenInfo->fRootless
2469ace9065Smrg#ifdef XWIN_MULTIWINDOW
2479ace9065Smrg               || s_pScreenInfo->fMultiWindow
24805b261ecSmrg#endif
2499ace9065Smrg               ))
25005b261ecSmrg	    {
2519ace9065Smrg              DWORD dwWidth, dwHeight;
2529ace9065Smrg
2539ace9065Smrg              if (s_pScreenInfo->fMultipleMonitors)
2549ace9065Smrg                {
2559ace9065Smrg                  /* resize to new virtual desktop size */
2569ace9065Smrg                  dwWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
2579ace9065Smrg                  dwHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
2589ace9065Smrg                }
2599ace9065Smrg              else
2609ace9065Smrg                {
2619ace9065Smrg                  /* resize to new size of specified monitor */
2629ace9065Smrg                  struct GetMonitorInfoData data;
2639ace9065Smrg                  if (QueryMonitor(s_pScreenInfo->iMonitor, &data))
2649ace9065Smrg                    {
2659ace9065Smrg                      if (data.bMonitorSpecifiedExists == TRUE)
2669ace9065Smrg                        {
2679ace9065Smrg                          dwWidth = data.monitorWidth;
2689ace9065Smrg                          dwHeight = data.monitorHeight;
2699ace9065Smrg                          /*
2709ace9065Smrg                             XXX: monitor may have changed position,
2719ace9065Smrg                             so we might need to update xinerama data
2729ace9065Smrg                          */
2739ace9065Smrg                        }
2749ace9065Smrg                      else
2759ace9065Smrg                        {
2769ace9065Smrg                          ErrorF ("Monitor number %d no longer exists!\n", s_pScreenInfo->iMonitor);
2779ace9065Smrg                        }
2789ace9065Smrg                    }
2799ace9065Smrg                }
2809ace9065Smrg
2819ace9065Smrg              /*
2829ace9065Smrg                XXX: probably a small bug here: we don't compute the work area
2839ace9065Smrg                and allow for task bar
2849ace9065Smrg
2859ace9065Smrg                XXX: generally, we don't allow for the task bar being moved after
2869ace9065Smrg                the server is started
2879ace9065Smrg               */
2889ace9065Smrg
2899ace9065Smrg              /* Set screen size to match new size, if it is different to current */
2909ace9065Smrg              if ((s_pScreenInfo->dwWidth != dwWidth) ||
2919ace9065Smrg                  (s_pScreenInfo->dwHeight != dwHeight))
2929ace9065Smrg                {
2939ace9065Smrg                  winDoRandRScreenSetSize(s_pScreen,
2949ace9065Smrg                                          dwWidth,
2959ace9065Smrg                                          dwHeight,
2969ace9065Smrg                                          (dwWidth * 25.4) / monitorResolution,
2979ace9065Smrg                                          (dwHeight * 25.4) / monitorResolution);
2989ace9065Smrg                }
29905b261ecSmrg	    }
3009ace9065Smrg          else
3019ace9065Smrg            {
3029ace9065Smrg              /*
3039ace9065Smrg               * We can simply recreate the same-sized primary surface when
3049ace9065Smrg               * the display dimensions change.
3059ace9065Smrg               */
3069ace9065Smrg
3079ace9065Smrg              /*
3089ace9065Smrg               * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface
3099ace9065Smrg               * and CreatePrimarySurface function pointers to point
3109ace9065Smrg               * to the no operation function, NoopDDA.  This allows us
3119ace9065Smrg               * to blindly call these functions, even if they are not
3129ace9065Smrg               * relevant to the current engine (e.g., Shadow GDI).
3139ace9065Smrg               */
3149ace9065Smrg
3159ace9065Smrg              winDebug ("winWindowProc - WM_DISPLAYCHANGE - Releasing and recreating primary surface\n");
3169ace9065Smrg
3179ace9065Smrg              /* Release the old primary surface */
3189ace9065Smrg              (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen);
3199ace9065Smrg
3209ace9065Smrg              /* Create the new primary surface */
3219ace9065Smrg              (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen);
3229ace9065Smrg            }
32305b261ecSmrg	}
32405b261ecSmrg
32505b261ecSmrg      break;
32605b261ecSmrg
32705b261ecSmrg    case WM_SIZE:
32805b261ecSmrg      {
32905b261ecSmrg	SCROLLINFO		si;
33005b261ecSmrg	RECT			rcWindow;
33105b261ecSmrg	int			iWidth, iHeight;
33205b261ecSmrg
33305b261ecSmrg#if CYGDEBUG
33405b261ecSmrg	winDebug ("winWindowProc - WM_SIZE\n");
33505b261ecSmrg#endif
33605b261ecSmrg
3379ace9065Smrg	/* Break if we do not allow resizing */
3389ace9065Smrg	if ((s_pScreenInfo->iResizeMode == notAllowed)
33905b261ecSmrg	    || !s_pScreenInfo->fDecoration
34005b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
34105b261ecSmrg	    || s_pScreenInfo->fMWExtWM
34205b261ecSmrg#endif
34305b261ecSmrg	    || s_pScreenInfo->fRootless
34405b261ecSmrg#ifdef XWIN_MULTIWINDOW
34505b261ecSmrg	    || s_pScreenInfo->fMultiWindow
34605b261ecSmrg#endif
34705b261ecSmrg	    || s_pScreenInfo->fFullScreen)
34805b261ecSmrg	  break;
34905b261ecSmrg
35005b261ecSmrg	/* No need to resize if we get minimized */
35105b261ecSmrg	if (wParam == SIZE_MINIMIZED)
35205b261ecSmrg	  return 0;
35305b261ecSmrg
3549ace9065Smrg        ErrorF ("winWindowProc - WM_SIZE - new client area w: %d h: %d\n",
3559ace9065Smrg                LOWORD (lParam), HIWORD (lParam));
3569ace9065Smrg
3579ace9065Smrg        if (s_pScreenInfo->iResizeMode == resizeWithRandr)
3589ace9065Smrg          {
3599ace9065Smrg            /* Actual resizing is done on WM_EXITSIZEMOVE */
3609ace9065Smrg            return 0;
3619ace9065Smrg          }
3629ace9065Smrg
3639ace9065Smrg        /* Otherwise iResizeMode == resizeWithScrollbars */
3649ace9065Smrg
36505b261ecSmrg	/*
36605b261ecSmrg	 * Get the size of the whole window, including client area,
36705b261ecSmrg	 * scrollbars, and non-client area decorations (caption, borders).
36805b261ecSmrg	 * We do this because we need to check if the client area
36905b261ecSmrg	 * without scrollbars is large enough to display the whole visual.
37005b261ecSmrg	 * The new client area size passed by lParam already subtracts
37105b261ecSmrg	 * the size of the scrollbars if they are currently displayed.
37205b261ecSmrg	 * So checking is LOWORD(lParam) == visual_width and
37305b261ecSmrg	 * HIWORD(lParam) == visual_height will never tell us to hide
37405b261ecSmrg	 * the scrollbars because the client area would always be too small.
37505b261ecSmrg	 * GetClientRect returns the same sizes given by lParam, so we
37605b261ecSmrg	 * cannot use GetClientRect either.
37705b261ecSmrg	 */
37805b261ecSmrg	GetWindowRect (hwnd, &rcWindow);
37905b261ecSmrg	iWidth = rcWindow.right - rcWindow.left;
38005b261ecSmrg	iHeight = rcWindow.bottom - rcWindow.top;
38105b261ecSmrg
38205b261ecSmrg	/* Subtract the frame size from the window size. */
38305b261ecSmrg	iWidth -= 2 * GetSystemMetrics (SM_CXSIZEFRAME);
38405b261ecSmrg	iHeight -= (2 * GetSystemMetrics (SM_CYSIZEFRAME)
38505b261ecSmrg		    + GetSystemMetrics (SM_CYCAPTION));
38605b261ecSmrg
38705b261ecSmrg	/*
38805b261ecSmrg	 * Update scrollbar page sizes.
38905b261ecSmrg	 * NOTE: If page size == range, then the scrollbar is
39005b261ecSmrg	 * automatically hidden.
39105b261ecSmrg	 */
39205b261ecSmrg
39305b261ecSmrg	/* Is the naked client area large enough to show the whole visual? */
39405b261ecSmrg	if (iWidth < s_pScreenInfo->dwWidth
39505b261ecSmrg	    || iHeight < s_pScreenInfo->dwHeight)
39605b261ecSmrg	  {
39705b261ecSmrg	    /* Client area too small to display visual, use scrollbars */
39805b261ecSmrg	    iWidth -= GetSystemMetrics (SM_CXVSCROLL);
39905b261ecSmrg	    iHeight -= GetSystemMetrics (SM_CYHSCROLL);
40005b261ecSmrg	  }
40105b261ecSmrg
40205b261ecSmrg	/* Set the horizontal scrollbar page size */
40305b261ecSmrg	si.cbSize = sizeof (si);
40405b261ecSmrg	si.fMask = SIF_PAGE | SIF_RANGE;
40505b261ecSmrg	si.nMin = 0;
40605b261ecSmrg	si.nMax = s_pScreenInfo->dwWidth - 1;
40705b261ecSmrg	si.nPage = iWidth;
40805b261ecSmrg	SetScrollInfo (hwnd, SB_HORZ, &si, TRUE);
40905b261ecSmrg
41005b261ecSmrg	/* Set the vertical scrollbar page size */
41105b261ecSmrg	si.cbSize = sizeof (si);
41205b261ecSmrg	si.fMask = SIF_PAGE | SIF_RANGE;
41305b261ecSmrg	si.nMin = 0;
41405b261ecSmrg	si.nMax = s_pScreenInfo->dwHeight - 1;
41505b261ecSmrg	si.nPage = iHeight;
41605b261ecSmrg	SetScrollInfo (hwnd, SB_VERT, &si, TRUE);
41705b261ecSmrg
41805b261ecSmrg	/*
41905b261ecSmrg	 * NOTE: Scrollbars may have moved if they were at the
42005b261ecSmrg	 * far right/bottom, so we query their current position.
42105b261ecSmrg	 */
42205b261ecSmrg
42305b261ecSmrg	/* Get the horizontal scrollbar position and set the offset */
42405b261ecSmrg	si.cbSize = sizeof (si);
42505b261ecSmrg	si.fMask = SIF_POS;
42605b261ecSmrg	GetScrollInfo (hwnd, SB_HORZ, &si);
42705b261ecSmrg	s_pScreenInfo->dwXOffset = -si.nPos;
42805b261ecSmrg
42905b261ecSmrg	/* Get the vertical scrollbar position and set the offset */
43005b261ecSmrg	si.cbSize = sizeof (si);
43105b261ecSmrg	si.fMask = SIF_POS;
43205b261ecSmrg	GetScrollInfo (hwnd, SB_VERT, &si);
43305b261ecSmrg	s_pScreenInfo->dwYOffset = -si.nPos;
43405b261ecSmrg      }
43505b261ecSmrg      return 0;
43605b261ecSmrg
4379ace9065Smrg    case WM_ENTERSIZEMOVE:
4389ace9065Smrg      ErrorF("winWindowProc - WM_ENTERSIZEMOVE\n");
4399ace9065Smrg      break;
4409ace9065Smrg
4419ace9065Smrg    case WM_EXITSIZEMOVE:
4429ace9065Smrg      ErrorF("winWindowProc - WM_EXITSIZEMOVE\n");
4439ace9065Smrg
4449ace9065Smrg      if (s_pScreenInfo->iResizeMode == resizeWithRandr)
4459ace9065Smrg        {
4469ace9065Smrg          /* Set screen size to match new client area, if it is different to current */
4479ace9065Smrg          RECT rcClient;
4489ace9065Smrg          DWORD dwWidth, dwHeight;
4499ace9065Smrg
4509ace9065Smrg          GetClientRect (hwnd, &rcClient);
4519ace9065Smrg          dwWidth = rcClient.right - rcClient.left;
4529ace9065Smrg          dwHeight = rcClient.bottom - rcClient.top;
4539ace9065Smrg
4549ace9065Smrg          if ((s_pScreenInfo->dwWidth != dwWidth) ||
4559ace9065Smrg              (s_pScreenInfo->dwHeight != dwHeight))
4569ace9065Smrg            {
4579ace9065Smrg              /* mm = dots * (25.4 mm / inch) / (dots / inch) */
4589ace9065Smrg              winDoRandRScreenSetSize(s_pScreen,
4599ace9065Smrg                                      dwWidth,
4609ace9065Smrg                                      dwHeight,
4619ace9065Smrg                                      (dwWidth * 25.4) / monitorResolution,
4629ace9065Smrg                                      (dwHeight * 25.4) / monitorResolution);
4639ace9065Smrg            }
4649ace9065Smrg        }
4659ace9065Smrg
4669ace9065Smrg      break;
4679ace9065Smrg
46805b261ecSmrg    case WM_VSCROLL:
46905b261ecSmrg      {
47005b261ecSmrg	SCROLLINFO		si;
47105b261ecSmrg	int			iVertPos;
47205b261ecSmrg
47305b261ecSmrg#if CYGDEBUG
47405b261ecSmrg	winDebug ("winWindowProc - WM_VSCROLL\n");
47505b261ecSmrg#endif
47605b261ecSmrg
47705b261ecSmrg	/* Get vertical scroll bar info */
47805b261ecSmrg	si.cbSize = sizeof (si);
47905b261ecSmrg	si.fMask = SIF_ALL;
48005b261ecSmrg	GetScrollInfo (hwnd, SB_VERT, &si);
48105b261ecSmrg
48205b261ecSmrg	/* Save the vertical position for comparison later */
48305b261ecSmrg	iVertPos = si.nPos;
48405b261ecSmrg
48505b261ecSmrg	/*
48605b261ecSmrg	 * Don't forget:
48705b261ecSmrg	 * moving the scrollbar to the DOWN, scroll the content UP
48805b261ecSmrg	 */
48905b261ecSmrg	switch (LOWORD(wParam))
49005b261ecSmrg	  {
49105b261ecSmrg	  case SB_TOP:
49205b261ecSmrg	    si.nPos = si.nMin;
49305b261ecSmrg	    break;
49405b261ecSmrg
49505b261ecSmrg	  case SB_BOTTOM:
49605b261ecSmrg	    si.nPos = si.nMax - si.nPage + 1;
49705b261ecSmrg	    break;
49805b261ecSmrg
49905b261ecSmrg	  case SB_LINEUP:
50005b261ecSmrg	    si.nPos -= 1;
50105b261ecSmrg	    break;
50205b261ecSmrg
50305b261ecSmrg	  case SB_LINEDOWN:
50405b261ecSmrg	    si.nPos += 1;
50505b261ecSmrg	    break;
50605b261ecSmrg
50705b261ecSmrg	  case SB_PAGEUP:
50805b261ecSmrg	    si.nPos -= si.nPage;
50905b261ecSmrg	    break;
51005b261ecSmrg
51105b261ecSmrg	  case SB_PAGEDOWN:
51205b261ecSmrg	    si.nPos += si.nPage;
51305b261ecSmrg	    break;
51405b261ecSmrg
51505b261ecSmrg	  case SB_THUMBTRACK:
51605b261ecSmrg	    si.nPos = si.nTrackPos;
51705b261ecSmrg	    break;
51805b261ecSmrg
51905b261ecSmrg	  default:
52005b261ecSmrg	    break;
52105b261ecSmrg	  }
52205b261ecSmrg
52305b261ecSmrg	/*
52405b261ecSmrg	 * We retrieve the position after setting it,
52505b261ecSmrg	 * because Windows may adjust it.
52605b261ecSmrg	 */
52705b261ecSmrg	si.fMask = SIF_POS;
52805b261ecSmrg	SetScrollInfo (hwnd, SB_VERT, &si, TRUE);
52905b261ecSmrg	GetScrollInfo (hwnd, SB_VERT, &si);
53005b261ecSmrg
53105b261ecSmrg	/* Scroll the window if the position has changed */
53205b261ecSmrg	if (si.nPos != iVertPos)
53305b261ecSmrg	  {
53405b261ecSmrg	    /* Save the new offset for bit block transfers, etc. */
53505b261ecSmrg	    s_pScreenInfo->dwYOffset = -si.nPos;
53605b261ecSmrg
53705b261ecSmrg	    /* Change displayed region in the window */
53805b261ecSmrg	    ScrollWindowEx (hwnd,
53905b261ecSmrg			    0,
54005b261ecSmrg			    iVertPos - si.nPos,
54105b261ecSmrg			    NULL,
54205b261ecSmrg			    NULL,
54305b261ecSmrg			    NULL,
54405b261ecSmrg			    NULL,
54505b261ecSmrg			    SW_INVALIDATE);
54605b261ecSmrg
54705b261ecSmrg	    /* Redraw the window contents */
54805b261ecSmrg	    UpdateWindow (hwnd);
54905b261ecSmrg	  }
55005b261ecSmrg      }
55105b261ecSmrg      return 0;
55205b261ecSmrg
55305b261ecSmrg    case WM_HSCROLL:
55405b261ecSmrg      {
55505b261ecSmrg	SCROLLINFO		si;
55605b261ecSmrg	int			iHorzPos;
55705b261ecSmrg
55805b261ecSmrg#if CYGDEBUG
55905b261ecSmrg	winDebug ("winWindowProc - WM_HSCROLL\n");
56005b261ecSmrg#endif
56105b261ecSmrg
56205b261ecSmrg	/* Get horizontal scroll bar info */
56305b261ecSmrg	si.cbSize = sizeof (si);
56405b261ecSmrg	si.fMask = SIF_ALL;
56505b261ecSmrg	GetScrollInfo (hwnd, SB_HORZ, &si);
56605b261ecSmrg
56705b261ecSmrg	/* Save the horizontal position for comparison later */
56805b261ecSmrg	iHorzPos = si.nPos;
56905b261ecSmrg
57005b261ecSmrg	/*
57105b261ecSmrg	 * Don't forget:
57205b261ecSmrg	 * moving the scrollbar to the RIGHT, scroll the content LEFT
57305b261ecSmrg	 */
57405b261ecSmrg	switch (LOWORD(wParam))
57505b261ecSmrg	  {
57605b261ecSmrg	  case SB_LEFT:
57705b261ecSmrg	    si.nPos = si.nMin;
57805b261ecSmrg	    break;
57905b261ecSmrg
58005b261ecSmrg	  case SB_RIGHT:
58105b261ecSmrg	    si.nPos = si.nMax - si.nPage + 1;
58205b261ecSmrg	    break;
58305b261ecSmrg
58405b261ecSmrg	  case SB_LINELEFT:
58505b261ecSmrg	    si.nPos -= 1;
58605b261ecSmrg	    break;
58705b261ecSmrg
58805b261ecSmrg	  case SB_LINERIGHT:
58905b261ecSmrg	    si.nPos += 1;
59005b261ecSmrg	    break;
59105b261ecSmrg
59205b261ecSmrg	  case SB_PAGELEFT:
59305b261ecSmrg	    si.nPos -= si.nPage;
59405b261ecSmrg	    break;
59505b261ecSmrg
59605b261ecSmrg	  case SB_PAGERIGHT:
59705b261ecSmrg	    si.nPos += si.nPage;
59805b261ecSmrg	    break;
59905b261ecSmrg
60005b261ecSmrg	  case SB_THUMBTRACK:
60105b261ecSmrg	    si.nPos = si.nTrackPos;
60205b261ecSmrg	    break;
60305b261ecSmrg
60405b261ecSmrg	  default:
60505b261ecSmrg	    break;
60605b261ecSmrg	  }
60705b261ecSmrg
60805b261ecSmrg	/*
60905b261ecSmrg	 * We retrieve the position after setting it,
61005b261ecSmrg	 * because Windows may adjust it.
61105b261ecSmrg	 */
61205b261ecSmrg	si.fMask = SIF_POS;
61305b261ecSmrg	SetScrollInfo (hwnd, SB_HORZ, &si, TRUE);
61405b261ecSmrg	GetScrollInfo (hwnd, SB_HORZ, &si);
61505b261ecSmrg
61605b261ecSmrg	/* Scroll the window if the position has changed */
61705b261ecSmrg	if (si.nPos != iHorzPos)
61805b261ecSmrg	  {
61905b261ecSmrg	    /* Save the new offset for bit block transfers, etc. */
62005b261ecSmrg	    s_pScreenInfo->dwXOffset = -si.nPos;
62105b261ecSmrg
62205b261ecSmrg	    /* Change displayed region in the window */
62305b261ecSmrg	    ScrollWindowEx (hwnd,
62405b261ecSmrg			    iHorzPos - si.nPos,
62505b261ecSmrg			    0,
62605b261ecSmrg			    NULL,
62705b261ecSmrg			    NULL,
62805b261ecSmrg			    NULL,
62905b261ecSmrg			    NULL,
63005b261ecSmrg			    SW_INVALIDATE);
63105b261ecSmrg
63205b261ecSmrg	    /* Redraw the window contents */
63305b261ecSmrg	    UpdateWindow (hwnd);
63405b261ecSmrg	  }
63505b261ecSmrg      }
63605b261ecSmrg      return 0;
63705b261ecSmrg
63805b261ecSmrg    case WM_GETMINMAXINFO:
63905b261ecSmrg      {
64005b261ecSmrg	MINMAXINFO		*pMinMaxInfo = (MINMAXINFO *) lParam;
64105b261ecSmrg	int			iCaptionHeight;
64205b261ecSmrg	int			iBorderHeight, iBorderWidth;
64305b261ecSmrg
64405b261ecSmrg#if CYGDEBUG
64505b261ecSmrg	winDebug ("winWindowProc - WM_GETMINMAXINFO - pScreenInfo: %08x\n",
64605b261ecSmrg		s_pScreenInfo);
64705b261ecSmrg#endif
64805b261ecSmrg
64905b261ecSmrg	/* Can't do anything without screen info */
65005b261ecSmrg	if (s_pScreenInfo == NULL
6519ace9065Smrg	    || (s_pScreenInfo->iResizeMode != resizeWithScrollbars)
65205b261ecSmrg	    || s_pScreenInfo->fFullScreen
65305b261ecSmrg	    || !s_pScreenInfo->fDecoration
65405b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
65505b261ecSmrg	    || s_pScreenInfo->fMWExtWM
65605b261ecSmrg#endif
65705b261ecSmrg	    || s_pScreenInfo->fRootless
65805b261ecSmrg#ifdef XWIN_MULTIWINDOW
65905b261ecSmrg	    || s_pScreenInfo->fMultiWindow
66005b261ecSmrg#endif
66105b261ecSmrg	    )
66205b261ecSmrg	  break;
66305b261ecSmrg
66405b261ecSmrg	/*
66505b261ecSmrg	 * Here we can override the maximum tracking size, which
66605b261ecSmrg	 * is the largest size that can be assigned to our window
66705b261ecSmrg	 * via the sizing border.
66805b261ecSmrg	 */
66905b261ecSmrg
67005b261ecSmrg	/*
67105b261ecSmrg	 * FIXME: Do we only need to do this once, since our visual size
67205b261ecSmrg	 * does not change?  Does Windows store this value statically
67305b261ecSmrg	 * once we have set it once?
67405b261ecSmrg	 */
67505b261ecSmrg
67605b261ecSmrg	/* Get the border and caption sizes */
67705b261ecSmrg	iCaptionHeight = GetSystemMetrics (SM_CYCAPTION);
67805b261ecSmrg	iBorderWidth = 2 * GetSystemMetrics (SM_CXSIZEFRAME);
67905b261ecSmrg	iBorderHeight = 2 * GetSystemMetrics (SM_CYSIZEFRAME);
68005b261ecSmrg
68105b261ecSmrg	/* Allow the full visual to be displayed */
68205b261ecSmrg	pMinMaxInfo->ptMaxTrackSize.x
68305b261ecSmrg	  = s_pScreenInfo->dwWidth + iBorderWidth;
68405b261ecSmrg	pMinMaxInfo->ptMaxTrackSize.y
68505b261ecSmrg	  = s_pScreenInfo->dwHeight + iBorderHeight + iCaptionHeight;
68605b261ecSmrg      }
68705b261ecSmrg      return 0;
68805b261ecSmrg
68905b261ecSmrg    case WM_ERASEBKGND:
69005b261ecSmrg#if CYGDEBUG
69105b261ecSmrg      winDebug ("winWindowProc - WM_ERASEBKGND\n");
69205b261ecSmrg#endif
69305b261ecSmrg      /*
69405b261ecSmrg       * Pretend that we did erase the background but we don't care,
69505b261ecSmrg       * the application uses the full window estate. This avoids some
69605b261ecSmrg       * flickering when resizing.
69705b261ecSmrg       */
69805b261ecSmrg      return TRUE;
69905b261ecSmrg
70005b261ecSmrg    case WM_PAINT:
70105b261ecSmrg#if CYGDEBUG
70205b261ecSmrg      winDebug ("winWindowProc - WM_PAINT\n");
70305b261ecSmrg#endif
70405b261ecSmrg      /* Only paint if we have privates and the server is enabled */
70505b261ecSmrg      if (s_pScreenPriv == NULL
70605b261ecSmrg	  || !s_pScreenPriv->fEnabled
70705b261ecSmrg	  || (s_pScreenInfo->fFullScreen && !s_pScreenPriv->fActive)
70805b261ecSmrg	  || s_pScreenPriv->fBadDepth)
70905b261ecSmrg	{
71005b261ecSmrg	  /* We don't want to paint */
71105b261ecSmrg	  break;
71205b261ecSmrg	}
71305b261ecSmrg
71405b261ecSmrg      /* Break out here if we don't have a valid paint routine */
71505b261ecSmrg      if (s_pScreenPriv->pwinBltExposedRegions == NULL)
71605b261ecSmrg	break;
71705b261ecSmrg
71805b261ecSmrg      /* Call the engine dependent repainter */
71905b261ecSmrg      (*s_pScreenPriv->pwinBltExposedRegions) (s_pScreen);
72005b261ecSmrg      return 0;
72105b261ecSmrg
72205b261ecSmrg    case WM_PALETTECHANGED:
72305b261ecSmrg      {
72405b261ecSmrg#if CYGDEBUG
72505b261ecSmrg	winDebug ("winWindowProc - WM_PALETTECHANGED\n");
72605b261ecSmrg#endif
72705b261ecSmrg	/*
72805b261ecSmrg	 * Don't process if we don't have privates or a colormap,
72905b261ecSmrg	 * or if we have an invalid depth.
73005b261ecSmrg	 */
73105b261ecSmrg	if (s_pScreenPriv == NULL
73205b261ecSmrg	    || s_pScreenPriv->pcmapInstalled == NULL
73305b261ecSmrg	    || s_pScreenPriv->fBadDepth)
73405b261ecSmrg	  break;
73505b261ecSmrg
73605b261ecSmrg	/* Return if we caused the palette to change */
73705b261ecSmrg	if ((HWND) wParam == hwnd)
73805b261ecSmrg	  {
73905b261ecSmrg	    /* Redraw the screen */
74005b261ecSmrg	    (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen);
74105b261ecSmrg	    return 0;
74205b261ecSmrg	  }
74305b261ecSmrg
74405b261ecSmrg	/* Reinstall the windows palette */
74505b261ecSmrg	(*s_pScreenPriv->pwinRealizeInstalledPalette) (s_pScreen);
74605b261ecSmrg
74705b261ecSmrg	/* Redraw the screen */
74805b261ecSmrg	(*s_pScreenPriv->pwinRedrawScreen) (s_pScreen);
74905b261ecSmrg	return 0;
75005b261ecSmrg      }
75105b261ecSmrg
75205b261ecSmrg    case WM_MOUSEMOVE:
75305b261ecSmrg      /* We can't do anything without privates */
75405b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
75505b261ecSmrg	break;
75605b261ecSmrg
7576747b715Smrg      /* We can't do anything without g_pwinPointer */
7586747b715Smrg      if (g_pwinPointer == NULL)
7596747b715Smrg        break;
7606747b715Smrg
76105b261ecSmrg      /* Has the mouse pointer crossed screens? */
7626747b715Smrg      if (s_pScreen != miPointerGetScreen(g_pwinPointer))
7636747b715Smrg	miPointerSetScreen (g_pwinPointer, s_pScreenInfo->dwScreen,
76405b261ecSmrg			       GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset,
76505b261ecSmrg			       GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset);
76605b261ecSmrg
76705b261ecSmrg      /* Are we tracking yet? */
76805b261ecSmrg      if (!s_fTracking)
76905b261ecSmrg	{
77005b261ecSmrg	  TRACKMOUSEEVENT		tme;
77105b261ecSmrg
77205b261ecSmrg	  /* Setup data structure */
77305b261ecSmrg	  ZeroMemory (&tme, sizeof (tme));
77405b261ecSmrg	  tme.cbSize = sizeof (tme);
77505b261ecSmrg	  tme.dwFlags = TME_LEAVE;
77605b261ecSmrg	  tme.hwndTrack = hwnd;
77705b261ecSmrg
77805b261ecSmrg	  /* Call the tracking function */
77905b261ecSmrg	  if (!(*g_fpTrackMouseEvent) (&tme))
78005b261ecSmrg	    ErrorF ("winWindowProc - _TrackMouseEvent failed\n");
78105b261ecSmrg
78205b261ecSmrg	  /* Flag that we are tracking now */
78305b261ecSmrg	  s_fTracking = TRUE;
78405b261ecSmrg	}
78505b261ecSmrg
78605b261ecSmrg      /* Hide or show the Windows mouse cursor */
78705b261ecSmrg      if (g_fSoftwareCursor && g_fCursor && (s_pScreenPriv->fActive || s_pScreenInfo->fLessPointer))
78805b261ecSmrg	{
78905b261ecSmrg	  /* Hide Windows cursor */
79005b261ecSmrg	  g_fCursor = FALSE;
79105b261ecSmrg	  ShowCursor (FALSE);
79205b261ecSmrg	}
79305b261ecSmrg      else if (g_fSoftwareCursor && !g_fCursor && !s_pScreenPriv->fActive
79405b261ecSmrg	       && !s_pScreenInfo->fLessPointer)
79505b261ecSmrg	{
79605b261ecSmrg	  /* Show Windows cursor */
79705b261ecSmrg	  g_fCursor = TRUE;
79805b261ecSmrg	  ShowCursor (TRUE);
79905b261ecSmrg	}
80005b261ecSmrg
80105b261ecSmrg      /* Deliver absolute cursor position to X Server */
8026747b715Smrg      winEnqueueMotion(GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset,
8036747b715Smrg		       GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset);
80405b261ecSmrg      return 0;
80505b261ecSmrg
80605b261ecSmrg    case WM_NCMOUSEMOVE:
80705b261ecSmrg      /*
80805b261ecSmrg       * We break instead of returning 0 since we need to call
80905b261ecSmrg       * DefWindowProc to get the mouse cursor changes
81005b261ecSmrg       * and min/max/close button highlighting in Windows XP.
81105b261ecSmrg       * The Platform SDK says that you should return 0 if you
81205b261ecSmrg       * process this message, but it fails to mention that you
81305b261ecSmrg       * will give up any default functionality if you do return 0.
81405b261ecSmrg       */
81505b261ecSmrg
81605b261ecSmrg      /* We can't do anything without privates */
81705b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
81805b261ecSmrg	break;
81905b261ecSmrg
82005b261ecSmrg      /* Non-client mouse movement, show Windows cursor */
82105b261ecSmrg      if (g_fSoftwareCursor && !g_fCursor)
82205b261ecSmrg	{
82305b261ecSmrg	  g_fCursor = TRUE;
82405b261ecSmrg	  ShowCursor (TRUE);
82505b261ecSmrg	}
82605b261ecSmrg      break;
82705b261ecSmrg
82805b261ecSmrg    case WM_MOUSELEAVE:
82905b261ecSmrg      /* Mouse has left our client area */
83005b261ecSmrg
83105b261ecSmrg      /* Flag that we are no longer tracking */
83205b261ecSmrg      s_fTracking = FALSE;
83305b261ecSmrg
83405b261ecSmrg      /* Show the mouse cursor, if necessary */
83505b261ecSmrg      if (g_fSoftwareCursor && !g_fCursor)
83605b261ecSmrg	{
83705b261ecSmrg	  g_fCursor = TRUE;
83805b261ecSmrg	  ShowCursor (TRUE);
83905b261ecSmrg	}
84005b261ecSmrg      return 0;
84105b261ecSmrg
84205b261ecSmrg    case WM_LBUTTONDBLCLK:
84305b261ecSmrg    case WM_LBUTTONDOWN:
84405b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
84505b261ecSmrg	break;
84605b261ecSmrg      if (s_pScreenInfo->fRootless
84705b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
84805b261ecSmrg	  || s_pScreenInfo->fMWExtWM
84905b261ecSmrg#endif
85005b261ecSmrg	  )
85105b261ecSmrg	SetCapture (hwnd);
85205b261ecSmrg      return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam);
85305b261ecSmrg
85405b261ecSmrg    case WM_LBUTTONUP:
85505b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
85605b261ecSmrg	break;
85705b261ecSmrg      if (s_pScreenInfo->fRootless
85805b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
85905b261ecSmrg	  || s_pScreenInfo->fMWExtWM
86005b261ecSmrg#endif
86105b261ecSmrg	  )
86205b261ecSmrg	ReleaseCapture ();
86305b261ecSmrg      return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam);
86405b261ecSmrg
86505b261ecSmrg    case WM_MBUTTONDBLCLK:
86605b261ecSmrg    case WM_MBUTTONDOWN:
86705b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
86805b261ecSmrg	break;
86905b261ecSmrg      if (s_pScreenInfo->fRootless
87005b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
87105b261ecSmrg	  || s_pScreenInfo->fMWExtWM
87205b261ecSmrg#endif
87305b261ecSmrg	  )
87405b261ecSmrg	SetCapture (hwnd);
87505b261ecSmrg      return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam);
87605b261ecSmrg
87705b261ecSmrg    case WM_MBUTTONUP:
87805b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
87905b261ecSmrg	break;
88005b261ecSmrg      if (s_pScreenInfo->fRootless
88105b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
88205b261ecSmrg	  || s_pScreenInfo->fMWExtWM
88305b261ecSmrg#endif
88405b261ecSmrg	  )
88505b261ecSmrg	ReleaseCapture ();
88605b261ecSmrg      return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam);
88705b261ecSmrg
88805b261ecSmrg    case WM_RBUTTONDBLCLK:
88905b261ecSmrg    case WM_RBUTTONDOWN:
89005b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
89105b261ecSmrg	break;
89205b261ecSmrg      if (s_pScreenInfo->fRootless
89305b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
89405b261ecSmrg	  || s_pScreenInfo->fMWExtWM
89505b261ecSmrg#endif
89605b261ecSmrg	  )
89705b261ecSmrg	SetCapture (hwnd);
89805b261ecSmrg      return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam);
89905b261ecSmrg
90005b261ecSmrg    case WM_RBUTTONUP:
90105b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
90205b261ecSmrg	break;
90305b261ecSmrg      if (s_pScreenInfo->fRootless
90405b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
90505b261ecSmrg	  || s_pScreenInfo->fMWExtWM
90605b261ecSmrg#endif
90705b261ecSmrg	  )
90805b261ecSmrg	ReleaseCapture ();
90905b261ecSmrg      return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam);
91005b261ecSmrg
91105b261ecSmrg    case WM_XBUTTONDBLCLK:
91205b261ecSmrg    case WM_XBUTTONDOWN:
91305b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
91405b261ecSmrg	break;
91505b261ecSmrg      if (s_pScreenInfo->fRootless
91605b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
91705b261ecSmrg	  || s_pScreenInfo->fMWExtWM
91805b261ecSmrg#endif
91905b261ecSmrg	  )
92005b261ecSmrg	SetCapture (hwnd);
92105b261ecSmrg      return winMouseButtonsHandle (s_pScreen, ButtonPress, HIWORD(wParam) + 5, wParam);
92205b261ecSmrg    case WM_XBUTTONUP:
92305b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
92405b261ecSmrg	break;
92505b261ecSmrg      if (s_pScreenInfo->fRootless
92605b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
92705b261ecSmrg	  || s_pScreenInfo->fMWExtWM
92805b261ecSmrg#endif
92905b261ecSmrg	  )
93005b261ecSmrg	ReleaseCapture ();
93105b261ecSmrg      return winMouseButtonsHandle (s_pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam);
93205b261ecSmrg
93305b261ecSmrg    case WM_TIMER:
93405b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
93505b261ecSmrg	break;
93605b261ecSmrg
93705b261ecSmrg      /* Branch on the timer id */
93805b261ecSmrg      switch (wParam)
93905b261ecSmrg	{
94005b261ecSmrg	case WIN_E3B_TIMER_ID:
94105b261ecSmrg	  /* Send delayed button press */
94205b261ecSmrg	  winMouseButtonsSendEvent (ButtonPress,
94305b261ecSmrg				    s_pScreenPriv->iE3BCachedPress);
94405b261ecSmrg
94505b261ecSmrg	  /* Kill this timer */
94605b261ecSmrg	  KillTimer (s_pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID);
94705b261ecSmrg
94805b261ecSmrg	  /* Clear screen privates flags */
94905b261ecSmrg	  s_pScreenPriv->iE3BCachedPress = 0;
95005b261ecSmrg	  break;
95105b261ecSmrg
95205b261ecSmrg	case WIN_POLLING_MOUSE_TIMER_ID:
95305b261ecSmrg	  {
95405b261ecSmrg	    POINT		point;
95505b261ecSmrg	    WPARAM		wL, wM, wR, wShift, wCtrl;
95605b261ecSmrg	    LPARAM		lPos;
95705b261ecSmrg
95805b261ecSmrg	    /* Get the current position of the mouse cursor */
95905b261ecSmrg	    GetCursorPos (&point);
96005b261ecSmrg
96105b261ecSmrg	    /* Map from screen (-X, -Y) to root (0, 0) */
96205b261ecSmrg	    point.x -= GetSystemMetrics (SM_XVIRTUALSCREEN);
96305b261ecSmrg	    point.y -= GetSystemMetrics (SM_YVIRTUALSCREEN);
96405b261ecSmrg
96505b261ecSmrg	    /* Deliver absolute cursor position to X Server */
9666747b715Smrg	    winEnqueueMotion(point.x , point.y);
96705b261ecSmrg
96805b261ecSmrg	    /* Check if a button was released but we didn't see it */
96905b261ecSmrg	    GetCursorPos (&point);
97005b261ecSmrg	    wL = (GetKeyState (VK_LBUTTON) & 0x8000)?MK_LBUTTON:0;
97105b261ecSmrg	    wM = (GetKeyState (VK_MBUTTON) & 0x8000)?MK_MBUTTON:0;
97205b261ecSmrg	    wR = (GetKeyState (VK_RBUTTON) & 0x8000)?MK_RBUTTON:0;
97305b261ecSmrg	    wShift = (GetKeyState (VK_SHIFT) & 0x8000)?MK_SHIFT:0;
97405b261ecSmrg	    wCtrl = (GetKeyState (VK_CONTROL) & 0x8000)?MK_CONTROL:0;
97505b261ecSmrg	    lPos = MAKELPARAM(point.x, point.y);
97605b261ecSmrg	    if (g_fButton[0] & !wL)
97705b261ecSmrg	    PostMessage (hwnd, WM_LBUTTONUP, wCtrl|wM|wR|wShift, lPos);
97805b261ecSmrg	    if (g_fButton[1] & !wM)
97905b261ecSmrg	      PostMessage (hwnd, WM_MBUTTONUP, wCtrl|wL|wR|wShift, lPos);
98005b261ecSmrg	    if (g_fButton[2] & !wR)
98105b261ecSmrg	      PostMessage (hwnd, WM_RBUTTONUP, wCtrl|wL|wM|wShift, lPos);
98205b261ecSmrg	  }
98305b261ecSmrg	}
98405b261ecSmrg      return 0;
98505b261ecSmrg
98605b261ecSmrg    case WM_CTLCOLORSCROLLBAR:
98705b261ecSmrg      FatalError ("winWindowProc - WM_CTLCOLORSCROLLBAR - We are not "
98805b261ecSmrg		  "supposed to get this message.  Exiting.\n");
98905b261ecSmrg      return 0;
99005b261ecSmrg
99105b261ecSmrg    case WM_MOUSEWHEEL:
99205b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
99305b261ecSmrg	break;
99405b261ecSmrg#if CYGDEBUG
99505b261ecSmrg      winDebug ("winWindowProc - WM_MOUSEWHEEL\n");
99605b261ecSmrg#endif
99705b261ecSmrg      winMouseWheel (s_pScreen, GET_WHEEL_DELTA_WPARAM(wParam));
99805b261ecSmrg      break;
99905b261ecSmrg
100005b261ecSmrg    case WM_SETFOCUS:
100105b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
100205b261ecSmrg	break;
100305b261ecSmrg
100405b261ecSmrg      /* Restore the state of all mode keys */
100505b261ecSmrg      winRestoreModeKeyStates ();
100605b261ecSmrg
100705b261ecSmrg      /* Add the keyboard hook if possible */
100805b261ecSmrg      if (g_fKeyboardHookLL)
100905b261ecSmrg	g_fKeyboardHookLL = winInstallKeyboardHookLL ();
101005b261ecSmrg      return 0;
101105b261ecSmrg
101205b261ecSmrg    case WM_KILLFOCUS:
101305b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
101405b261ecSmrg	break;
101505b261ecSmrg
101605b261ecSmrg      /* Release any pressed keys */
101705b261ecSmrg      winKeybdReleaseKeys ();
101805b261ecSmrg
101905b261ecSmrg      /* Remove our keyboard hook if it is installed */
102005b261ecSmrg      winRemoveKeyboardHookLL ();
102105b261ecSmrg      return 0;
102205b261ecSmrg
102305b261ecSmrg    case WM_SYSKEYDOWN:
102405b261ecSmrg    case WM_KEYDOWN:
102505b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
102605b261ecSmrg	break;
102705b261ecSmrg
102805b261ecSmrg      /*
102905b261ecSmrg       * FIXME: Catching Alt-F4 like this is really terrible.  This should
103005b261ecSmrg       * be generalized to handle other Windows keyboard signals.  Actually,
103105b261ecSmrg       * the list keys to catch and the actions to perform when caught should
103205b261ecSmrg       * be configurable; that way user's can customize the keys that they
103305b261ecSmrg       * need to have passed through to their window manager or apps, or they
103405b261ecSmrg       * can remap certain actions to new key codes that do not conflict
103505b261ecSmrg       * with the X apps that they are using.  Yeah, that'll take awhile.
103605b261ecSmrg       */
103705b261ecSmrg      if ((s_pScreenInfo->fUseWinKillKey && wParam == VK_F4
103805b261ecSmrg	   && (GetKeyState (VK_MENU) & 0x8000))
103905b261ecSmrg	  || (s_pScreenInfo->fUseUnixKillKey && wParam == VK_BACK
104005b261ecSmrg	      && (GetKeyState (VK_MENU) & 0x8000)
104105b261ecSmrg	      && (GetKeyState (VK_CONTROL) & 0x8000)))
104205b261ecSmrg	{
104305b261ecSmrg	  /*
104405b261ecSmrg	   * Better leave this message here, just in case some unsuspecting
104505b261ecSmrg	   * user enters Alt + F4 and is surprised when the application
104605b261ecSmrg	   * quits.
104705b261ecSmrg	   */
104805b261ecSmrg	  ErrorF ("winWindowProc - WM_*KEYDOWN - Closekey hit, quitting\n");
104905b261ecSmrg
105005b261ecSmrg	  /* Display Exit dialog */
105105b261ecSmrg	  winDisplayExitDialog (s_pScreenPriv);
105205b261ecSmrg	  return 0;
105305b261ecSmrg	}
105405b261ecSmrg
105505b261ecSmrg      /*
105605b261ecSmrg       * Don't do anything for the Windows keys, as focus will soon
105705b261ecSmrg       * be returned to Windows.  We may be able to trap the Windows keys,
105805b261ecSmrg       * but we should determine if that is desirable before doing so.
105905b261ecSmrg       */
106005b261ecSmrg      if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL)
106105b261ecSmrg	break;
106205b261ecSmrg
106305b261ecSmrg      /*
106405b261ecSmrg       * Discard presses generated from Windows auto-repeat
106505b261ecSmrg       */
10666747b715Smrg      if (lParam & (1<<30))
106705b261ecSmrg      {
106805b261ecSmrg        switch (wParam)
106905b261ecSmrg        {
107005b261ecSmrg          /* ago: Pressing LControl while RControl is pressed is
107105b261ecSmrg           * Indicated as repeat. Fix this!
107205b261ecSmrg           */
107305b261ecSmrg          case VK_CONTROL:
107405b261ecSmrg          case VK_SHIFT:
107505b261ecSmrg            if (winCheckKeyPressed(wParam, lParam))
107605b261ecSmrg              return 0;
107705b261ecSmrg            break;
107805b261ecSmrg          default:
107905b261ecSmrg            return 0;
108005b261ecSmrg        }
108105b261ecSmrg      }
108205b261ecSmrg
108305b261ecSmrg      /* Discard fake Ctrl_L presses that precede AltGR on non-US keyboards */
108405b261ecSmrg      if (winIsFakeCtrl_L (message, wParam, lParam))
108505b261ecSmrg	return 0;
108605b261ecSmrg
108705b261ecSmrg      /* Translate Windows key code to X scan code */
108805b261ecSmrg      winTranslateKey (wParam, lParam, &iScanCode);
108905b261ecSmrg
109005b261ecSmrg      /* Ignore repeats for CapsLock */
109105b261ecSmrg      if (wParam == VK_CAPITAL)
109205b261ecSmrg	lParam = 1;
109305b261ecSmrg
109405b261ecSmrg      /* Send the key event(s) */
109505b261ecSmrg      for (i = 0; i < LOWORD(lParam); ++i)
109605b261ecSmrg	winSendKeyEvent (iScanCode, TRUE);
109705b261ecSmrg      return 0;
109805b261ecSmrg
109905b261ecSmrg    case WM_SYSKEYUP:
110005b261ecSmrg    case WM_KEYUP:
110105b261ecSmrg      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
110205b261ecSmrg	break;
110305b261ecSmrg
110405b261ecSmrg      /*
110505b261ecSmrg       * Don't do anything for the Windows keys, as focus will soon
110605b261ecSmrg       * be returned to Windows.  We may be able to trap the Windows keys,
110705b261ecSmrg       * but we should determine if that is desirable before doing so.
110805b261ecSmrg       */
110905b261ecSmrg      if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL)
111005b261ecSmrg	break;
111105b261ecSmrg
111205b261ecSmrg      /* Ignore the fake Ctrl_L that follows an AltGr release */
111305b261ecSmrg      if (winIsFakeCtrl_L (message, wParam, lParam))
111405b261ecSmrg	return 0;
111505b261ecSmrg
111605b261ecSmrg      /* Enqueue a keyup event */
111705b261ecSmrg      winTranslateKey (wParam, lParam, &iScanCode);
111805b261ecSmrg      winSendKeyEvent (iScanCode, FALSE);
111905b261ecSmrg
112005b261ecSmrg      /* Release all pressed shift keys */
112105b261ecSmrg      if (wParam == VK_SHIFT)
112205b261ecSmrg        winFixShiftKeys (iScanCode);
112305b261ecSmrg      return 0;
112405b261ecSmrg
112505b261ecSmrg    case WM_HOTKEY:
112605b261ecSmrg      if (s_pScreenPriv == NULL)
112705b261ecSmrg	break;
112805b261ecSmrg
112905b261ecSmrg      /* Call the engine-specific hot key handler */
113005b261ecSmrg      (*s_pScreenPriv->pwinHotKeyAltTab) (s_pScreen);
113105b261ecSmrg      return 0;
113205b261ecSmrg
113305b261ecSmrg    case WM_ACTIVATE:
113405b261ecSmrg      if (s_pScreenPriv == NULL
113505b261ecSmrg	  || s_pScreenInfo->fIgnoreInput)
113605b261ecSmrg	break;
113705b261ecSmrg
113805b261ecSmrg      /* TODO: Override display of window when we have a bad depth */
113905b261ecSmrg      if (LOWORD(wParam) != WA_INACTIVE && s_pScreenPriv->fBadDepth)
114005b261ecSmrg	{
114105b261ecSmrg	  ErrorF ("winWindowProc - WM_ACTIVATE - Bad depth, trying "
114205b261ecSmrg		  "to override window activation\n");
114305b261ecSmrg
114405b261ecSmrg	  /* Minimize the window */
114505b261ecSmrg	  ShowWindow (hwnd, SW_MINIMIZE);
114605b261ecSmrg
114705b261ecSmrg	  /* Display dialog box */
114805b261ecSmrg	  if (g_hDlgDepthChange != NULL)
114905b261ecSmrg	    {
115005b261ecSmrg	      /* Make the existing dialog box active */
115105b261ecSmrg	      SetActiveWindow (g_hDlgDepthChange);
115205b261ecSmrg	    }
115305b261ecSmrg	  else
115405b261ecSmrg	    {
115505b261ecSmrg	      /* TODO: Recreate the dialog box and bring to the top */
115605b261ecSmrg	      ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT);
115705b261ecSmrg	    }
115805b261ecSmrg
115905b261ecSmrg	  /* Don't do any other processing of this message */
116005b261ecSmrg	  return 0;
116105b261ecSmrg	}
116205b261ecSmrg
116305b261ecSmrg#if CYGDEBUG
116405b261ecSmrg      winDebug ("winWindowProc - WM_ACTIVATE\n");
116505b261ecSmrg#endif
116605b261ecSmrg
116705b261ecSmrg      /*
116805b261ecSmrg       * Focus is being changed to another window.
116905b261ecSmrg       * The other window may or may not belong to
117005b261ecSmrg       * our process.
117105b261ecSmrg       */
117205b261ecSmrg
117305b261ecSmrg      /* Clear any lingering wheel delta */
117405b261ecSmrg      s_pScreenPriv->iDeltaZ = 0;
117505b261ecSmrg
117605b261ecSmrg      /* Reshow the Windows mouse cursor if we are being deactivated */
117705b261ecSmrg      if (g_fSoftwareCursor && LOWORD(wParam) == WA_INACTIVE
117805b261ecSmrg	  && !g_fCursor)
117905b261ecSmrg	{
118005b261ecSmrg	  /* Show Windows cursor */
118105b261ecSmrg	  g_fCursor = TRUE;
118205b261ecSmrg	  ShowCursor (TRUE);
118305b261ecSmrg	}
118405b261ecSmrg      return 0;
118505b261ecSmrg
118605b261ecSmrg    case WM_ACTIVATEAPP:
118705b261ecSmrg      if (s_pScreenPriv == NULL
118805b261ecSmrg	  || s_pScreenInfo->fIgnoreInput)
118905b261ecSmrg	break;
119005b261ecSmrg
119105b261ecSmrg#if CYGDEBUG || TRUE
119205b261ecSmrg      winDebug ("winWindowProc - WM_ACTIVATEAPP\n");
119305b261ecSmrg#endif
119405b261ecSmrg
119505b261ecSmrg      /* Activate or deactivate */
119605b261ecSmrg      s_pScreenPriv->fActive = wParam;
119705b261ecSmrg
119805b261ecSmrg      /* Reshow the Windows mouse cursor if we are being deactivated */
119905b261ecSmrg      if (g_fSoftwareCursor && !s_pScreenPriv->fActive
120005b261ecSmrg	  && !g_fCursor)
120105b261ecSmrg	{
120205b261ecSmrg	  /* Show Windows cursor */
120305b261ecSmrg	  g_fCursor = TRUE;
120405b261ecSmrg	  ShowCursor (TRUE);
120505b261ecSmrg	}
120605b261ecSmrg
120705b261ecSmrg#ifdef XWIN_CLIPBOARD
120805b261ecSmrg      /* Make sure the clipboard chain is ok. */
120905b261ecSmrg      winFixClipboardChain ();
121005b261ecSmrg#endif
121105b261ecSmrg
121205b261ecSmrg      /* Call engine specific screen activation/deactivation function */
121305b261ecSmrg      (*s_pScreenPriv->pwinActivateApp) (s_pScreen);
121405b261ecSmrg
121505b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
121605b261ecSmrg      if (s_pScreenPriv->fActive)
121705b261ecSmrg	{
121805b261ecSmrg	  /* Restack all window unless using built-in wm. */
121905b261ecSmrg	  if (s_pScreenInfo->fInternalWM && s_pScreenInfo->fAnotherWMRunning)
122005b261ecSmrg	    winMWExtWMRestackWindows (s_pScreen);
122105b261ecSmrg	}
122205b261ecSmrg#endif
122305b261ecSmrg
122405b261ecSmrg      return 0;
122505b261ecSmrg
122605b261ecSmrg    case WM_COMMAND:
122705b261ecSmrg      switch (LOWORD (wParam))
122805b261ecSmrg	{
122905b261ecSmrg	case ID_APP_EXIT:
123005b261ecSmrg	  /* Display Exit dialog */
123105b261ecSmrg	  winDisplayExitDialog (s_pScreenPriv);
123205b261ecSmrg	  return 0;
123305b261ecSmrg
123405b261ecSmrg#ifdef XWIN_MULTIWINDOW
123505b261ecSmrg	case ID_APP_HIDE_ROOT:
123605b261ecSmrg	  if (s_pScreenPriv->fRootWindowShown)
123705b261ecSmrg	    ShowWindow (s_pScreenPriv->hwndScreen, SW_HIDE);
123805b261ecSmrg	  else
123905b261ecSmrg	    ShowWindow (s_pScreenPriv->hwndScreen, SW_SHOW);
124005b261ecSmrg	  s_pScreenPriv->fRootWindowShown = !s_pScreenPriv->fRootWindowShown;
124105b261ecSmrg	  return 0;
124205b261ecSmrg#endif
124305b261ecSmrg
124405b261ecSmrg	case ID_APP_ABOUT:
124505b261ecSmrg	  /* Display the About box */
124605b261ecSmrg	  winDisplayAboutDialog (s_pScreenPriv);
124705b261ecSmrg	  return 0;
124805b261ecSmrg
124905b261ecSmrg	default:
125005b261ecSmrg	  /* It's probably one of the custom menus... */
125105b261ecSmrg	  if (HandleCustomWM_COMMAND (0, LOWORD (wParam)))
125205b261ecSmrg	    return 0;
125305b261ecSmrg	}
125405b261ecSmrg      break;
125505b261ecSmrg
125605b261ecSmrg    case WM_ENDSESSION:
125705b261ecSmrg    case WM_GIVEUP:
125805b261ecSmrg      /* Tell X that we are giving up */
125905b261ecSmrg#ifdef XWIN_MULTIWINDOW
126005b261ecSmrg      if (s_pScreenInfo->fMultiWindow)
126105b261ecSmrg	winDeinitMultiWindowWM ();
126205b261ecSmrg#endif
126305b261ecSmrg      GiveUp (0);
126405b261ecSmrg      return 0;
126505b261ecSmrg
126605b261ecSmrg    case WM_CLOSE:
126705b261ecSmrg      /* Display Exit dialog */
126805b261ecSmrg      winDisplayExitDialog (s_pScreenPriv);
126905b261ecSmrg      return 0;
127005b261ecSmrg
127105b261ecSmrg    case WM_SETCURSOR:
127205b261ecSmrg      if (LOWORD(lParam) == HTCLIENT)
127305b261ecSmrg	{
127405b261ecSmrg	  if (!g_fSoftwareCursor) SetCursor (s_pScreenPriv->cursor.handle);
127505b261ecSmrg	  return TRUE;
127605b261ecSmrg	}
127705b261ecSmrg      break;
127805b261ecSmrg
127905b261ecSmrg#ifdef XWIN_MULTIWINDOWEXTWM
128005b261ecSmrg    case WM_MANAGE:
128105b261ecSmrg      ErrorF ("winWindowProc - WM_MANAGE\n");
128205b261ecSmrg      s_pScreenInfo->fAnotherWMRunning = FALSE;
128305b261ecSmrg
128405b261ecSmrg      if (s_pScreenInfo->fInternalWM)
128505b261ecSmrg	{
128605b261ecSmrg	  EnumThreadWindows (g_dwCurrentThreadID, winMWExtWMDecorateWindow, 0);
128705b261ecSmrg	  //RootlessRepositionWindows (s_pScreen);
128805b261ecSmrg	}
128905b261ecSmrg      break;
129005b261ecSmrg
129105b261ecSmrg    case WM_UNMANAGE:
129205b261ecSmrg      ErrorF ("winWindowProc - WM_UNMANAGE\n");
129305b261ecSmrg      s_pScreenInfo->fAnotherWMRunning = TRUE;
129405b261ecSmrg
129505b261ecSmrg      if (s_pScreenInfo->fInternalWM)
129605b261ecSmrg	{
129705b261ecSmrg	  EnumThreadWindows (g_dwCurrentThreadID, winMWExtWMDecorateWindow, 0);
129805b261ecSmrg	  winMWExtWMRestackWindows (s_pScreen);
129905b261ecSmrg	}
130005b261ecSmrg      break;
130105b261ecSmrg#endif
130205b261ecSmrg
130305b261ecSmrg    default:
130405b261ecSmrg      if(message == s_uTaskbarRestart)
130505b261ecSmrg	{
130605b261ecSmrg	  winInitNotifyIcon (s_pScreenPriv);
130705b261ecSmrg	}
130805b261ecSmrg      break;
130905b261ecSmrg    }
131005b261ecSmrg
131105b261ecSmrg  return DefWindowProc (hwnd, message, wParam, lParam);
131205b261ecSmrg}
1313