863 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			863 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  *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
 | |
|  */
 | |
| /* $XFree86: xc/programs/Xserver/hw/xwin/winwindow.c,v 1.5 2002/11/07 10:31:32 alanh Exp $ */
 | |
| 
 | |
| #include "win.h"
 | |
| #include "dixevents.h"
 | |
| #include "winmultiwindowclass.h"
 | |
| #include "winprefs.h"
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * External global variables
 | |
|  */
 | |
| 
 | |
| extern HICON		g_hiconX;
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Prototypes for local functions
 | |
|  */
 | |
| 
 | |
| static void
 | |
| winCreateWindowsWindow (WindowPtr pWin);
 | |
| 
 | |
| static void
 | |
| winDestroyWindowsWindow (WindowPtr pWin);
 | |
| 
 | |
| static void
 | |
| winUpdateWindowsWindow (WindowPtr pWin);
 | |
| 
 | |
| static void
 | |
| winFindWindow (pointer value, XID id, pointer cdata);
 | |
| 
 | |
| #if 0
 | |
| static void
 | |
| winRestackXWindow (WindowPtr pWin, int smode);
 | |
| #endif
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Constant defines
 | |
|  */
 | |
| 
 | |
| #define MOUSE_POLLING_INTERVAL		500
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Macros
 | |
|  */
 | |
| 
 | |
| #define SubSend(pWin) \
 | |
|     ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
 | |
| 
 | |
| #define StrSend(pWin) \
 | |
|     ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
 | |
| 
 | |
| #define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * CreateWindow - See Porting Layer Definition - p. 37
 | |
|  */
 | |
| 
 | |
| Bool
 | |
| winCreateWindowMultiWindow (WindowPtr pWin)
 | |
| {
 | |
|   Bool			fResult = TRUE;
 | |
|   winWindowPriv(pWin);
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("winCreateWindowMultiWindow - pWin: %08x\n", pWin);
 | |
| #endif
 | |
|   
 | |
|   /* Call any wrapped CreateWindow function */
 | |
|   if (winGetScreenPriv(pWin->drawable.pScreen)->CreateWindow)
 | |
|     fResult = winGetScreenPriv(pWin->drawable.pScreen)->CreateWindow (pWin);
 | |
|   
 | |
|   /* Initialize some privates values */
 | |
|   pWinPriv->hRgn = NULL;
 | |
|   pWinPriv->hWnd = NULL;
 | |
|   pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen);
 | |
|   pWinPriv->fXKilled = FALSE;
 | |
|   pWinPriv->fNeedRestore = FALSE;
 | |
|   
 | |
|   return fResult;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * DestroyWindow - See Porting Layer Definition - p. 37
 | |
|  */
 | |
| 
 | |
| Bool
 | |
| winDestroyWindowMultiWindow (WindowPtr pWin)
 | |
| {
 | |
|   Bool			fResult = TRUE;
 | |
|   winWindowPriv(pWin);
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("winDestroyWindowMultiWindow - pWin: %08x\n", pWin);
 | |
| #endif
 | |
|   
 | |
|   /* Call any wrapped DestroyWindow function */
 | |
|   if (winGetScreenPriv(pWin->drawable.pScreen)->DestroyWindow)
 | |
|     fResult = winGetScreenPriv(pWin->drawable.pScreen)->DestroyWindow (pWin);
 | |
|   
 | |
|   /* Flag that the window has been destroyed */
 | |
|   pWinPriv->fXKilled = TRUE;
 | |
|   
 | |
|   /* Kill the MS Windows window associated with this window */
 | |
|   winDestroyWindowsWindow (pWin); 
 | |
| 
 | |
|   return fResult;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * PositionWindow - See Porting Layer Definition - p. 37
 | |
|  */
 | |
| 
 | |
| Bool
 | |
| winPositionWindowMultiWindow (WindowPtr pWin, int x, int y)
 | |
| {
 | |
|   Bool			fResult = TRUE;
 | |
|   int		        iX, iY, iWidth, iHeight, iBorder;
 | |
|   winWindowPriv(pWin);
 | |
|   HWND hWnd = pWinPriv->hWnd;
 | |
|   RECT rcNew;
 | |
|   RECT rcOld;
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   RECT rcClient;
 | |
|   RECT *lpRc;
 | |
| #endif
 | |
|   DWORD dwExStyle;
 | |
|   DWORD dwStyle;
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("winPositionWindowMultiWindow - pWin: %08x\n", pWin);
 | |
| #endif
 | |
|   
 | |
|   /* Call any wrapped PositionWindow function */
 | |
|   if (winGetScreenPriv(pWin->drawable.pScreen)->PositionWindow)
 | |
|     fResult = winGetScreenPriv(pWin->drawable.pScreen)->PositionWindow (pWin, x, y);
 | |
|   
 | |
|   /* Bail out if the Windows window handle is bad */
 | |
|   if (!hWnd)
 | |
|     return fResult;
 | |
| 
 | |
|   /* Get the Windows window style and extended style */
 | |
|   dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE);
 | |
|   dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE);
 | |
