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