1340 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			1340 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
| /*
 | |
|  *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
 | |
|  *
 | |
|  *Permission is hereby granted, free of charge, to any person obtaining
 | |
|  * a copy of this software and associated documentation files (the
 | |
|  *"Software"), to deal in the Software without restriction, including
 | |
|  *without limitation the rights to use, copy, modify, merge, publish,
 | |
|  *distribute, sublicense, and/or sell copies of the Software, and to
 | |
|  *permit persons to whom the Software is furnished to do so, subject to
 | |
|  *the following conditions:
 | |
|  *
 | |
|  *The above copyright notice and this permission notice shall be
 | |
|  *included in all copies or substantial portions of the Software.
 | |
|  *
 | |
|  *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | |
|  *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | |
|  *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | |
|  *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
 | |
|  *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 | |
|  *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 | |
|  *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | |
|  *
 | |
|  *Except as contained in this notice, the name of the XFree86 Project
 | |
|  *shall not be used in advertising or otherwise to promote the sale, use
 | |
|  *or other dealings in this Software without prior written authorization
 | |
|  *from the XFree86 Project.
 | |
|  *
 | |
|  * Authors:	Kensuke Matsuzaki
 | |
|  *		Earle F. Philhower, III
 | |
|  *		Harold L Hunt II
 | |
|  */
 | |
| #ifdef HAVE_XWIN_CONFIG_H
 | |
| #include <xwin-config.h>
 | |
| #endif
 | |
| #include "win.h"
 | |
| #include <winuser.h>
 | |
| #define _WINDOWSWM_SERVER_
 | |
| #include <X11/extensions/windowswmstr.h>
 | |
| #include "dixevents.h"
 | |
| #include "propertyst.h"
 | |
| #include <X11/Xatom.h>
 | |
| #include "winmultiwindowclass.h"
 | |
| #include "winmsg.h"
 | |
| #include "inputstr.h"
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Constant defines
 | |
|  */
 | |
| 
 | |
| #define MOUSE_ACTIVATE_DEFAULT		TRUE
 | |
| #define RAISE_ON_CLICK_DEFAULT		FALSE
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Global variables
 | |
|  */
 | |
| 
 | |
| extern Bool			g_fNoConfigureWindow;
 | |
| extern Bool			g_fSoftwareCursor;
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Local globals
 | |
|  */
 | |
| 
 | |
| static UINT_PTR		g_uipMousePollingTimerID = 0;
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Local function
 | |
|  */
 | |
| 
 | |
| DEFINE_ATOM_HELPER(AtmWindowsWmRaiseOnClick, WINDOWSWM_RAISE_ON_CLICK)
 | |
| DEFINE_ATOM_HELPER(AtmWindowsWMMouseActivate, WINDOWSWM_MOUSE_ACTIVATE)
 | |
| /* DEFINE_ATOM_HELPER(AtmWindowsWMClientWindow, WINDOWSWM_CLIENT_WINDOW) */
 | |
| 
 | |
| /*
 | |
|  * ConstrainSize - Taken from TWM sources - Respects hints for sizing
 | |
|  */
 | |
| #define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) )
 | |
| static void
 | |
| ConstrainSize (WinXSizeHints hints, int *widthp, int *heightp)
 | |