| 
 | |
|   /* Get the width of the X window border */
 | |
|   iBorder = wBorderWidth (pWin);
 | |
|   
 | |
|   /* Get the X and Y location of the X window */
 | |
|   iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
 | |
|   iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
 | |
| 
 | |
|   /* Get the height and width of the X window */
 | |
|   iWidth = pWin->drawable.width;
 | |
|   iHeight = pWin->drawable.height;
 | |
| 
 | |
|   /* Store the origin, height, and width in a rectangle structure */
 | |
|   SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight);
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   lpRc = &rcNew;
 | |
|   ErrorF ("winPositionWindowMultiWindow - (%d ms)drawable (%d, %d)-(%d, %d)\n",
 | |
| 	  GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
 | |
| #endif
 | |
| 
 | |
|   /*
 | |
|    * Calculate the required size of the Windows window rectangle,
 | |
|    * given the size of the Windows window client area.
 | |
|    */
 | |
|   AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle);
 | |
| 
 | |
|   /* Get a rectangle describing the old Windows window */
 | |
|   GetWindowRect (hWnd, &rcOld);
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   /* Get a rectangle describing the Windows window client area */
 | |
|   GetClientRect (hWnd, &rcClient);
 | |
| 
 | |
|   lpRc = &rcNew;
 | |
