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