| {
 | |
|   int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta;
 | |
|   int baseWidth, baseHeight;
 | |
|   int dwidth = *widthp, dheight = *heightp;
 | |
|   
 | |
|   if (hints.flags & PMinSize)
 | |
|     {
 | |
|       minWidth = hints.min_width;
 | |
|       minHeight = hints.min_height;
 | |
|     }
 | |
|   else if (hints.flags & PBaseSize)
 | |
|     {
 | |
|       minWidth = hints.base_width;
 | |
|       minHeight = hints.base_height;
 | |
|     }
 | |
|   else
 | |
|     minWidth = minHeight = 1;
 | |
|   
 | |
|   if (hints.flags & PBaseSize)
 | |
|     {
 | |
|       baseWidth = hints.base_width;
 | |
|       baseHeight = hints.base_height;
 | |
|     } 
 | |
|   else if (hints.flags & PMinSize)
 | |
|     {
 | |
|       baseWidth = hints.min_width;
 | |
|       baseHeight = hints.min_height;
 | |
|     }
 | |
|   else
 | |
|     baseWidth = baseHeight = 0;
 | |
| 
 | |
|   if (hints.flags & PMaxSize)
 | |
|     {
 | |
|       maxWidth = hints.max_width;
 | |
|       maxHeight = hints.max_height;
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       maxWidth = MAXINT;
 | |
|       maxHeight = MAXINT;
 | |
|     }
 | |
| 
 | |
|   if (hints.flags & PResizeInc)
 | |
|     {
 | |
|       xinc = hints.width_inc;
 | |
|       yinc = hints.height_inc;
 | |
|     }
 | |
|   else
 | |
|     xinc = yinc = 1;
 | |
| 
 | |
|   /*
 | |
|    * First, clamp to min and max values
 | |
|    */
 | |
|   if (dwidth < minWidth)
 | |
|     dwidth = minWidth;
 | |
|   if (dheight < minHeight)
 | |
|     dheight = minHeight;
 | |
| 
 | |
|   if (dwidth > maxWidth)
 | |
|     dwidth = maxWidth;
 | |
|   if (dheight > maxHeight)
 | |
|     dheight = maxHeight;
 | |
| 
 | |
|   /*
 | |
|    * Second, fit to base + N * inc
 | |
|    */
 | |
|   dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth;
 | |
|   dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight;
 | |
|   
 | |
|   /*
 | |
|    * Third, adjust for aspect ratio
 | |
|    */
 | |
| 
 | |
|   /*
 | |
|    * The math looks like this:
 | |
|    *
 | |
|    * minAspectX    dwidth     maxAspectX
 | |
|    * ---------- <= ------- <= ----------
 | |
|    * minAspectY    dheight    maxAspectY
 | |
|    *
 | |
|    * If that is multiplied out, then the width and height are
 | |
|    * invalid in the following situations:
 | |
|    *
 | |
|    * minAspectX * dheight > minAspectY * dwidth
 | |
|    * maxAspectX * dheight < maxAspectY * dwidth
 | |
|    * 
 | |
|    */
 | |
|   
 | |
|   if (hints.flags & PAspect)
 | |
|     {
 | |
|       if (hints.min_aspect.x * dheight > hints.min_aspect.y * dwidth)
 | |
|         {
 | |
| 	  delta = makemult(hints.min_aspect.x * dheight / hints.min_aspect.y - dwidth, xinc);
 | |
| 	  if (dwidth + delta <= maxWidth)
 | |
| 	    dwidth += delta;
 | |
| 	  else
 | |
|             {
 | |
| 	      delta = makemult(dheight - dwidth*hints.min_aspect.y/hints.min_aspect.x, yinc);
 | |
| 	      if (dheight - delta >= minHeight)
 | |
| 		dheight -= delta;
 | |
|             }
 | |
|         }
 | |
|       
 | |
|       if (hints.max_aspect.x * dheight < hints.max_aspect.y * dwidth)
 | |
|         {
 | |
| 	  delta = makemult(dwidth * hints.max_aspect.y / hints.max_aspect.x - dheight, yinc);
 | |
| 	  if (dheight + delta <= maxHeight)
 | |
| 	    dheight += delta;
 | |
| 	  else
 | |
|             {
 | |
| 	      delta = makemult(dwidth - hints.max_aspect.x*dheight/hints.max_aspect.y, xinc);
 | |
| 	      if (dwidth - delta >= minWidth)
 | |
| 		dwidth -= delta;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|   
 | |
|   /* Return computed values */
 | |
|   *widthp = dwidth;
 | |
|   *heightp = dheight;
 | |
| }
 | |
| #undef makemult
 | |
| 
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * ValidateSizing - Ensures size request respects hints
 | |
|  */
 | |
| static int
 | |
| ValidateSizing (HWND hwnd, WindowPtr pWin,
 | |
| 		WPARAM wParam, LPARAM lParam)
 | |
| {
 | |
|   WinXSizeHints sizeHints;
 | |
|   RECT *rect;
 | |
|   int iWidth, iHeight, iTopBorder;
 | |
|   POINT pt;
 | |
| 
 | |
|   /* Invalid input checking */
 | |
|   if (pWin==NULL || lParam==0)
 | |
|     {
 | |
|       ErrorF ("Invalid input checking\n");
 | |
|       return FALSE;
 | |
|     }
 | |
| 
 | |
|   /* No size hints, no checking */
 | |
|   if (!winMultiWindowGetWMNormalHints (pWin, &sizeHints))
 | |
|     {
 | |
|       ErrorF ("No size hints, no checking\n");
 | |
|       return FALSE;
 | |
|     }
 | |
|   
 | |
|   /* Avoid divide-by-zero */
 | |
|   if (sizeHints.flags & PResizeInc)
 | |
|     {
 | |
|       if (sizeHints.width_inc == 0) sizeHints.width_inc = 1;
 | |
|       if (sizeHints.height_inc == 0) sizeHints.height_inc = 1;
 | |
|     }
 | |
|   
 | |
|   rect = (RECT*)lParam;
 | |
|   
 | |
|   iWidth = rect->right - rect->left;
 | |
|   iHeight = rect->bottom - rect->top;
 | |
| 
 | |
|   /* Get title bar height, there must be an easier way?! */
 | |
|   pt.x = pt.y = 0;
 | |
|   ClientToScreen(hwnd, &pt);
 | |
|   iTopBorder = pt.y - rect->top;
 | |
|   
 | |
|   /* Now remove size of any borders */
 | |
|   iWidth -= 2 * GetSystemMetrics(SM_CXSIZEFRAME);
 | |
|   iHeight -= GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder;
 | |
| 
 | |
|   /* Constrain the size to legal values */
 | |
|   ConstrainSize (sizeHints, &iWidth, &iHeight);
 | |
| 
 | |
|   /* Add back the borders */
 | |
|   iWidth += 2 * GetSystemMetrics(SM_CXSIZEFRAME);
 | |
|   iHeight += GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder;
 | |
| 
 | |
|   /* Adjust size according to where we're dragging from */
 | |
|   switch(wParam) {
 | |
|   case WMSZ_TOP:
 | |
|   case WMSZ_TOPRIGHT:
 | |
|   case WMSZ_BOTTOM:
 | |
|   case WMSZ_BOTTOMRIGHT:
 | |
|   case WMSZ_RIGHT:
 | |
|     rect->right = rect->left + iWidth;
 | |
|     break;
 | |
|   default:
 | |
|     rect->left = rect->right - iWidth;
 | |
|     break;
 | |
|   }
 | |
|   switch(wParam) {
 | |
|   case WMSZ_BOTTOM:
 | |
|   case WMSZ_BOTTOMRIGHT:
 | |
|   case WMSZ_BOTTOMLEFT:
 | |
|   case WMSZ_RIGHT:
 | |
|   case WMSZ_LEFT:
 | |
|     rect->bottom = rect->top + iHeight;
 | |
|     break;
 | |
|   default:
 | |
|     rect->top = rect->bottom - iHeight;
 | |
|     break;
 | |
|   }
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * IsRaiseOnClick
 | |
|  */
 | |
| 
 | |
| static Bool
 | |
| IsRaiseOnClick (WindowPtr pWin)
 | |
| {
 | |
| 
 | |
|   struct _Window	*pwin;
 | |
|   struct _Property	*prop;  
 | |
|   /* XXX We're getting inputInfo.poniter here, but this might be really wrong.
 | |
|    * Which pointer's current window do we want? */
 | |
|   WindowPtr		pRoot = GetCurrentRootWindow (inputInfo.pointer);
 | |
| 
 | |
|   if (!pWin)
 | |
|     {
 | |
|       ErrorF ("IsRaiseOnClick - no prop use default value:%d\n",
 | |
| 	      RAISE_ON_CLICK_DEFAULT);
 | |
|       return RAISE_ON_CLICK_DEFAULT;
 | |
|     } 
 | |
| 
 | |
|   pwin = (struct _Window*) pWin;
 | |
| 
 | |
|   if (pwin->optional)
 | |
|     prop = (struct _Property *) pwin->optional->userProps;
 | |
|   else
 | |
|     prop = NULL;
 | |
| 
 | |
|   while (prop)
 | |
|     {
 | |
|       if (prop->propertyName == AtmWindowsWmRaiseOnClick ()
 | |
| 	  && prop->type == XA_INTEGER
 | |
| 	  && prop->format == 32)
 | |
| 	{
 | |
| 	  return *(int*)prop->data;
 | |
| 	}
 | |
|       else
 | |
| 	prop = prop->next;
 | |
|     }
 | |
| 
 | |
|   if (pWin != pRoot)
 | |
|     {
 | |
|       return IsRaiseOnClick (pRoot);
 | |
|     }
 | |
|   else
 | |
|     {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("IsRaiseOnClick - no prop use default value:%d\n",
 | |
| 		RAISE_ON_CLICK_DEFAULT);
 | |
| #endif
 | |
|       return RAISE_ON_CLICK_DEFAULT;
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * IsMouseActive
 | |
|  */
 | |
| 
 | |
| static Bool
 | |
| IsMouseActive (WindowPtr pWin)
 | |
| {
 | |
| 
 | |
|   struct _Window	*pwin;
 | |
|   struct _Property	*prop;
 | |
|   /* XXX We're getting inputInfo.poniter here, but this might be really wrong.
 | |
|    * Which pointer's current window do we want? */
 | |
|   WindowPtr		pRoot = GetCurrentRootWindow (inputInfo.pointer);
 | |
| 
 | |
|   if (!pWin)
 | |
|     {
 | |
|       ErrorF ("IsMouseActive - pWin was NULL use default value:%d\n",
 | |
| 	      MOUSE_ACTIVATE_DEFAULT);
 | |
|       return MOUSE_ACTIVATE_DEFAULT;
 | |
|     } 
 | |
| 
 | |
|   pwin = (struct _Window*) pWin;
 | |
| 
 | |
|   if (pwin->optional)
 | |
|     prop = (struct _Property *) pwin->optional->userProps;
 | |
|   else
 | |
|     prop = NULL;
 | |
| 
 | |
|   while (prop)
 | |
|     {
 | |
|       if (prop->propertyName == AtmWindowsWMMouseActivate ()
 | |
| 	  && prop->type == XA_INTEGER
 | |
| 	  && prop->format == 32)
 | |
| 	{
 | |
| 	  return *(int*)prop->data;
 | |
| 	}
 | |
|       else
 | |
| 	prop = prop->next;
 | |
|     }
 | |
| 
 | |
|   if (pWin != pRoot)
 | |
|     {
 | |
|       return IsMouseActive (pRoot);
 | |
|     }
 | |
|   else
 | |
|     {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("IsMouseActive - no prop use default value:%d\n",
 | |
| 		MOUSE_ACTIVATE_DEFAULT);
 | |
| #endif
 | |
|       return MOUSE_ACTIVATE_DEFAULT;
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * winMWExtWMWindowProc - Window procedure
 | |
|  */
 | |
| 
 | |
| LRESULT CALLBACK
 | |
| winMWExtWMWindowProc (HWND hwnd, UINT message, 
 | |
| 			    WPARAM wParam, LPARAM lParam)
 | |
| {
 | |
|   WindowPtr		pWin = NULL;
 | |
|   win32RootlessWindowPtr pRLWinPriv = NULL;
 | |
|   ScreenPtr		pScreen = NULL;
 | |
|   winPrivScreenPtr	pScreenPriv = NULL;
 | |
|   winScreenInfo		*pScreenInfo = NULL;
 | |
|   HWND			hwndScreen = NULL;
 | |
|   POINT			ptMouse;
 | |
|   static Bool		s_fTracking = FALSE;
 | |
|   HDC			hdcUpdate;
 | |
|   PAINTSTRUCT		ps;
 | |
|   LPWINDOWPOS		pWinPos = NULL;
 | |
|   RECT			rcClient;
 | |
|   winWMMessageRec	wmMsg;
 | |
|   Bool			fWMMsgInitialized = FALSE;
 | |
| 
 | |
|   /* Check if the Windows window property for our X window pointer is valid */
 | |
|   if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL)
 | |
|     {
 | |
|       pWin = pRLWinPriv->pFrame->win;
 | |
|       pScreen				= pWin->drawable.pScreen;
 | |
|       if (pScreen) pScreenPriv		= winGetScreenPriv(pScreen);
 | |
|       if (pScreenPriv) pScreenInfo	= pScreenPriv->pScreenInfo;
 | |
|       if (pScreenPriv) hwndScreen	= pScreenPriv->hwndScreen;
 | |
| 
 | |
|       wmMsg.msg		= 0;
 | |
|       wmMsg.hwndWindow	= hwnd;
 | |
|       wmMsg.iWindow	= (Window)pWin->drawable.id;
 | |
| 
 | |
|       wmMsg.iX		= pRLWinPriv->pFrame->x;
 | |
|       wmMsg.iY		= pRLWinPriv->pFrame->y;
 | |
|       wmMsg.iWidth	= pRLWinPriv->pFrame->width;
 | |
|       wmMsg.iHeight	= pRLWinPriv->pFrame->height;
 | |
| 
 | |
|       fWMMsgInitialized = TRUE;
 | |
| #if CYGDEBUG
 | |
|       winDebugWin32Message("winMWExtWMWindowProc", hwnd, message, wParam, lParam);
 | |
| 
 | |
|       winDebug ("\thWnd %08X\n", hwnd);
 | |
|       winDebug ("\tpScreenPriv %08X\n", pScreenPriv);
 | |
|       winDebug ("\tpScreenInfo %08X\n", pScreenInfo);
 | |
|       winDebug ("\thwndScreen %08X\n", hwndScreen);
 | |
|       winDebug ("winMWExtWMWindowProc (%08x) %08x %08x %08x\n",
 | |
| 	      pRLWinPriv, message, wParam, lParam);
 | |
| #endif
 | |
|     }
 | |
|   /* Branch on message type */
 | |
|   switch (message)
 | |
|     {
 | |
|     case WM_CREATE:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_CREATE\n");
 | |
| #endif
 | |
|       /* */
 | |
|       SetProp (hwnd,
 | |
| 	       WIN_WINDOW_PROP,
 | |
| 	       (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams);
 | |
|       return 0;
 | |
| 
 | |
|     case WM_CLOSE:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_CLOSE %d\n", pRLWinPriv->fClose);
 | |
| #endif
 | |
|       /* Tell window-manager to close window */
 | |
|       if (pRLWinPriv->fClose)
 | |
| 	{
 | |
| 	  DestroyWindow (hwnd);
 | |
| 	}
 | |
|       else
 | |
| 	{
 | |
| 	  if (winIsInternalWMRunning(pScreenInfo))
 | |
| 	    {
 | |
| 	      /* Tell our Window Manager thread to kill the window */
 | |
| 	      wmMsg.msg = WM_WM_KILL;
 | |
| 	      if (fWMMsgInitialized)
 | |
| 		winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
 | |
| 	    }
 | |
| 	  winWindowsWMSendEvent(WindowsWMControllerNotify,
 | |
| 				WindowsWMControllerNotifyMask,
 | |
| 				1,
 | |
| 				WindowsWMCloseWindow,
 | |
| 				pWin->drawable.id,
 | |
| 				0, 0, 0, 0);
 | |
| 	}
 | |
|       return 0;
 | |
| 
 | |
|     case WM_DESTROY:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_DESTROY\n");
 | |
| #endif
 | |
|       /* Free the shaodw DC; which allows the bitmap to be freed */
 | |
|       DeleteDC (pRLWinPriv->hdcShadow);
 | |
|       pRLWinPriv->hdcShadow = NULL;
 | |
|       
 | |
|       /* Free the shadow bitmap */
 | |
|       DeleteObject (pRLWinPriv->hbmpShadow);
 | |
|       pRLWinPriv->hbmpShadow = NULL;
 | |
|       
 | |
|       /* Free the screen DC */
 | |
|       ReleaseDC (pRLWinPriv->hWnd, pRLWinPriv->hdcScreen);
 | |
|       pRLWinPriv->hdcScreen = NULL;
 | |
| 
 | |
|       /* Free shadow buffer info header */
 | |
|       free (pRLWinPriv->pbmihShadow);
 | |
|       pRLWinPriv->pbmihShadow = NULL;
 | |
|       
 | |
|       pRLWinPriv->fResized = FALSE;
 | |
|       pRLWinPriv->pfb = NULL;
 | |
|       free (pRLWinPriv);
 | |
|       RemoveProp (hwnd, WIN_WINDOW_PROP);
 | |
|       break;
 | |
| 
 | |
|     case WM_MOUSEMOVE:
 | |
| #if CYGMULTIWINDOW_DEBUG && 0
 | |
|       winDebug ("winMWExtWMWindowProc - WM_MOUSEMOVE\n");
 | |
| #endif
 | |
|       /* Unpack the client area mouse coordinates */
 | |
|       ptMouse.x = GET_X_LPARAM(lParam);
 | |
|       ptMouse.y = GET_Y_LPARAM(lParam);
 | |
| 
 | |
|       /* Translate the client area mouse coordinates to screen coordinates */
 | |
|       ClientToScreen (hwnd, &ptMouse);
 | |
| 
 | |
|       /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */
 | |
|       ptMouse.x -= GetSystemMetrics (SM_XVIRTUALSCREEN);
 | |
|       ptMouse.y -= GetSystemMetrics (SM_YVIRTUALSCREEN);
 | |
| 
 | |
|       /* We can't do anything without privates */
 | |
|       if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
 | |
| 	break;
 | |
| 
 | |
|       /* Has the mouse pointer crossed screens? */
 | |
|       if (pScreen != miPointerGetScreen(inputInfo.pointer))
 | |
| 	miPointerSetScreen (inputInfo.pointer, pScreenInfo->dwScreen,
 | |
| 			       ptMouse.x - pScreenInfo->dwXOffset,
 | |
| 			       ptMouse.y - pScreenInfo->dwYOffset);
 | |
| 
 | |
|       /* Are we tracking yet? */
 | |
|       if (!s_fTracking)
 | |
| 	{
 | |
| 	  TRACKMOUSEEVENT		tme;
 | |
| 	  
 | |
| 	  /* Setup data structure */
 | |
| 	  ZeroMemory (&tme, sizeof (tme));
 | |
| 	  tme.cbSize = sizeof (tme);
 | |
| 	  tme.dwFlags = TME_LEAVE;
 | |
| 	  tme.hwndTrack = hwnd;
 | |
| 
 | |
| 	  /* Call the tracking function */
 | |
| 	  if (!(*g_fpTrackMouseEvent) (&tme))
 | |
| 	    ErrorF ("winMWExtWMWindowProc - _TrackMouseEvent failed\n");
 | |
| 
 | |
| 	  /* Flag that we are tracking now */
 | |
| 	  s_fTracking = TRUE;
 | |
| 	}
 | |
|       
 | |
|       /* Kill the timer used to poll mouse events */
 | |
|       if (g_uipMousePollingTimerID != 0)
 | |
| 	{
 | |
| 	  KillTimer (pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID);
 | |
| 	  g_uipMousePollingTimerID = 0;
 | |
| 	}
 | |
| 
 | |
|       /* Deliver absolute cursor position to X Server */
 | |
|       winEnqueueMotion(ptMouse.x - pScreenInfo->dwXOffset,
 | |
| 		       ptMouse.y - pScreenInfo->dwYOffset);
 | |
| 
 | |
|       return 0;
 | |
|       
 | |
|     case WM_NCMOUSEMOVE:
 | |
| #if CYGMULTIWINDOW_DEBUG && 0
 | |
|       winDebug ("winMWExtWMWindowProc - WM_NCMOUSEMOVE\n");
 | |
| #endif
 | |
|       /*
 | |
|        * We break instead of returning 0 since we need to call
 | |
|        * DefWindowProc to get the mouse cursor changes
 | |
|        * and min/max/close button highlighting in Windows XP.
 | |
|        * The Platform SDK says that you should return 0 if you
 | |
|        * process this message, but it fails to mention that you
 | |
|        * will give up any default functionality if you do return 0.
 | |
|        */
 | |
|       
 | |
|       /* We can't do anything without privates */
 | |
|       if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
 | |
| 	break;
 | |
| 
 | |
|       /*
 | |
|        * Timer to poll mouse events.  This is needed to make
 | |
|        * programs like xeyes follow the mouse properly.
 | |
|        */
 | |
|       if (g_uipMousePollingTimerID == 0)
 | |
| 	g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen,
 | |
| 					     WIN_POLLING_MOUSE_TIMER_ID,
 | |
| 					     MOUSE_POLLING_INTERVAL,
 | |
| 					     NULL);
 | |
|       break;
 | |
| 
 | |
|     case WM_MOUSELEAVE:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_MOUSELEAVE\n");
 | |
| #endif
 | |
|       /* Mouse has left our client area */
 | |
| 
 | |
|       /* Flag that we are no longer tracking */
 | |
|       s_fTracking = FALSE;
 | |
| 
 | |
|       /*
 | |
|        * Timer to poll mouse events.  This is needed to make
 | |
|        * programs like xeyes follow the mouse properly.
 | |
|        */
 | |
|       if (g_uipMousePollingTimerID == 0)
 | |
| 	g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen,
 | |
| 					     WIN_POLLING_MOUSE_TIMER_ID,
 | |
| 					     MOUSE_POLLING_INTERVAL,
 | |
| 					     NULL);
 | |
|       return 0;
 | |
| 
 | |
|     case WM_LBUTTONDBLCLK:
 | |
|     case WM_LBUTTONDOWN:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_LBUTTONDBLCLK\n");
 | |
| #endif
 | |
|       if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
 | |
| 	break;
 | |
|       SetCapture (hwnd);
 | |
|       return winMouseButtonsHandle (pScreen, ButtonPress, Button1, wParam);
 | |
|       
 | |
|     case WM_LBUTTONUP:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_LBUTTONUP\n");
 | |
| #endif
 | |
|       if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
 | |
| 	break;
 | |
|       ReleaseCapture ();
 | |
|       return winMouseButtonsHandle (pScreen, ButtonRelease, Button1, wParam);
 | |
| 
 | |
|     case WM_MBUTTONDBLCLK:
 | |
|     case WM_MBUTTONDOWN:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_MBUTTONDBLCLK\n");
 | |
| #endif
 | |
|       if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
 | |
| 	break;
 | |
|       SetCapture (hwnd);
 | |
|       return winMouseButtonsHandle (pScreen, ButtonPress, Button2, wParam);
 | |
|       
 | |
|     case WM_MBUTTONUP:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_MBUTTONUP\n");
 | |
| #endif
 | |
|       if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
 | |
| 	break;
 | |
|       ReleaseCapture ();
 | |
|       return winMouseButtonsHandle (pScreen, ButtonRelease, Button2, wParam);
 | |
|       
 | |
|     case WM_RBUTTONDBLCLK:
 | |
|     case WM_RBUTTONDOWN:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_RBUTTONDBLCLK\n");
 | |
| #endif
 | |
|       if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
 | |
| 	break;
 | |
|       SetCapture (hwnd);
 | |
|       return winMouseButtonsHandle (pScreen, ButtonPress, Button3, wParam);
 | |
|       
 | |
|     case WM_RBUTTONUP:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_RBUTTONUP\n");
 | |
| #endif
 | |
|       if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
 | |
| 	break;
 | |
|       ReleaseCapture ();
 | |
|       return winMouseButtonsHandle (pScreen, ButtonRelease, Button3, wParam);
 | |
| 
 | |
|     case WM_XBUTTONDBLCLK:
 | |
|     case WM_XBUTTONDOWN:
 | |
|       if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
 | |
| 	break;
 | |
|       SetCapture (hwnd);
 | |
|       return winMouseButtonsHandle (pScreen, ButtonPress, HIWORD(wParam) + 5, wParam);
 | |
|     case WM_XBUTTONUP:
 | |
|       if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
 | |
| 	break;
 | |
|       ReleaseCapture ();
 | |
|       return winMouseButtonsHandle (pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam);
 | |
| 
 | |
|     case WM_MOUSEWHEEL:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_MOUSEWHEEL\n");
 | |
| #endif
 | |
|       
 | |
|       /* Pass the message to the root window */
 | |
|       SendMessage (hwndScreen, message, wParam, lParam);
 | |
|       return 0;
 | |
| 
 | |
|     case WM_MOUSEACTIVATE:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE\n");
 | |
| #endif
 | |
| #if 1
 | |
|       /* Check if this window needs to be made active when clicked */
 | |
|       if (winIsInternalWMRunning(pScreenInfo) && pWin->overrideRedirect)
 | |
| 	{
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	  winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE - "
 | |
| 		    "MA_NOACTIVATE\n");
 | |
| #endif
 | |
| 
 | |
| 	  /* */
 | |
| 	  return MA_NOACTIVATE;
 | |
| 	}
 | |
| #endif
 | |
|       if (!winIsInternalWMRunning(pScreenInfo) && !IsMouseActive (pWin))
 | |
| 	return MA_NOACTIVATE;
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case WM_KILLFOCUS:
 | |
|       /* Pop any pressed keys since we are losing keyboard focus */
 | |
|       winKeybdReleaseKeys ();
 | |
|       return 0;
 | |
| 
 | |
|     case WM_SYSDEADCHAR:
 | |
|     case WM_DEADCHAR:
 | |
|       /*
 | |
|        * NOTE: We do nothing with WM_*CHAR messages,
 | |
|        * nor does the root window, so we can just toss these messages.
 | |
|        */
 | |
|       return 0;
 | |
| 
 | |
|     case WM_SYSKEYDOWN:
 | |
|     case WM_KEYDOWN:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_*KEYDOWN\n");
 | |
| #endif
 | |
| 
 | |
|       /*
 | |
|        * Don't pass Alt-F4 key combo to root window,
 | |
|        * let Windows translate to WM_CLOSE and close this top-level window.
 | |
|        *
 | |
|        * NOTE: We purposely don't check the fUseWinKillKey setting because
 | |
|        * it should only apply to the key handling for the root window,
 | |
|        * not for top-level window-manager windows.
 | |
|        *
 | |
|        * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window
 | |
|        * because that is a key combo that no X app should be expecting to
 | |
|        * receive, since it has historically been used to shutdown the X server.
 | |
|        * Passing Ctrl-Alt-Backspace to the root window preserves that
 | |
|        * behavior, assuming that -unixkill has been passed as a parameter.
 | |
|        */
 | |
|       if (wParam == VK_F4 && (GetKeyState (VK_MENU) & 0x8000))
 | |
| 	  break;
 | |
| 
 | |
|       /* Pass the message to the root window */
 | |
|       SendMessage (hwndScreen, message, wParam, lParam);
 | |
|       return 0;
 | |
| 
 | |
|     case WM_SYSKEYUP:
 | |
|     case WM_KEYUP:
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_*KEYUP\n");
 | |
| #endif
 | |
| 
 | |
|       /* Pass the message to the root window */
 | |
|       SendMessage (hwndScreen, message, wParam, lParam);
 | |
|       return 0;
 | |
| 
 | |
|     case WM_HOTKEY:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_HOTKEY\n");
 | |
| #endif
 | |
| 
 | |
|       /* Pass the message to the root window */
 | |
|       SendMessage (hwndScreen, message, wParam, lParam);
 | |
|       return 0;
 | |
| 
 | |
|     case WM_ERASEBKGND:
 | |
| #if CYGDEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_ERASEBKGND\n");
 | |
| #endif
 | |
|       /*
 | |
|        * Pretend that we did erase the background but we don't care,
 | |
|        * since we repaint the entire region anyhow
 | |
|        * This avoids some flickering when resizing.
 | |
|        */
 | |
|       return TRUE;
 | |
| 
 | |
|     case WM_PAINT:
 | |
|     
 | |
|       /* BeginPaint gives us an hdc that clips to the invalidated region */
 | |
|       hdcUpdate = BeginPaint (hwnd, &ps);
 | |
| 
 | |
|       /* Try to copy from the shadow buffer */
 | |
|       if (!BitBlt (hdcUpdate,
 | |
| 		   ps.rcPaint.left, ps.rcPaint.top,
 | |
| 		   ps.rcPaint.right - ps.rcPaint.left,
 | |
| 		   ps.rcPaint.bottom - ps.rcPaint.top,
 | |
| 		   pRLWinPriv->hdcShadow,
 | |
| 		   ps.rcPaint.left, ps.rcPaint.top,
 | |
| 		   SRCCOPY))
 | |
| 	{
 | |
| 	  LPVOID lpMsgBuf;
 | |
| 	  
 | |
| 	  /* Display a fancy error message */
 | |
| 	  FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | 
 | |
| 			 FORMAT_MESSAGE_FROM_SYSTEM | 
 | |
| 			 FORMAT_MESSAGE_IGNORE_INSERTS,
 | |
| 			 NULL,
 | |
| 			 GetLastError (),
 | |
| 			 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
 | |
| 			 (LPTSTR) &lpMsgBuf,
 | |
| 			 0, NULL);
 | |
| 
 | |
| 	  ErrorF ("winMWExtWMWindowProc - BitBlt failed: %s\n",
 | |
| 		  (LPSTR)lpMsgBuf);
 | |
| 	  LocalFree (lpMsgBuf);
 | |
| 	}
 | |
| 
 | |
|       /* EndPaint frees the DC */
 | |
|       EndPaint (hwnd, &ps);
 | |
|       break;
 | |
| 
 | |
|     case WM_ACTIVATE:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_ACTIVATE\n");
 | |
| #endif
 | |
|       if (LOWORD(wParam) != WA_INACTIVE)
 | |
| 	{
 | |
| 	  if (winIsInternalWMRunning(pScreenInfo))
 | |
| 	    {
 | |
| #if 0
 | |
| 	      /* Raise the window to the top in Z order */
 | |
| 	      wmMsg.msg = WM_WM_RAISE;
 | |
| 	      if (fWMMsgInitialized)
 | |
| 		winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
 | |
| #endif
 | |
| 	      /* Tell our Window Manager thread to activate the window */
 | |
| 	      wmMsg.msg = WM_WM_ACTIVATE;
 | |
| 	      if (fWMMsgInitialized)
 | |
| 		if (!pWin || !pWin->overrideRedirect) /* for OOo menus */
 | |
| 		  winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
 | |
| 	    }
 | |
| 	  winWindowsWMSendEvent(WindowsWMControllerNotify,
 | |
| 				WindowsWMControllerNotifyMask,
 | |
| 				1,
 | |
| 				WindowsWMActivateWindow,
 | |
| 				pWin->drawable.id,
 | |
| 				0, 0,
 | |
| 				0, 0);
 | |
| 	}
 | |
|       return 0;
 | |
| 
 | |
| #if 1
 | |
|     case WM_WINDOWPOSCHANGING:
 | |
|       pWinPos = (LPWINDOWPOS)lParam;
 | |
|       if (!(pWinPos->flags & SWP_NOZORDER))
 | |
| 	{
 | |
| 	  if (pRLWinPriv->fRestackingNow || pScreenPriv->fRestacking)
 | |
| 	    {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	      winDebug ("Win %08x is now restacking.\n", (unsigned int)pRLWinPriv);
 | |
| #endif
 | |
| 	      break;
 | |
| 	    }
 | |
| 
 | |
| 	  if (winIsInternalWMRunning(pScreenInfo) || IsRaiseOnClick (pWin))
 | |
| 	    {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	      winDebug ("Win %08x has WINDOWSWM_RAISE_ON_CLICK.\n", (unsigned int)pRLWinPriv);
 | |
| #endif
 | |
| 	      break;
 | |
| 	    }
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	  winDebug ("Win %08x forbid to change z order (%08x).\n",
 | |
| 		    (unsigned int)pRLWinPriv, (unsigned int)pWinPos->hwndInsertAfter);
 | |
| #endif
 | |
| 	  pWinPos->flags |= SWP_NOZORDER;
 | |
| 	}
 | |
|       break;
 | |
| #endif
 | |
| 
 | |
|     case WM_MOVE:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_MOVE - %d ms\n",
 | |
| 		(unsigned int)GetTickCount ());
 | |
| #endif
 | |
|       if (g_fNoConfigureWindow) break;
 | |
| #if 0
 | |
|       /* Bail if Windows window is not actually moving */
 | |
|       if (pRLWinPriv->dwX == (short) LOWORD(lParam)
 | |
| 	  && pRLWinPriv->dwY == (short) HIWORD(lParam))
 | |
| 	break;
 | |
| 
 | |
|       /* Also bail if we're maximizing, we'll do the whole thing in WM_SIZE */
 | |
|       {
 | |
| 	WINDOWPLACEMENT windPlace;
 | |
| 	windPlace.length = sizeof (WINDOWPLACEMENT);
 | |
| 
 | |
| 	/* Get current window placement */
 | |
| 	GetWindowPlacement (hwnd, &windPlace);
 | |
| 
 | |
| 	/* Bail if maximizing */
 | |
| 	if (windPlace.showCmd == SW_MAXIMIZE
 | |
| 	    || windPlace.showCmd == SW_SHOWMAXIMIZED)
 | |
| 	  break;
 | |
|       }
 | |
| #endif
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("\t(%d, %d)\n", (short) LOWORD(lParam), (short) HIWORD(lParam));
 | |
| #endif
 | |
|       if (!pRLWinPriv->fMovingOrSizing)
 | |
| 	{
 | |
| 	  if (winIsInternalWMRunning(pScreenInfo))
 | |
| 	    winAdjustXWindow (pWin, hwnd);
 | |
| 
 | |
| 	  winMWExtWMMoveXWindow (pWin,
 | |
| 				 (LOWORD(lParam) - wBorderWidth (pWin)
 | |
| 				  - GetSystemMetrics (SM_XVIRTUALSCREEN)),
 | |
| 				 (HIWORD(lParam) - wBorderWidth (pWin)
 | |
| 				  - GetSystemMetrics (SM_YVIRTUALSCREEN)));
 | |
| 	}
 | |
|       return 0;
 | |
| 
 | |
|     case WM_SHOWWINDOW:
 | |
| #if CYGMULTIWINDOW_DEBUG || TRUE
 | |
|       winDebug ("winMWExtWMWindowProc - WM_SHOWWINDOW - %d ms\n",
 | |
| 		(unsigned int)GetTickCount ());
 | |
| #endif
 | |
|       /* Bail out if the window is being hidden */
 | |
|       if (!wParam)
 | |
| 	return 0;
 | |
| 
 | |
|       if (!pScreenInfo->fInternalWM)//XXXX
 | |
| 	return 0;
 | |
| 
 | |
|       winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo);
 | |
| 
 | |
|       if (winIsInternalWMRunning(pScreenInfo))
 | |
| 	{
 | |
| #if CYGMULTIWINDOW_DEBUG || TRUE
 | |
| 	  winDebug ("\tMapWindow\n");
 | |
| #endif
 | |
| 	  /* Tell X to map the window */
 | |
| 	   MapWindow (pWin, wClient(pWin));
 | |
| 
 | |
| 	  if (!pRLWinPriv->pFrame->win->overrideRedirect)
 | |
| 	    /* Bring the Windows window to the foreground */
 | |
| 	    SetForegroundWindow (hwnd);
 | |
| 
 | |
| 	  /* Setup the Window Manager message */
 | |
| 	  wmMsg.msg = WM_WM_MAP;
 | |
| 	  wmMsg.iWidth = pRLWinPriv->pFrame->width;
 | |
| 	  wmMsg.iHeight = pRLWinPriv->pFrame->height;
 | |
| 
 | |
| 	  /* Tell our Window Manager thread to map the window */
 | |
| 	  if (fWMMsgInitialized)
 | |
| 	    winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
 | |
| 	}
 | |
|       break;
 | |
| 
 | |
|     case WM_SIZING:
 | |
|       /* Need to legalize the size according to WM_NORMAL_HINTS */
 | |
|       /* for applications like xterm */
 | |
|       return ValidateSizing (hwnd, pWin, wParam, lParam);
 | |
| 
 | |
|     case WM_WINDOWPOSCHANGED:
 | |
|       {
 | |
| 	pWinPos = (LPWINDOWPOS) lParam;
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|         winDebug("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED\n");
 | |
| 	winDebug("\tflags: %s%s%s%s%s%s%s%s%s%s%s%s\n",
 | |
| 	(pWinPos->flags & SWP_DRAWFRAME)?"SWP_DRAWFRAME ":"",
 | |
| 	(pWinPos->flags & SWP_FRAMECHANGED)?"SWP_FRAMECHANGED ":"",
 | |
| 	(pWinPos->flags & SWP_HIDEWINDOW)?"SWP_HIDEWINDOW ":"",
 | |
| 	(pWinPos->flags & SWP_NOACTIVATE)?"SWP_NOACTIVATE ":"",
 | |
| 	(pWinPos->flags & SWP_NOCOPYBITS)?"SWP_NOCOPYBITS ":"",
 | |
| 	(pWinPos->flags & SWP_NOMOVE)?"SWP_NOMOVE ":"",
 | |
| 	(pWinPos->flags & SWP_NOOWNERZORDER)?"SWP_NOOWNERZORDER ":"",
 | |
| 	(pWinPos->flags & SWP_NOSIZE)?"SWP_NOSIZE ":"",
 | |
| 	(pWinPos->flags & SWP_NOREDRAW)?"SWP_NOREDRAW ":"",
 | |
| 	(pWinPos->flags & SWP_NOSENDCHANGING)?"SWP_NOSENDCHANGING ":"",
 | |
| 	(pWinPos->flags & SWP_NOZORDER)?"SWP_NOZORDER ":"",
 | |
| 	(pWinPos->flags & SWP_SHOWWINDOW)?"SWP_SHOWWINDOW ":"");
 | |
| 	winDebug("\tno_configure: %s\n", (g_fNoConfigureWindow?"Yes":"No"));
 | |
| 	winDebug("\textend: (%d, %d, %d, %d)\n",
 | |
|             pWinPos->x, pWinPos->y, pWinPos->cx, pWinPos->cy);
 | |
| 
 | |
| #endif
 | |
| 	if (pWinPos->flags & SWP_HIDEWINDOW) break;
 | |
| 
 | |
| 	/* Reorder if window z order was changed */
 | |
| 	if ((pScreenPriv != NULL)
 | |
| 	    && !(pWinPos->flags & SWP_NOZORDER)
 | |
| 	    && !(pWinPos->flags & SWP_SHOWWINDOW)
 | |
| 	    && winIsInternalWMRunning(pScreenInfo))
 | |
| 	  {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	    winDebug ("\twindow z order was changed\n");
 | |
| #endif
 | |
| 	    if (pWinPos->hwndInsertAfter == HWND_TOP
 | |
| 		||pWinPos->hwndInsertAfter == HWND_TOPMOST
 | |
| 		||pWinPos->hwndInsertAfter == HWND_NOTOPMOST)
 | |
| 	      {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 		winDebug ("\traise to top\n");
 | |
| #endif
 | |
| 		/* Raise the window to the top in Z order */
 | |
| 		wmMsg.msg = WM_WM_RAISE;
 | |
| 		if (fWMMsgInitialized)
 | |
| 		  winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
 | |
| 	      }
 | |
| #if 1
 | |
| 	    else if (pWinPos->hwndInsertAfter == HWND_BOTTOM)
 | |
| 	      {
 | |
| 	      }
 | |
| 	    else
 | |
| 	      {
 | |
| 		/* Check if this window is top of X windows. */
 | |
| 		HWND hWndAbove = NULL;
 | |
| 		DWORD dwCurrentProcessID = GetCurrentProcessId ();
 | |
| 		DWORD dwWindowProcessID = 0;
 | |
| 
 | |
| 		for (hWndAbove = pWinPos->hwndInsertAfter;
 | |
| 		     hWndAbove != NULL;
 | |
| 		     hWndAbove = GetNextWindow (hWndAbove, GW_HWNDPREV))
 | |
| 		  {
 | |
| 		    /* Ignore other XWin process's window */
 | |
| 		    GetWindowThreadProcessId (hWndAbove, &dwWindowProcessID);
 | |
| 
 | |
| 		    if ((dwWindowProcessID == dwCurrentProcessID)
 | |
| 			&& GetProp (hWndAbove, WIN_WINDOW_PROP)
 | |
| 			&& !IsWindowVisible (hWndAbove)
 | |
| 			&& !IsIconic (hWndAbove) ) /* ignore minimized windows */
 | |
| 		      break;
 | |
| 		  }
 | |
| 		/* If this is top of X windows in Windows stack,
 | |
| 		   raise it in X stack. */
 | |
| 		if (hWndAbove == NULL)
 | |
| 		  {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 		    winDebug ("\traise to top\n");
 | |
| #endif
 | |
| 		    /* Raise the window to the top in Z order */
 | |
| 		    wmMsg.msg = WM_WM_RAISE;
 | |
| 		    if (fWMMsgInitialized)
 | |
| 		      winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
 | |
| 		  }
 | |
| 	      }
 | |
| #endif
 | |
| 	  }
 | |
| 
 | |
| 	if (!(pWinPos->flags & SWP_NOSIZE)) {
 | |
| 	  if (IsIconic(hwnd)){
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	    winDebug ("\tIconic -> MINIMIZED\n");
 | |
| #endif
 | |
| 	    if (winIsInternalWMRunning(pScreenInfo))
 | |
| 	      {
 | |
| 	      /* Raise the window to the top in Z order */
 | |
| 		wmMsg.msg = WM_WM_LOWER;
 | |
| 		if (fWMMsgInitialized)
 | |
| 		  winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
 | |
| 	      }
 | |
| 	    winWindowsWMSendEvent(WindowsWMControllerNotify,
 | |
| 				  WindowsWMControllerNotifyMask,
 | |
| 				  1,
 | |
| 				  WindowsWMMinimizeWindow,
 | |
| 				  pWin->drawable.id,
 | |
| 				  0, 0, 0, 0);
 | |
| 	  } else if (IsZoomed(hwnd)){
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	    winDebug ("\tZoomed -> MAXIMIZED\n");
 | |
| #endif
 | |
| 	    winWindowsWMSendEvent(WindowsWMControllerNotify,
 | |
| 				  WindowsWMControllerNotifyMask,
 | |
| 				  1,
 | |
| 				  WindowsWMMaximizeWindow,
 | |
| 				  pWin->drawable.id,
 | |
| 				  0, 0, 0, 0);
 | |
| 	  } else {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	    winDebug ("\tnone -> RESTORED\n");
 | |
| #endif
 | |
| 	    winWindowsWMSendEvent(WindowsWMControllerNotify,
 | |
| 				  WindowsWMControllerNotifyMask,
 | |
| 				  1,
 | |
| 				  WindowsWMRestoreWindow,
 | |
| 				  pWin->drawable.id,
 | |
| 				  0, 0, 0, 0);
 | |
| 	  }
 | |
| 	}
 | |
| 	if (!g_fNoConfigureWindow ) {
 | |
| 
 | |
| 	  if (!pRLWinPriv->fMovingOrSizing
 | |
| 	      /*&& (pWinPos->flags & SWP_SHOWWINDOW)*/) {
 | |
| 	    GetClientRect (hwnd, &rcClient);
 | |
| 	    MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2);
 | |
| 
 | |
| 	    if (!(pWinPos->flags & SWP_NOMOVE)
 | |
| 		&&!(pWinPos->flags & SWP_NOSIZE)) {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	      winDebug ("\tmove & resize\n");
 | |
| #endif
 | |
| 	      if (winIsInternalWMRunning(pScreenInfo))
 | |
|                 winAdjustXWindow (pWin, hwnd);
 | |
| 
 | |
| 	      winMWExtWMMoveResizeXWindow (pWin,
 | |
| 					   rcClient.left - wBorderWidth (pWin)
 | |
| 					   - GetSystemMetrics (SM_XVIRTUALSCREEN),
 | |
| 					   rcClient.top - wBorderWidth (pWin)
 | |
| 					   - GetSystemMetrics (SM_YVIRTUALSCREEN),
 | |
| 					   rcClient.right - rcClient.left
 | |
| 					   - wBorderWidth (pWin)*2,
 | |
| 					   rcClient.bottom - rcClient.top
 | |
| 					   - wBorderWidth (pWin)*2);
 | |
| 	    } else if (!(pWinPos->flags & SWP_NOMOVE)) {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	      winDebug ("\tmove\n");
 | |
| #endif
 | |
| 	      if (winIsInternalWMRunning(pScreenInfo))
 | |
|                 winAdjustXWindow (pWin, hwnd);
 | |
| 
 | |
| 	      winMWExtWMMoveResizeXWindow (pWin,
 | |
| 					   rcClient.left - wBorderWidth (pWin)
 | |
| 					   - GetSystemMetrics (SM_XVIRTUALSCREEN),
 | |
| 					   rcClient.top - wBorderWidth (pWin)
 | |
| 					   - GetSystemMetrics (SM_YVIRTUALSCREEN),
 | |
| 					   rcClient.right - rcClient.left
 | |
| 					   - wBorderWidth (pWin)*2,
 | |
| 					   rcClient.bottom - rcClient.top
 | |
| 					   - wBorderWidth (pWin)*2);
 | |
| 	    } else if (!(pWinPos->flags & SWP_NOMOVE)) {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	      winDebug ("\tmove\n");
 | |
| #endif
 | |
| 	      if (winIsInternalWMRunning(pScreenInfo))
 | |
|                 winAdjustXWindow (pWin, hwnd); 
 | |
| 
 | |
| 	      winMWExtWMMoveXWindow (pWin,
 | |
| 				     rcClient.left - wBorderWidth (pWin)
 | |
| 				     - GetSystemMetrics (SM_XVIRTUALSCREEN),
 | |
| 				     rcClient.top - wBorderWidth (pWin)
 | |
| 				     - GetSystemMetrics (SM_YVIRTUALSCREEN));
 | |
| 	    } else if (!(pWinPos->flags & SWP_NOSIZE)) {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	      winDebug ("\tresize\n");
 | |
| #endif
 | |
| 	      if (winIsInternalWMRunning(pScreenInfo))
 | |
|                 winAdjustXWindow (pWin, hwnd); 
 | |
| 
 | |
| 	      winMWExtWMResizeXWindow (pWin,
 | |
| 				       rcClient.right - rcClient.left
 | |
| 				       - wBorderWidth (pWin)*2,
 | |
| 				       rcClient.bottom - rcClient.top
 | |
| 				       - wBorderWidth (pWin)*2);
 | |
| 	    }
 | |
| 	  }
 | |
| 	}
 | |
|       }
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED - done.\n");
 | |
| #endif
 | |
|       return 0;
 | |
| 
 | |
|     case WM_SIZE:
 | |
|       /* see dix/window.c */
 | |
|       /* FIXME: Maximize/Restore? */
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_SIZE - %d ms\n",
 | |
| 		(unsigned int)GetTickCount ());
 | |
| #endif
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("\t(%d, %d) %d\n", (short) LOWORD(lParam), (short) HIWORD(lParam), g_fNoConfigureWindow);
 | |
| #endif
 | |
|       if (g_fNoConfigureWindow) break;
 | |
| 
 | |
|       /* Branch on type of resizing occurring */
 | |
|       switch (wParam)
 | |
| 	{
 | |
| 	case SIZE_MINIMIZED:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	  winDebug ("\tSIZE_MINIMIZED\n");
 | |
| #endif
 | |
| 	  if (winIsInternalWMRunning(pScreenInfo))
 | |
| 	    {
 | |
| 	      /* Raise the window to the top in Z order */
 | |
| 	      wmMsg.msg = WM_WM_LOWER;
 | |
| 	      if (fWMMsgInitialized)
 | |
| 		winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
 | |
| 	    }
 | |
| 	  winWindowsWMSendEvent(WindowsWMControllerNotify,
 | |
| 				WindowsWMControllerNotifyMask,
 | |
| 				1,
 | |
| 				WindowsWMMinimizeWindow,
 | |
| 				pWin->drawable.id,
 | |
| 				0, 0,
 | |
| 				LOWORD(lParam), HIWORD(lParam));
 | |
| 	  break;
 | |
| 
 | |
| 	case SIZE_RESTORED:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	  winDebug ("\tSIZE_RESTORED\n");
 | |
| #endif
 | |
| 	  winWindowsWMSendEvent(WindowsWMControllerNotify,
 | |
| 				WindowsWMControllerNotifyMask,
 | |
| 				1,
 | |
| 				WindowsWMRestoreWindow,
 | |
| 				pWin->drawable.id,
 | |
| 				0, 0,
 | |
| 				LOWORD(lParam), HIWORD(lParam));
 | |
| 	  break;
 | |
| 
 | |
| 	case SIZE_MAXIMIZED:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	  winDebug ("\tSIZE_MAXIMIZED\n");
 | |
| #endif
 | |
| 	  winWindowsWMSendEvent(WindowsWMControllerNotify,
 | |
| 				WindowsWMControllerNotifyMask,
 | |
| 				1,
 | |
| 				WindowsWMMaximizeWindow,
 | |
| 				pWin->drawable.id,
 | |
| 				0, 0,
 | |
| 				LOWORD(lParam), HIWORD(lParam));
 | |
| 	  break;
 | |
| 	}
 | |
| 
 | |
|       /* Perform the resize and notify the X client */
 | |
|       if (!pRLWinPriv->fMovingOrSizing)
 | |
| 	{
 | |
| 	  if (winIsInternalWMRunning(pScreenInfo))
 | |
|             winAdjustXWindow (pWin, hwnd);
 | |
| 
 | |
| 	  winMWExtWMResizeXWindow (pWin,
 | |
| 				   (short) LOWORD(lParam)
 | |
| 				   - wBorderWidth (pWin)*2,
 | |
| 				   (short) HIWORD(lParam)
 | |
| 				   - wBorderWidth (pWin)*2);
 | |
| 	}
 | |
|       break;
 | |
| 
 | |
|     case WM_ACTIVATEAPP:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_ACTIVATEAPP - %d ms\n",
 | |
| 		(unsigned int)GetTickCount ());
 | |
| #endif
 | |
|       if (wParam)
 | |
| 	{
 | |
| 	  if (winIsInternalWMRunning(pScreenInfo))
 | |
| 	    {
 | |
| 	    }
 | |
| 	  else
 | |
| 	    {
 | |
| 	    }
 | |
| 	  winWindowsWMSendEvent(WindowsWMActivationNotify,
 | |
| 				WindowsWMActivationNotifyMask,
 | |
| 				1,
 | |
| 				WindowsWMIsActive,
 | |
| 				pWin->drawable.id,
 | |
| 				0, 0,
 | |
| 				0, 0);
 | |
| 	}
 | |
|       else
 | |
| 	{
 | |
| 	  winWindowsWMSendEvent(WindowsWMActivationNotify,
 | |
| 				WindowsWMActivationNotifyMask,
 | |
| 				1,
 | |
| 				WindowsWMIsInactive,
 | |
| 				pWin->drawable.id,
 | |
| 				0, 0,
 | |
| 				0, 0);
 | |
| 	}
 | |
|       break;
 | |
| 
 | |
|     case WM_SETCURSOR:
 | |
|       if (LOWORD(lParam) == HTCLIENT)
 | |
| 	{
 | |
| 	  if (!g_fSoftwareCursor) SetCursor (pScreenPriv->cursor.handle);
 | |
| 	  return TRUE;
 | |
| 	}
 | |
|       break;
 | |
| 
 | |
|     case WM_ENTERSIZEMOVE:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_ENTERSIZEMOVE - %d ms\n",
 | |
| 		(unsigned int)GetTickCount ());
 | |