|   ErrorF ("winPositionWindowMultiWindow - (%d ms)rcNew (%d, %d)-(%d, %d)\n",
 | |
| 	  GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
 | |
|       
 | |
|   lpRc = &rcOld;
 | |
|   ErrorF ("winPositionWindowMultiWindow - (%d ms)rcOld (%d, %d)-(%d, %d)\n",
 | |
| 	  GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
 | |
|       
 | |
|   lpRc = &rcClient;
 | |
|   ErrorF ("(%d ms)rcClient (%d, %d)-(%d, %d)\n",
 | |
| 	  GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
 | |
| #endif
 | |
| 
 | |
|   /* Check if the old rectangle and new rectangle are the same */
 | |
|   if (!EqualRect (&rcNew, &rcOld))
 | |
|     {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       ErrorF ("winPositionWindowMultiWindow - Need to move\n");
 | |
| #endif
 | |
| 
 | |
|       /* Change the position and dimensions of the Windows window */
 | |
|       MoveWindow (hWnd,
 | |
| 		  rcNew.left, rcNew.top,
 | |
| 		  rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
 | |
| 		  TRUE);
 | |
|     }
 | |
|   else
 | |
|     {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       ErrorF ("winPositionWindowMultiWindow - Not need to move\n");
 | |
| #endif
 | |
|     }
 | |
| 
 | |
|   return fResult;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * ChangeWindowAttributes - See Porting Layer Definition - p. 37
 | |
|  */
 | |
| 
 | |
| Bool
 | |
| winChangeWindowAttributesMultiWindow (WindowPtr pWin, unsigned long mask)
 | |
| {
 | |
|   Bool			fResult = TRUE;
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin);
 | |
| #endif
 | |
|   
 | |
|   /* Call any wrapped ChangeWindowAttributes function */
 | |
|   if (winGetScreenPriv(pWin->drawable.pScreen)->ChangeWindowAttributes)
 | |
|     fResult = winGetScreenPriv(pWin->drawable.pScreen)->ChangeWindowAttributes (pWin, mask);
 | |
|   
 | |
|   /*
 | |
|    * NOTE: We do not currently need to do anything here.
 | |
|    */
 | |
| 
 | |
|   return fResult;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * UnmapWindow - See Porting Layer Definition - p. 37
 | |
|  * Also referred to as UnrealizeWindow
 | |
|  */
 | |
| 
 | |
| Bool
 | |
| winUnmapWindowMultiWindow (WindowPtr pWin)
 | |
| {
 | |
|   Bool			fResult = TRUE;
 | |
|   winWindowPriv(pWin);
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin);
 | |
| #endif
 | |
|   
 | |
|   /* Call any wrapped UnrealizeWindow function */
 | |
|   if (winGetScreenPriv(pWin->drawable.pScreen)->UnrealizeWindow)
 | |
|     fResult = winGetScreenPriv(pWin->drawable.pScreen)->UnrealizeWindow (pWin);
 | |
|   
 | |
|   /* Flag that the window has been killed */
 | |
|   pWinPriv->fXKilled = TRUE;
 | |
|  
 | |
|   /* Destroy the Windows window associated with this X window */
 | |
|   winDestroyWindowsWindow (pWin);
 | |
| 
 | |
|   return fResult;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * MapWindow - See Porting Layer Definition - p. 37
 | |
|  * Also referred to as RealizeWindow
 | |
|  */
 | |
| 
 | |
| Bool
 | |
| winMapWindowMultiWindow (WindowPtr pWin)
 | |
| {
 | |
|   Bool			fResult = TRUE;
 | |
|   winWindowPriv(pWin);
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("winMapWindowMultiWindow - pWin: %08x\n", pWin);
 | |
| #endif
 | |
|   
 | |
|   /* Call any wrapped RealizeWindow function */
 | |
|   if (winGetScreenPriv(pWin->drawable.pScreen)->RealizeWindow)
 | |
|     fResult = winGetScreenPriv(pWin->drawable.pScreen)->RealizeWindow (pWin);
 | |
|   
 | |
|   /* Flag that this window has not been destroyed */
 | |
|   pWinPriv->fXKilled = FALSE;
 | |
| 
 | |
|   /* Refresh/redisplay the Windows window associated with this X window */
 | |
|   winUpdateWindowsWindow (pWin);
 | |
| 
 | |
| #ifdef SHAPE
 | |
|   /* Update the Windows window's shape */
 | |
|   winReshapeMultiWindow (pWin);
 | |
|   winUpdateRgnMultiWindow (pWin);
 | |
| #endif
 | |
| 
 | |
|   return fResult;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * ReparentWindow - See Porting Layer Definition - p. 42
 | |
|  */
 | |
| 
 | |
| void
 | |
| winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent)
 | |
| {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin);
 | |
| #endif
 | |
| 
 | |
|   /* Call any wrapped ReparentWindow function */
 | |
|   if (winGetScreenPriv(pWin->drawable.pScreen)->ReparentWindow)
 | |
|     winGetScreenPriv(pWin->drawable.pScreen)->ReparentWindow (pWin,
 | |
| 							      pPriorParent);
 | |
|   
 | |
|   /* Update the Windows window associated with this X window */
 | |
|   winUpdateWindowsWindow (pWin);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * RestackWindow - Shuffle the z-order of a window
 | |
|  */
 | |
| 
 | |
| void
 | |
| winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib)
 | |
| {
 | |
|   WindowPtr		pPrevWin;
 | |
|   UINT			uFlags;
 | |
|   HWND			hInsertAfter;
 | |
|   HWND                  hWnd = NULL;
 | |
|   winWindowPriv(pWin);
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("winRestackMultiWindow - %08x\n", pWin);
 | |
| #endif
 | |
|   
 | |
|   /* Call any wrapped RestackWindow function */
 | |
|   if (winGetScreenPriv(pWin->drawable.pScreen)->RestackWindow)
 | |
|     winGetScreenPriv(pWin->drawable.pScreen)->RestackWindow (pWin,
 | |
| 							     pOldNextSib);
 | |
|   
 | |
|   if (winGetScreenPriv(pWin->drawable.pScreen)->fRestacking)
 | |
|     return;
 | |
| 
 | |
|   /* Bail out if no window privates or window handle is invalid */
 | |
|   if (!pWinPriv || !pWinPriv->hWnd)
 | |
|     return;
 | |
| 
 | |
|   /* Get a pointer to our previous sibling window */
 | |
|   pPrevWin = pWin->prevSib;
 | |
| 
 | |
|   /*
 | |
|    * Look for a sibling window with
 | |
|    * valid privates and window handle
 | |
|    */
 | |
|   while (pPrevWin
 | |
| 	 && !winGetWindowPriv(pPrevWin)
 | |
| 	 && !winGetWindowPriv(pPrevWin)->hWnd)
 | |
|     pPrevWin = pPrevWin->prevSib;
 | |
|       
 | |
|   /* Check if we found a valid sibling */
 | |
|   if (pPrevWin)
 | |
|     {
 | |
|       /* Valid sibling - get handle to insert window after */
 | |
|       hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd;
 | |
|       uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
 | |
|   
 | |
|       hWnd = GetNextWindow (pWinPriv->hWnd, GW_HWNDPREV);
 | |
| 
 | |
|       do
 | |
| 	{
 | |
| 	  if (GetProp (hWnd, WIN_WINDOW_PROP))
 | |
| 	    {
 | |
| 	      if (hWnd == winGetWindowPriv(pPrevWin)->hWnd)
 | |
| 		{
 | |
| 		  uFlags |= SWP_NOZORDER;
 | |
| 		}
 | |
| 	      break;
 | |
| 	    }
 | |
| 	  hWnd = GetNextWindow (hWnd, GW_HWNDPREV);
 | |
| 	}
 | |
|       while (hWnd);
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       /* No valid sibling - make this window the top window */
 | |
|       hInsertAfter = HWND_TOP;
 | |
|       uFlags = SWP_NOMOVE | SWP_NOSIZE;
 | |
|     }
 | |
|       
 | |
|   /* Perform the restacking operation in Windows */
 | |
|   SetWindowPos (pWinPriv->hWnd,
 | |
| 		hInsertAfter,
 | |
| 		0, 0,
 | |
| 		0, 0,
 | |
| 		uFlags);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * winCreateWindowsWindow - Create a Windows window associated with an X window
 | |
|  */
 | |
| 
 | |
| static void
 | |
| winCreateWindowsWindow (WindowPtr pWin)
 | |
| {
 | |
|   int                   iX, iY;
 | |
|   int			iWidth;
 | |
|   int			iHeight;
 | |
|   int                   iBorder;
 | |
|   HWND			hWnd;
 | |
|   WNDCLASS		wc;
 | |
|   winWindowPriv(pWin);
 | |
|   HICON                 hIcon;
 | |
| #define CLASS_NAME_LENGTH 512
 | |
|   char                  pszClass[CLASS_NAME_LENGTH], pszWindowID[12];
 | |
|   char                  *res_name, *res_class, *res_role;
 | |
|   static int		s_iWindowID = 0;
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin);
 | |
| #endif
 | |
| 
 | |
|   iBorder = wBorderWidth (pWin);
 | |
|   
 | |
|   iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
 | |
|   iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
 | |
|   
 | |
|   iWidth = pWin->drawable.width;
 | |
|   iHeight = pWin->drawable.height;
 | |
| 
 | |
|   /* Load default X icon in case it's not ready yet */
 | |
|   if (!g_hiconX)
 | |
|     g_hiconX = (HICON)winOverrideDefaultIcon();
 | |
|   
 | |
|   if (!g_hiconX)
 | |
|     g_hiconX = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN));
 | |
|   
 | |
|   /* Try and get the icon from WM_HINTS */
 | |
|   hIcon = winXIconToHICON (pWin);
 | |
|   
 | |
|   /* Use default X icon if no icon loaded from WM_HINTS */
 | |
|   if (!hIcon)
 | |
|     hIcon = g_hiconX;
 | |
| 
 | |
|   /* Set standard class name prefix so we can identify window easily */
 | |
|   strncpy (pszClass, WINDOW_CLASS_X, strlen (WINDOW_CLASS_X));
 | |
| 
 | |
|   if (winMultiWindowGetClassHint (pWin, &res_name, &res_class))
 | |
|     {
 | |
|       strncat (pszClass, "-", 1);
 | |
|       strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass));
 | |
|       strncat (pszClass, "-", 1);
 | |
|       strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass));
 | |
|       
 | |
|       /* Check if a window class is provided by the WM_WINDOW_ROLE property,
 | |
|        * if not use the WM_CLASS information.
 | |
|        * For further information see:
 | |
|        * http://tronche.com/gui/x/icccm/sec-5.html
 | |
|        */ 
 | |
|       if (winMultiWindowGetWindowRole (pWin, &res_role) )
 | |
| 	{
 | |
| 	  strcat (pszClass, "-");
 | |
| 	  strcat (pszClass, res_role);
 | |
| 	  free (res_role);
 | |
| 	}
 | |
| 
 | |
|       free (res_name);
 | |
|       free (res_class);
 | |
|     }
 | |
| 
 | |
|   /* Add incrementing window ID to make unique class name */
 | |
|   sprintf (pszWindowID, "-%x", s_iWindowID++);
 | |
|   strcat (pszClass, pszWindowID);
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("winCreateWindowsWindow - Creating class: %s\n", pszClass);
 | |
| #endif
 | |
| 
 | |
|   /* Setup our window class */
 | |
|   wc.style = CS_HREDRAW | CS_VREDRAW;
 | |
|   wc.lpfnWndProc = winTopLevelWindowProc;
 | |