| #endif
 | |
|       pRLWinPriv->fMovingOrSizing = TRUE;
 | |
|       break;
 | |
| 
 | |
|     case WM_EXITSIZEMOVE:
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       winDebug ("winMWExtWMWindowProc - WM_EXITSIZEMOVE - %d ms\n",
 | |
| 		(unsigned int)GetTickCount ());
 | |
| #endif
 | |
|       pRLWinPriv->fMovingOrSizing = FALSE;
 | |
| 
 | |
|       GetClientRect (hwnd, &rcClient);
 | |
| 
 | |
|       MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2);
 | |
| 
 | |
|       if (winIsInternalWMRunning(pScreenInfo))
 | |
|         winAdjustXWindow (pWin, hwnd); 
 | |
| 
 | |
|       winMWExtWMMoveResizeXWindow (pWin,
 | |
| 				   rcClient.left - wBorderWidth (pWin)
 | |
| 				   - GetSystemMetrics (SM_XVIRTUALSCREEN),
 | |
| 				   rcClient.top - wBorderWidth (pWin)
 | |
| 				   - GetSystemMetrics (SM_YVIRTUALSCREEN),
 | |
| 				   rcClient.right - rcClient.left
 | |
| 				   - wBorderWidth (pWin)*2,
 | |
| 				   rcClient.bottom - rcClient.top
 | |
| 				   - wBorderWidth (pWin)*2);
 | |
|       break;
 | |
| 
 | |
|     case WM_MANAGE:
 | |
|       ErrorF ("winMWExtWMWindowProc - WM_MANAGE\n");
 | |
|       break;
 | |
| 
 | |
|     case WM_UNMANAGE:
 | |
|       ErrorF ("winMWExtWMWindowProc - WM_UNMANAGE\n");
 | |
|       break;
 | |
| 
 | |
|     default:
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|   return DefWindowProc (hwnd, message, wParam, lParam);
 | |
| }
 |