|   wc.cbClsExtra = 0;
 | |
|   wc.cbWndExtra = 0;
 | |
|   wc.hInstance = g_hInstance;
 | |
|   wc.hIcon = hIcon;
 | |
|   wc.hCursor = 0;
 | |
|   wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
 | |
|   wc.lpszMenuName = NULL;
 | |
|   wc.lpszClassName = pszClass;
 | |
|   RegisterClass (&wc);
 | |
| 
 | |
|   /* Create the window */
 | |
|   hWnd = CreateWindowExA (WS_EX_TOOLWINDOW,	/* Extended styles */
 | |
| 			  pszClass,		/* Class name */
 | |
| 			  WINDOW_TITLE_X,	/* Window name */
 | |
| 			  WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
 | |
| 			  iX,			/* Horizontal position */
 | |
| 			  iY,			/* Vertical position */
 | |
| 			  iWidth,		/* Right edge */ 
 | |
| 			  iHeight,		/* Bottom edge */
 | |
| 			  (HWND) NULL,		/* No parent or owner window */
 | |
| 			  (HMENU) NULL,		/* No menu */
 | |
| 			  GetModuleHandle (NULL), /* Instance handle */
 | |
| 			  pWin);		/* ScreenPrivates */
 | |
|   if (hWnd == NULL)
 | |
|     {
 | |
|       ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
 | |
| 	      GetLastError ());
 | |
|     }
 | |
|   
 | |
|   pWinPriv->hWnd = hWnd;
 | |
| 
 | |
|   /* Cause the "Always On Top" to be added in main WNDPROC */
 | |
|   PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0);
 | |
|   
 | |
|   SetProp (pWinPriv->hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin));
 | |
| 
 | |
|   /* Flag that this Windows window handles its own activation */
 | |
|   SetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * winDestroyWindowsWindow - Destroy a Windows window associated
 | |
|  * with an X window
 | |
|  */
 | |
| 
 | |
| static void
 | |
| winDestroyWindowsWindow (WindowPtr pWin)
 | |
| {
 | |
|   MSG			msg;
 | |
|   winWindowPriv(pWin);
 | |
|   HICON			hiconClass;
 | |
|   HMODULE		hInstance;
 | |
|   int			iReturn;
 | |
|   char			pszClass[512];
 | |
|   
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("winDestroyWindowsWindow\n");
 | |
| #endif
 | |
| 
 | |
|   /* Bail out if the Windows window handle is invalid */
 | |
|   if (pWinPriv->hWnd == NULL)
 | |
|     return;
 | |
| 
 | |
|   SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, 0);
 | |
| 
 | |
|   /* Store the info we need to destroy after this window is gone */
 | |
|   hInstance = (HINSTANCE) GetClassLong (pWinPriv->hWnd, GCL_HMODULE);
 | |
|   hiconClass = (HICON) GetClassLong (pWinPriv->hWnd, GCL_HICON);
 | |
|   iReturn = GetClassName (pWinPriv->hWnd, pszClass, 512);
 | |
|   
 | |
|   /* Destroy the Windows window */
 | |
|   DestroyWindow (pWinPriv->hWnd);
 | |
| 
 | |
|   /* Null our handle to the Window so referencing it will cause an error */
 | |
|   pWinPriv->hWnd = NULL;
 | |
|   
 | |
|   /* Process all messages on our queue */
 | |
|   while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
 | |
|     {
 | |
|       if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg))
 | |
| 	{
 | |
| 	  DispatchMessage (&msg);
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   /* Only if we were able to get the name */
 | |
|   if (iReturn)
 | |
|     { 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       ErrorF ("winDestroyWindowsWindow - Unregistering %s: ", pszClass);
 | |
| #endif
 | |
|       iReturn = UnregisterClass (pszClass, hInstance);
 | |
|       
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       ErrorF ("winDestroyWindowsWindow - %d Deleting Icon: ", iReturn);
 | |
| #endif
 | |
|       
 | |
|       /* Only delete if it's not the default */
 | |
|       if (hiconClass != g_hiconX &&
 | |
| 	  !winIconIsOverride((unsigned long)hiconClass))
 | |
| 	{ 
 | |
| 	  iReturn = DestroyIcon (hiconClass);
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
| 	  ErrorF ("winDestroyWindowsWindow - %d\n", iReturn);
 | |
| #endif
 | |
| 	}
 | |
|     }
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("-winDestroyWindowsWindow\n");
 | |
| #endif
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * winUpdateWindowsWindow - Redisplay/redraw a Windows window
 | |
|  * associated with an X window
 | |
|  */
 | |
| 
 | |
| static void
 | |
| winUpdateWindowsWindow (WindowPtr pWin)
 | |
| {
 | |
|   winWindowPriv(pWin);
 | |
|   HWND			hWnd = pWinPriv->hWnd;
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("winUpdateWindowsWindow\n");
 | |
| #endif
 | |
| 
 | |
|   /* Check if the Windows window's parents have been destroyed */
 | |
|   if (pWin->parent != NULL
 | |
|       && pWin->parent->parent == NULL
 | |
|       && pWin->mapped)
 | |
|     {
 | |
|       /* Create the Windows window if it has been destroyed */
 | |
|       if (hWnd == NULL)
 | |
| 	{
 | |
| 	  winCreateWindowsWindow (pWin);
 | |
| 	  assert (pWinPriv->hWnd != NULL);
 | |
| 	}
 | |
| 
 | |
|       /* Display the window without activating it */
 | |
|       ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE);
 | |
| 
 | |
|       /* Send first paint message */
 | |
|       UpdateWindow (pWinPriv->hWnd);
 | |
|     }
 | |
|   else if (hWnd != NULL)
 | |
|     {
 | |
|       /* Destroy the Windows window if its parents are destroyed */
 | |
|       winDestroyWindowsWindow (pWin);
 | |
|       assert (pWinPriv->hWnd == NULL);
 | |
|     }
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("-winUpdateWindowsWindow\n");
 | |
| #endif
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * winGetWindowID - 
 | |
|  */
 | |
| 
 | |
| XID
 | |
| winGetWindowID (WindowPtr pWin)
 | |
| {
 | |
|   WindowIDPairRec	wi = {pWin, 0};
 | |
|   ClientPtr		c = wClient(pWin);
 | |
|   
 | |
|   /* */
 | |
|   FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi);
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("winGetWindowID - Window ID: %d\n", wi.id);
 | |
| #endif
 | |
| 
 | |
|   return wi.id;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * winMoveXWindow - 
 | |
|  */
 | |
| 
 | |
| void
 | |
| winMoveXWindow (WindowPtr pWin, int x, int y)
 | |
| {
 | |
|   XID *vlist = malloc(sizeof(long)*2);
 | |
| 
 | |
|   (CARD32*)vlist[0] = x;
 | |
|   (CARD32*)vlist[1] = y;
 | |
|   ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin));
 | |
|   free(vlist);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * winResizeXWindow - 
 | |
|  */
 | |
| 
 | |
| void
 | |
| winResizeXWindow (WindowPtr pWin, int w, int h)
 | |
| {
 | |
|   XID *vlist = malloc(sizeof(long)*2);
 | |
| 
 | |
|   (CARD32*)vlist[0] = w;
 | |
|   (CARD32*)vlist[1] = h;
 | |
|   ConfigureWindow (pWin, CWWidth | CWHeight, vlist, wClient(pWin));
 | |
|   free(vlist);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * winFindWindow - 
 | |
|  */
 | |
| 
 | |
| static void
 | |
| winFindWindow (pointer value, XID id, pointer cdata)
 | |
| {
 | |
|   WindowIDPairPtr	wi = (WindowIDPairPtr)cdata;
 | |
| 
 | |
|   if (value == wi->value)
 | |
|     {
 | |
|       wi->id = id;
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| #if 0
 | |
| /*
 | |
|  * winRestackXWindow - 
 | |
|  */
 | |
| 
 | |
| static void
 | |
| winRestackXWindow (WindowPtr pWin, int smode)
 | |
| {
 | |
|   XID *vlist = malloc(sizeof(unsigned long));
 | |
| 
 | |
|   if (vlist == NULL)
 | |
|     {
 | |
|       ErrorF ("winRestackXWindow - malloc () failed\n");
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|   if (pWin == NULL)
 | |
|     {
 | |
|       ErrorF ("winRestackXWindow - NULL window\n");
 | |
|       free(vlist);
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|   *((unsigned long*)vlist) = smode;
 | |
|   ConfigureWindow (pWin, CWStackMode, vlist, wClient(pWin));
 | |
| 
 | |
|   free(vlist);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * winReorderWindowsMultiWindow - 
 | |
|  */
 | |
| 
 | |
| void
 | |
| winReorderWindowsMultiWindow (ScreenPtr pScreen)
 | |
| {
 | |
|   winScreenPriv(pScreen);
 | |
|   HWND hwnd = NULL;
 | |
|   WindowPtr pWin = NULL;
 | |
|   WindowPtr pWinSib = NULL;
 | |
| 
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|   ErrorF ("winOrderWindowsMultiWindow\n");
 | |
| #endif
 | |
| 
 | |
|   pScreenPriv->fRestacking = TRUE;
 | |
| 
 | |
|   if (pScreenPriv->fWindowOrderChanged)
 | |
|     {
 | |
| #if CYGMULTIWINDOW_DEBUG
 | |
|       ErrorF ("winOrderWindowsMultiWindow - Need to restack\n");
 | |
| #endif
 | |
|       hwnd = GetTopWindow (NULL);
 | |
| 
 | |
|       while (hwnd)
 | |
| 	{
 | |
| 	  if (GetProp (hwnd, WIN_WINDOW_PROP))
 | |
| 	    {
 | |
| 	      pWinSib = pWin;
 | |
| 	      pWin = GetProp (hwnd, WIN_WINDOW_PROP);
 | |
| 	      
 | |
| 	      if (pWinSib)
 | |
| 		{
 | |
| 		  XID *vlist = malloc (sizeof(long) * 2);
 | |
| 		  
 | |
| 		  if (vlist == NULL)
 | |
| 		    {
 | |
| 		      ErrorF ("winOrderWindowsMultiWindow - malloc () "
 | |
| 			      "failed\n");
 | |
| 		      return;
 | |
| 		    }
 | |
| 		  
 | |
| 		  ((long*)vlist)[0] = winGetWindowID (pWinSib);
 | |
| 		  ((long*)vlist)[1] = Below;
 | |
| 
 | |
| 		  ConfigureWindow (pWin, CWSibling | CWStackMode,
 | |
| 				   vlist, wClient(pWin));
 | |
| 		  
 | |
| 		  free (vlist);
 | |
| 		}
 | |
| 	    }
 | |
| 	  hwnd = GetNextWindow (hwnd, GW_HWNDNEXT);
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   pScreenPriv->fRestacking = FALSE;
 | |
|   pScreenPriv->fWindowOrderChanged = FALSE;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE
 | |
|  */
 | |
| 
 | |
| void
 | |
| winMinimizeWindow (Window id)
 | |
| {
 | |
|   WindowPtr		pWin;
 | |
|   winPrivWinPtr	pWinPriv;
 | |
|   
 | |
|   pWin = LookupIDByType (id, RT_WINDOW);
 | |
|   
 | |
|   pWinPriv = winGetWindowPriv (pWin);
 | |
|   
 | |
|   ShowWindow (pWinPriv->hWnd, SW_MINIMIZE);
 | |
| }
 |