xref: /OK3568_Linux_fs/external/xserver/hw/xwin/winmultiwindowwindow.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
3*4882a593Smuzhiyun  *Copyright (C) Colin Harrison 2005-2008
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  *Permission is hereby granted, free of charge, to any person obtaining
6*4882a593Smuzhiyun  * a copy of this software and associated documentation files (the
7*4882a593Smuzhiyun  *"Software"), to deal in the Software without restriction, including
8*4882a593Smuzhiyun  *without limitation the rights to use, copy, modify, merge, publish,
9*4882a593Smuzhiyun  *distribute, sublicense, and/or sell copies of the Software, and to
10*4882a593Smuzhiyun  *permit persons to whom the Software is furnished to do so, subject to
11*4882a593Smuzhiyun  *the following conditions:
12*4882a593Smuzhiyun  *
13*4882a593Smuzhiyun  *The above copyright notice and this permission notice shall be
14*4882a593Smuzhiyun  *included in all copies or substantial portions of the Software.
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17*4882a593Smuzhiyun  *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18*4882a593Smuzhiyun  *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19*4882a593Smuzhiyun  *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
20*4882a593Smuzhiyun  *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
21*4882a593Smuzhiyun  *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22*4882a593Smuzhiyun  *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23*4882a593Smuzhiyun  *
24*4882a593Smuzhiyun  *Except as contained in this notice, the name of the XFree86 Project
25*4882a593Smuzhiyun  *shall not be used in advertising or otherwise to promote the sale, use
26*4882a593Smuzhiyun  *or other dealings in this Software without prior written authorization
27*4882a593Smuzhiyun  *from the XFree86 Project.
28*4882a593Smuzhiyun  *
29*4882a593Smuzhiyun  * Authors:	Kensuke Matsuzaki
30*4882a593Smuzhiyun  *		Earle F. Philhower, III
31*4882a593Smuzhiyun  *		Harold L Hunt II
32*4882a593Smuzhiyun  *              Colin Harrison
33*4882a593Smuzhiyun  */
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #ifdef HAVE_XWIN_CONFIG_H
36*4882a593Smuzhiyun #include <xwin-config.h>
37*4882a593Smuzhiyun #endif
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #include "win.h"
40*4882a593Smuzhiyun #include "dixevents.h"
41*4882a593Smuzhiyun #include "winmultiwindowclass.h"
42*4882a593Smuzhiyun #include "winmultiwindowicons.h"
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun /*
45*4882a593Smuzhiyun  * Prototypes for local functions
46*4882a593Smuzhiyun  */
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun void
49*4882a593Smuzhiyun  winCreateWindowsWindow(WindowPtr pWin);
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun static void
52*4882a593Smuzhiyun  winDestroyWindowsWindow(WindowPtr pWin);
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun static void
55*4882a593Smuzhiyun  winUpdateWindowsWindow(WindowPtr pWin);
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun static void
58*4882a593Smuzhiyun  winFindWindow(void *value, XID id, void *cdata);
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun static
61*4882a593Smuzhiyun     void
winInitMultiWindowClass(void)62*4882a593Smuzhiyun winInitMultiWindowClass(void)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun     static wATOM atomXWinClass = 0;
65*4882a593Smuzhiyun     WNDCLASSEX wcx;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun     if (atomXWinClass == 0) {
68*4882a593Smuzhiyun         HICON hIcon, hIconSmall;
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun         /* Load the default icons */
71*4882a593Smuzhiyun         winSelectIcons(&hIcon, &hIconSmall);
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun         /* Setup our window class */
74*4882a593Smuzhiyun         wcx.cbSize = sizeof(WNDCLASSEX);
75*4882a593Smuzhiyun         wcx.style = CS_HREDRAW | CS_VREDRAW | (g_fNativeGl ? CS_OWNDC : 0);
76*4882a593Smuzhiyun         wcx.lpfnWndProc = winTopLevelWindowProc;
77*4882a593Smuzhiyun         wcx.cbClsExtra = 0;
78*4882a593Smuzhiyun         wcx.cbWndExtra = 0;
79*4882a593Smuzhiyun         wcx.hInstance = g_hInstance;
80*4882a593Smuzhiyun         wcx.hIcon = hIcon;
81*4882a593Smuzhiyun         wcx.hCursor = 0;
82*4882a593Smuzhiyun         wcx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
83*4882a593Smuzhiyun         wcx.lpszMenuName = NULL;
84*4882a593Smuzhiyun         wcx.lpszClassName = WINDOW_CLASS_X;
85*4882a593Smuzhiyun         wcx.hIconSm = hIconSmall;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
88*4882a593Smuzhiyun         ErrorF("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X);
89*4882a593Smuzhiyun #endif
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun         atomXWinClass = RegisterClassEx(&wcx);
92*4882a593Smuzhiyun     }
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun /*
96*4882a593Smuzhiyun  * CreateWindow - See Porting Layer Definition - p. 37
97*4882a593Smuzhiyun  */
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun Bool
winCreateWindowMultiWindow(WindowPtr pWin)100*4882a593Smuzhiyun winCreateWindowMultiWindow(WindowPtr pWin)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun     Bool fResult = TRUE;
103*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun     winWindowPriv(pWin);
106*4882a593Smuzhiyun     winScreenPriv(pScreen);
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
109*4882a593Smuzhiyun     winTrace("winCreateWindowMultiWindow - pWin: %p\n", pWin);
110*4882a593Smuzhiyun #endif
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun     WIN_UNWRAP(CreateWindow);
113*4882a593Smuzhiyun     fResult = (*pScreen->CreateWindow) (pWin);
114*4882a593Smuzhiyun     WIN_WRAP(CreateWindow, winCreateWindowMultiWindow);
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun     /* Initialize some privates values */
117*4882a593Smuzhiyun     pWinPriv->hRgn = NULL;
118*4882a593Smuzhiyun     pWinPriv->hWnd = NULL;
119*4882a593Smuzhiyun     pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen);
120*4882a593Smuzhiyun     pWinPriv->fXKilled = FALSE;
121*4882a593Smuzhiyun #ifdef XWIN_GLX_WINDOWS
122*4882a593Smuzhiyun     pWinPriv->fWglUsed = FALSE;
123*4882a593Smuzhiyun #endif
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun     return fResult;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun /*
129*4882a593Smuzhiyun  * DestroyWindow - See Porting Layer Definition - p. 37
130*4882a593Smuzhiyun  */
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun Bool
winDestroyWindowMultiWindow(WindowPtr pWin)133*4882a593Smuzhiyun winDestroyWindowMultiWindow(WindowPtr pWin)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun     Bool fResult = TRUE;
136*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun     winWindowPriv(pWin);
139*4882a593Smuzhiyun     winScreenPriv(pScreen);
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
142*4882a593Smuzhiyun     ErrorF("winDestroyWindowMultiWindow - pWin: %p\n", pWin);
143*4882a593Smuzhiyun #endif
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun     WIN_UNWRAP(DestroyWindow);
146*4882a593Smuzhiyun     fResult = (*pScreen->DestroyWindow) (pWin);
147*4882a593Smuzhiyun     WIN_WRAP(DestroyWindow, winDestroyWindowMultiWindow);
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun     /* Flag that the window has been destroyed */
150*4882a593Smuzhiyun     pWinPriv->fXKilled = TRUE;
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun     /* Kill the MS Windows window associated with this window */
153*4882a593Smuzhiyun     winDestroyWindowsWindow(pWin);
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun     return fResult;
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun /*
159*4882a593Smuzhiyun  * PositionWindow - See Porting Layer Definition - p. 37
160*4882a593Smuzhiyun  *
161*4882a593Smuzhiyun  * This function adjusts the position and size of Windows window
162*4882a593Smuzhiyun  * with respect to the underlying X window.  This is the inverse
163*4882a593Smuzhiyun  * of winAdjustXWindow, which adjusts X window to Windows window.
164*4882a593Smuzhiyun  */
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun Bool
winPositionWindowMultiWindow(WindowPtr pWin,int x,int y)167*4882a593Smuzhiyun winPositionWindowMultiWindow(WindowPtr pWin, int x, int y)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun     Bool fResult = TRUE;
170*4882a593Smuzhiyun     int iX, iY, iWidth, iHeight;
171*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun     winWindowPriv(pWin);
174*4882a593Smuzhiyun     winScreenPriv(pScreen);
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun     HWND hWnd = pWinPriv->hWnd;
177*4882a593Smuzhiyun     RECT rcNew;
178*4882a593Smuzhiyun     RECT rcOld;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
181*4882a593Smuzhiyun     RECT rcClient;
182*4882a593Smuzhiyun     RECT *lpRc;
183*4882a593Smuzhiyun #endif
184*4882a593Smuzhiyun     DWORD dwExStyle;
185*4882a593Smuzhiyun     DWORD dwStyle;
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
188*4882a593Smuzhiyun     winTrace("winPositionWindowMultiWindow - pWin: %p\n", pWin);
189*4882a593Smuzhiyun #endif
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun     WIN_UNWRAP(PositionWindow);
192*4882a593Smuzhiyun     fResult = (*pScreen->PositionWindow) (pWin, x, y);
193*4882a593Smuzhiyun     WIN_WRAP(PositionWindow, winPositionWindowMultiWindow);
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
196*4882a593Smuzhiyun     ErrorF("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n", x, y);
197*4882a593Smuzhiyun #endif
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun     /* Bail out if the Windows window handle is bad */
200*4882a593Smuzhiyun     if (!hWnd) {
201*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
202*4882a593Smuzhiyun         ErrorF("\timmediately return since hWnd is NULL\n");
203*4882a593Smuzhiyun #endif
204*4882a593Smuzhiyun         return fResult;
205*4882a593Smuzhiyun     }
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun     /* Get the Windows window style and extended style */
208*4882a593Smuzhiyun     dwExStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);
209*4882a593Smuzhiyun     dwStyle = GetWindowLongPtr(hWnd, GWL_STYLE);
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun     /* Get the X and Y location of the X window */
212*4882a593Smuzhiyun     iX = pWin->drawable.x + GetSystemMetrics(SM_XVIRTUALSCREEN);
213*4882a593Smuzhiyun     iY = pWin->drawable.y + GetSystemMetrics(SM_YVIRTUALSCREEN);
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun     /* Get the height and width of the X window */
216*4882a593Smuzhiyun     iWidth = pWin->drawable.width;
217*4882a593Smuzhiyun     iHeight = pWin->drawable.height;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun     /* Store the origin, height, and width in a rectangle structure */
220*4882a593Smuzhiyun     SetRect(&rcNew, iX, iY, iX + iWidth, iY + iHeight);
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
223*4882a593Smuzhiyun     lpRc = &rcNew;
224*4882a593Smuzhiyun     ErrorF("winPositionWindowMultiWindow - drawable (%d, %d)-(%d, %d)\n",
225*4882a593Smuzhiyun            (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
226*4882a593Smuzhiyun #endif
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun     /*
229*4882a593Smuzhiyun      * Calculate the required size of the Windows window rectangle,
230*4882a593Smuzhiyun      * given the size of the Windows window client area.
231*4882a593Smuzhiyun      */
232*4882a593Smuzhiyun     AdjustWindowRectEx(&rcNew, dwStyle, FALSE, dwExStyle);
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun     /* Get a rectangle describing the old Windows window */
235*4882a593Smuzhiyun     GetWindowRect(hWnd, &rcOld);
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
238*4882a593Smuzhiyun     /* Get a rectangle describing the Windows window client area */
239*4882a593Smuzhiyun     GetClientRect(hWnd, &rcClient);
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun     lpRc = &rcNew;
242*4882a593Smuzhiyun     ErrorF("winPositionWindowMultiWindow - rcNew (%d, %d)-(%d, %d)\n",
243*4882a593Smuzhiyun            (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun     lpRc = &rcOld;
246*4882a593Smuzhiyun     ErrorF("winPositionWindowMultiWindow - rcOld (%d, %d)-(%d, %d)\n",
247*4882a593Smuzhiyun            (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun     lpRc = &rcClient;
250*4882a593Smuzhiyun     ErrorF("rcClient (%d, %d)-(%d, %d)\n",
251*4882a593Smuzhiyun            (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
252*4882a593Smuzhiyun #endif
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun     /* Check if the old rectangle and new rectangle are the same */
255*4882a593Smuzhiyun     if (!EqualRect(&rcNew, &rcOld)) {
256*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
257*4882a593Smuzhiyun         ErrorF("winPositionWindowMultiWindow - Need to move\n");
258*4882a593Smuzhiyun #endif
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
261*4882a593Smuzhiyun         ErrorF("\tMoveWindow to (%d, %d) - %dx%d\n", (int)rcNew.left, (int)rcNew.top,
262*4882a593Smuzhiyun                (int)(rcNew.right - rcNew.left), (int)(rcNew.bottom - rcNew.top));
263*4882a593Smuzhiyun #endif
264*4882a593Smuzhiyun         /* Change the position and dimensions of the Windows window */
265*4882a593Smuzhiyun         MoveWindow(hWnd,
266*4882a593Smuzhiyun                    rcNew.left, rcNew.top,
267*4882a593Smuzhiyun                    rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, TRUE);
268*4882a593Smuzhiyun     }
269*4882a593Smuzhiyun     else {
270*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
271*4882a593Smuzhiyun         ErrorF("winPositionWindowMultiWindow - Not need to move\n");
272*4882a593Smuzhiyun #endif
273*4882a593Smuzhiyun     }
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun     return fResult;
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun /*
279*4882a593Smuzhiyun  * ChangeWindowAttributes - See Porting Layer Definition - p. 37
280*4882a593Smuzhiyun  */
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun Bool
winChangeWindowAttributesMultiWindow(WindowPtr pWin,unsigned long mask)283*4882a593Smuzhiyun winChangeWindowAttributesMultiWindow(WindowPtr pWin, unsigned long mask)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun     Bool fResult = TRUE;
286*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun     winScreenPriv(pScreen);
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
291*4882a593Smuzhiyun     ErrorF("winChangeWindowAttributesMultiWindow - pWin: %p\n", pWin);
292*4882a593Smuzhiyun #endif
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun     WIN_UNWRAP(ChangeWindowAttributes);
295*4882a593Smuzhiyun     fResult = (*pScreen->ChangeWindowAttributes) (pWin, mask);
296*4882a593Smuzhiyun     WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesMultiWindow);
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun     /*
299*4882a593Smuzhiyun      * NOTE: We do not currently need to do anything here.
300*4882a593Smuzhiyun      */
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun     return fResult;
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun /*
306*4882a593Smuzhiyun  * UnmapWindow - See Porting Layer Definition - p. 37
307*4882a593Smuzhiyun  * Also referred to as UnrealizeWindow
308*4882a593Smuzhiyun  */
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun Bool
winUnmapWindowMultiWindow(WindowPtr pWin)311*4882a593Smuzhiyun winUnmapWindowMultiWindow(WindowPtr pWin)
312*4882a593Smuzhiyun {
313*4882a593Smuzhiyun     Bool fResult = TRUE;
314*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun     winWindowPriv(pWin);
317*4882a593Smuzhiyun     winScreenPriv(pScreen);
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
320*4882a593Smuzhiyun     ErrorF("winUnmapWindowMultiWindow - pWin: %p\n", pWin);
321*4882a593Smuzhiyun #endif
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun     WIN_UNWRAP(UnrealizeWindow);
324*4882a593Smuzhiyun     fResult = (*pScreen->UnrealizeWindow) (pWin);
325*4882a593Smuzhiyun     WIN_WRAP(UnrealizeWindow, winUnmapWindowMultiWindow);
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun     /* Flag that the window has been killed */
328*4882a593Smuzhiyun     pWinPriv->fXKilled = TRUE;
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun     /* Destroy the Windows window associated with this X window */
331*4882a593Smuzhiyun     winDestroyWindowsWindow(pWin);
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun     return fResult;
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun /*
337*4882a593Smuzhiyun  * MapWindow - See Porting Layer Definition - p. 37
338*4882a593Smuzhiyun  * Also referred to as RealizeWindow
339*4882a593Smuzhiyun  */
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun Bool
winMapWindowMultiWindow(WindowPtr pWin)342*4882a593Smuzhiyun winMapWindowMultiWindow(WindowPtr pWin)
343*4882a593Smuzhiyun {
344*4882a593Smuzhiyun     Bool fResult = TRUE;
345*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun     winWindowPriv(pWin);
348*4882a593Smuzhiyun     winScreenPriv(pScreen);
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
351*4882a593Smuzhiyun     ErrorF("winMapWindowMultiWindow - pWin: %p\n", pWin);
352*4882a593Smuzhiyun #endif
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun     WIN_UNWRAP(RealizeWindow);
355*4882a593Smuzhiyun     fResult = (*pScreen->RealizeWindow) (pWin);
356*4882a593Smuzhiyun     WIN_WRAP(RealizeWindow, winMapWindowMultiWindow);
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun     /* Flag that this window has not been destroyed */
359*4882a593Smuzhiyun     pWinPriv->fXKilled = FALSE;
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun     /* Refresh/redisplay the Windows window associated with this X window */
362*4882a593Smuzhiyun     winUpdateWindowsWindow(pWin);
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun     /* Update the Windows window's shape */
365*4882a593Smuzhiyun     winReshapeMultiWindow(pWin);
366*4882a593Smuzhiyun     winUpdateRgnMultiWindow(pWin);
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun     return fResult;
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun /*
372*4882a593Smuzhiyun  * ReparentWindow - See Porting Layer Definition - p. 42
373*4882a593Smuzhiyun  */
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun void
winReparentWindowMultiWindow(WindowPtr pWin,WindowPtr pPriorParent)376*4882a593Smuzhiyun winReparentWindowMultiWindow(WindowPtr pWin, WindowPtr pPriorParent)
377*4882a593Smuzhiyun {
378*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun     winScreenPriv(pScreen);
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun     winDebug
383*4882a593Smuzhiyun         ("winReparentMultiWindow - pWin:%p XID:0x%x, reparent from pWin:%p XID:0x%x to pWin:%p XID:0x%x\n",
384*4882a593Smuzhiyun          pWin, (unsigned int)pWin->drawable.id,
385*4882a593Smuzhiyun          pPriorParent, (unsigned int)pPriorParent->drawable.id,
386*4882a593Smuzhiyun          pWin->parent, (unsigned int)pWin->parent->drawable.id);
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun     WIN_UNWRAP(ReparentWindow);
389*4882a593Smuzhiyun     if (pScreen->ReparentWindow)
390*4882a593Smuzhiyun         (*pScreen->ReparentWindow) (pWin, pPriorParent);
391*4882a593Smuzhiyun     WIN_WRAP(ReparentWindow, winReparentWindowMultiWindow);
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun     /* Update the Windows window associated with this X window */
394*4882a593Smuzhiyun     winUpdateWindowsWindow(pWin);
395*4882a593Smuzhiyun }
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun /*
398*4882a593Smuzhiyun  * RestackWindow - Shuffle the z-order of a window
399*4882a593Smuzhiyun  */
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun void
winRestackWindowMultiWindow(WindowPtr pWin,WindowPtr pOldNextSib)402*4882a593Smuzhiyun winRestackWindowMultiWindow(WindowPtr pWin, WindowPtr pOldNextSib)
403*4882a593Smuzhiyun {
404*4882a593Smuzhiyun #if 0
405*4882a593Smuzhiyun     WindowPtr pPrevWin;
406*4882a593Smuzhiyun     UINT uFlags;
407*4882a593Smuzhiyun     HWND hInsertAfter;
408*4882a593Smuzhiyun     HWND hWnd = NULL;
409*4882a593Smuzhiyun #endif
410*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun     winScreenPriv(pScreen);
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
415*4882a593Smuzhiyun     winTrace("winRestackMultiWindow - %p\n", pWin);
416*4882a593Smuzhiyun #endif
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun     WIN_UNWRAP(RestackWindow);
419*4882a593Smuzhiyun     if (pScreen->RestackWindow)
420*4882a593Smuzhiyun         (*pScreen->RestackWindow) (pWin, pOldNextSib);
421*4882a593Smuzhiyun     WIN_WRAP(RestackWindow, winRestackWindowMultiWindow);
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun #if 1
424*4882a593Smuzhiyun     /*
425*4882a593Smuzhiyun      * Calling winReorderWindowsMultiWindow here means our window manager
426*4882a593Smuzhiyun      * (i.e. Windows Explorer) has initiative to determine Z order.
427*4882a593Smuzhiyun      */
428*4882a593Smuzhiyun     if (pWin->nextSib != pOldNextSib)
429*4882a593Smuzhiyun         winReorderWindowsMultiWindow();
430*4882a593Smuzhiyun #else
431*4882a593Smuzhiyun     /* Bail out if no window privates or window handle is invalid */
432*4882a593Smuzhiyun     if (!pWinPriv || !pWinPriv->hWnd)
433*4882a593Smuzhiyun         return;
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun     /* Get a pointer to our previous sibling window */
436*4882a593Smuzhiyun     pPrevWin = pWin->prevSib;
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun     /*
439*4882a593Smuzhiyun      * Look for a sibling window with
440*4882a593Smuzhiyun      * valid privates and window handle
441*4882a593Smuzhiyun      */
442*4882a593Smuzhiyun     while (pPrevWin && !winGetWindowPriv(pPrevWin)
443*4882a593Smuzhiyun            && !winGetWindowPriv(pPrevWin)->hWnd)
444*4882a593Smuzhiyun         pPrevWin = pPrevWin->prevSib;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun     /* Check if we found a valid sibling */
447*4882a593Smuzhiyun     if (pPrevWin) {
448*4882a593Smuzhiyun         /* Valid sibling - get handle to insert window after */
449*4882a593Smuzhiyun         hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd;
450*4882a593Smuzhiyun         uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun         hWnd = GetNextWindow(pWinPriv->hWnd, GW_HWNDPREV);
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun         do {
455*4882a593Smuzhiyun             if (GetProp(hWnd, WIN_WINDOW_PROP)) {
456*4882a593Smuzhiyun                 if (hWnd == winGetWindowPriv(pPrevWin)->hWnd) {
457*4882a593Smuzhiyun                     uFlags |= SWP_NOZORDER;
458*4882a593Smuzhiyun                 }
459*4882a593Smuzhiyun                 break;
460*4882a593Smuzhiyun             }
461*4882a593Smuzhiyun             hWnd = GetNextWindow(hWnd, GW_HWNDPREV);
462*4882a593Smuzhiyun         }
463*4882a593Smuzhiyun         while (hWnd);
464*4882a593Smuzhiyun     }
465*4882a593Smuzhiyun     else {
466*4882a593Smuzhiyun         /* No valid sibling - make this window the top window */
467*4882a593Smuzhiyun         hInsertAfter = HWND_TOP;
468*4882a593Smuzhiyun         uFlags = SWP_NOMOVE | SWP_NOSIZE;
469*4882a593Smuzhiyun     }
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun     /* Perform the restacking operation in Windows */
472*4882a593Smuzhiyun     SetWindowPos(pWinPriv->hWnd, hInsertAfter, 0, 0, 0, 0, uFlags);
473*4882a593Smuzhiyun #endif
474*4882a593Smuzhiyun }
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun /*
477*4882a593Smuzhiyun  * winCreateWindowsWindow - Create a Windows window associated with an X window
478*4882a593Smuzhiyun  */
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun void
winCreateWindowsWindow(WindowPtr pWin)481*4882a593Smuzhiyun winCreateWindowsWindow(WindowPtr pWin)
482*4882a593Smuzhiyun {
483*4882a593Smuzhiyun     int iX, iY;
484*4882a593Smuzhiyun     int iWidth;
485*4882a593Smuzhiyun     int iHeight;
486*4882a593Smuzhiyun     HWND hWnd;
487*4882a593Smuzhiyun     HWND hFore = NULL;
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun     winWindowPriv(pWin);
490*4882a593Smuzhiyun     WinXSizeHints hints;
491*4882a593Smuzhiyun     Window daddyId;
492*4882a593Smuzhiyun     DWORD dwStyle, dwExStyle;
493*4882a593Smuzhiyun     RECT rc;
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun     winInitMultiWindowClass();
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun     winDebug("winCreateWindowsTopLevelWindow - pWin:%p XID:0x%x \n", pWin,
498*4882a593Smuzhiyun              (unsigned int)pWin->drawable.id);
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun     iX = pWin->drawable.x + GetSystemMetrics(SM_XVIRTUALSCREEN);
501*4882a593Smuzhiyun     iY = pWin->drawable.y + GetSystemMetrics(SM_YVIRTUALSCREEN);
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun     iWidth = pWin->drawable.width;
504*4882a593Smuzhiyun     iHeight = pWin->drawable.height;
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun     /* If it's an InputOutput window, and so is going to end up being made visible,
507*4882a593Smuzhiyun        make sure the window actually ends up somewhere where it will be visible
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun        To handle arrangements of monitors which form a non-rectangular virtual
510*4882a593Smuzhiyun        desktop, check if the window will end up with it's top-left corner on any
511*4882a593Smuzhiyun        monitor
512*4882a593Smuzhiyun     */
513*4882a593Smuzhiyun     if (pWin->drawable.class != InputOnly) {
514*4882a593Smuzhiyun         POINT pt = { iX, iY };
515*4882a593Smuzhiyun         if (MonitorFromPoint(pt, MONITOR_DEFAULTTONULL) == NULL)
516*4882a593Smuzhiyun             {
517*4882a593Smuzhiyun                 iX = CW_USEDEFAULT;
518*4882a593Smuzhiyun                 iY = CW_USEDEFAULT;
519*4882a593Smuzhiyun             }
520*4882a593Smuzhiyun     }
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun     winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX,
523*4882a593Smuzhiyun              iY);
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun     if (winMultiWindowGetTransientFor(pWin, &daddyId)) {
526*4882a593Smuzhiyun         if (daddyId) {
527*4882a593Smuzhiyun             WindowPtr pParent;
528*4882a593Smuzhiyun             int res = dixLookupWindow(&pParent, daddyId, serverClient, DixReadAccess);
529*4882a593Smuzhiyun             if (res == Success)
530*4882a593Smuzhiyun                 {
531*4882a593Smuzhiyun                     winPrivWinPtr pParentPriv = winGetWindowPriv(pParent);
532*4882a593Smuzhiyun                     hFore = pParentPriv->hWnd;
533*4882a593Smuzhiyun                 }
534*4882a593Smuzhiyun         }
535*4882a593Smuzhiyun     }
536*4882a593Smuzhiyun     else {
537*4882a593Smuzhiyun         /* Default positions if none specified */
538*4882a593Smuzhiyun         if (!winMultiWindowGetWMNormalHints(pWin, &hints))
539*4882a593Smuzhiyun             hints.flags = 0;
540*4882a593Smuzhiyun         if (!(hints.flags & (USPosition | PPosition)) &&
541*4882a593Smuzhiyun             !pWin->overrideRedirect) {
542*4882a593Smuzhiyun             iX = CW_USEDEFAULT;
543*4882a593Smuzhiyun             iY = CW_USEDEFAULT;
544*4882a593Smuzhiyun         }
545*4882a593Smuzhiyun     }
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun     /* Make it WS_OVERLAPPED in create call since WS_POPUP doesn't support */
548*4882a593Smuzhiyun     /* CW_USEDEFAULT, change back to popup after creation */
549*4882a593Smuzhiyun     dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
550*4882a593Smuzhiyun     dwExStyle = WS_EX_TOOLWINDOW;
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun     /*
553*4882a593Smuzhiyun        Calculate the window coordinates containing the requested client area,
554*4882a593Smuzhiyun        being careful to preseve CW_USEDEFAULT
555*4882a593Smuzhiyun      */
556*4882a593Smuzhiyun     rc.top = (iY != CW_USEDEFAULT) ? iY : 0;
557*4882a593Smuzhiyun     rc.left = (iX != CW_USEDEFAULT) ? iX : 0;
558*4882a593Smuzhiyun     rc.bottom = rc.top + iHeight;
559*4882a593Smuzhiyun     rc.right = rc.left + iWidth;
560*4882a593Smuzhiyun     AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle);
561*4882a593Smuzhiyun     if (iY != CW_USEDEFAULT)
562*4882a593Smuzhiyun         iY = rc.top;
563*4882a593Smuzhiyun     if (iX != CW_USEDEFAULT)
564*4882a593Smuzhiyun         iX = rc.left;
565*4882a593Smuzhiyun     iHeight = rc.bottom - rc.top;
566*4882a593Smuzhiyun     iWidth = rc.right - rc.left;
567*4882a593Smuzhiyun 
568*4882a593Smuzhiyun     winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX,
569*4882a593Smuzhiyun              iY);
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun     /* Create the window */
572*4882a593Smuzhiyun     hWnd = CreateWindowExA(dwExStyle,   /* Extended styles */
573*4882a593Smuzhiyun                            WINDOW_CLASS_X,      /* Class name */
574*4882a593Smuzhiyun                            WINDOW_TITLE_X,      /* Window name */
575*4882a593Smuzhiyun                            dwStyle,     /* Styles */
576*4882a593Smuzhiyun                            iX,  /* Horizontal position */
577*4882a593Smuzhiyun                            iY,  /* Vertical position */
578*4882a593Smuzhiyun                            iWidth,      /* Right edge */
579*4882a593Smuzhiyun                            iHeight,     /* Bottom edge */
580*4882a593Smuzhiyun                            hFore,       /* Null or Parent window if transient */
581*4882a593Smuzhiyun                            (HMENU) NULL,        /* No menu */
582*4882a593Smuzhiyun                            GetModuleHandle(NULL),       /* Instance handle */
583*4882a593Smuzhiyun                            pWin);       /* ScreenPrivates */
584*4882a593Smuzhiyun     if (hWnd == NULL) {
585*4882a593Smuzhiyun         ErrorF("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
586*4882a593Smuzhiyun                (int) GetLastError());
587*4882a593Smuzhiyun     }
588*4882a593Smuzhiyun     pWinPriv->hWnd = hWnd;
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun     /* Change style back to popup, already placed... */
591*4882a593Smuzhiyun     SetWindowLongPtr(hWnd, GWL_STYLE,
592*4882a593Smuzhiyun                      WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
593*4882a593Smuzhiyun     SetWindowPos(hWnd, 0, 0, 0, 0, 0,
594*4882a593Smuzhiyun                  SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE |
595*4882a593Smuzhiyun                  SWP_NOACTIVATE);
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun     /* Adjust the X window to match the window placement we actually got... */
598*4882a593Smuzhiyun     winAdjustXWindow(pWin, hWnd);
599*4882a593Smuzhiyun 
600*4882a593Smuzhiyun     /* Make sure it gets the proper system menu for a WS_POPUP, too */
601*4882a593Smuzhiyun     GetSystemMenu(hWnd, TRUE);
602*4882a593Smuzhiyun 
603*4882a593Smuzhiyun     /* Cause any .XWinrc menus to be added in main WNDPROC */
604*4882a593Smuzhiyun     PostMessage(hWnd, WM_INIT_SYS_MENU, 0, 0);
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun     SetProp(hWnd, WIN_WID_PROP, (HANDLE) (INT_PTR) winGetWindowID(pWin));
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun     /* Flag that this Windows window handles its own activation */
609*4882a593Smuzhiyun     SetProp(hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0);
610*4882a593Smuzhiyun }
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun Bool winInDestroyWindowsWindow = FALSE;
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun /*
615*4882a593Smuzhiyun  * winDestroyWindowsWindow - Destroy a Windows window associated
616*4882a593Smuzhiyun  * with an X window
617*4882a593Smuzhiyun  */
618*4882a593Smuzhiyun static void
winDestroyWindowsWindow(WindowPtr pWin)619*4882a593Smuzhiyun winDestroyWindowsWindow(WindowPtr pWin)
620*4882a593Smuzhiyun {
621*4882a593Smuzhiyun     MSG msg;
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun     winWindowPriv(pWin);
624*4882a593Smuzhiyun     BOOL oldstate = winInDestroyWindowsWindow;
625*4882a593Smuzhiyun     HICON hIcon;
626*4882a593Smuzhiyun     HICON hIconSm;
627*4882a593Smuzhiyun 
628*4882a593Smuzhiyun     winDebug("winDestroyWindowsWindow - pWin:%p XID:0x%x \n", pWin,
629*4882a593Smuzhiyun              (unsigned int)pWin->drawable.id);
630*4882a593Smuzhiyun 
631*4882a593Smuzhiyun     /* Bail out if the Windows window handle is invalid */
632*4882a593Smuzhiyun     if (pWinPriv->hWnd == NULL)
633*4882a593Smuzhiyun         return;
634*4882a593Smuzhiyun 
635*4882a593Smuzhiyun     winInDestroyWindowsWindow = TRUE;
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun     /* Store the info we need to destroy after this window is gone */
638*4882a593Smuzhiyun     hIcon = (HICON) SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_BIG, 0);
639*4882a593Smuzhiyun     hIconSm = (HICON) SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_SMALL, 0);
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun     /* Destroy the Windows window */
642*4882a593Smuzhiyun     DestroyWindow(pWinPriv->hWnd);
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun     /* Null our handle to the Window so referencing it will cause an error */
645*4882a593Smuzhiyun     pWinPriv->hWnd = NULL;
646*4882a593Smuzhiyun 
647*4882a593Smuzhiyun     /* Destroy any icons we created for this window */
648*4882a593Smuzhiyun     winDestroyIcon(hIcon);
649*4882a593Smuzhiyun     winDestroyIcon(hIconSm);
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun #ifdef XWIN_GLX_WINDOWS
652*4882a593Smuzhiyun     /* No longer note WGL used on this window */
653*4882a593Smuzhiyun     pWinPriv->fWglUsed = FALSE;
654*4882a593Smuzhiyun #endif
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun     /* Process all messages on our queue */
657*4882a593Smuzhiyun     while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
658*4882a593Smuzhiyun         if (g_hDlgDepthChange == 0 || !IsDialogMessage(g_hDlgDepthChange, &msg)) {
659*4882a593Smuzhiyun             DispatchMessage(&msg);
660*4882a593Smuzhiyun         }
661*4882a593Smuzhiyun     }
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun     winInDestroyWindowsWindow = oldstate;
664*4882a593Smuzhiyun 
665*4882a593Smuzhiyun     winDebug("winDestroyWindowsWindow - done\n");
666*4882a593Smuzhiyun }
667*4882a593Smuzhiyun 
668*4882a593Smuzhiyun /*
669*4882a593Smuzhiyun  * winUpdateWindowsWindow - Redisplay/redraw a Windows window
670*4882a593Smuzhiyun  * associated with an X window
671*4882a593Smuzhiyun  */
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun static void
winUpdateWindowsWindow(WindowPtr pWin)674*4882a593Smuzhiyun winUpdateWindowsWindow(WindowPtr pWin)
675*4882a593Smuzhiyun {
676*4882a593Smuzhiyun     winWindowPriv(pWin);
677*4882a593Smuzhiyun     HWND hWnd = pWinPriv->hWnd;
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
680*4882a593Smuzhiyun     ErrorF("winUpdateWindowsWindow\n");
681*4882a593Smuzhiyun #endif
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun     /* Check if the Windows window's parents have been destroyed */
684*4882a593Smuzhiyun     if (pWin->parent != NULL && pWin->parent->parent == NULL && pWin->mapped) {
685*4882a593Smuzhiyun         /* Create the Windows window if it has been destroyed */
686*4882a593Smuzhiyun         if (hWnd == NULL) {
687*4882a593Smuzhiyun             winCreateWindowsWindow(pWin);
688*4882a593Smuzhiyun             assert(pWinPriv->hWnd != NULL);
689*4882a593Smuzhiyun         }
690*4882a593Smuzhiyun 
691*4882a593Smuzhiyun         /* Display the window without activating it */
692*4882a593Smuzhiyun         if (pWin->drawable.class != InputOnly)
693*4882a593Smuzhiyun             ShowWindow(pWinPriv->hWnd, SW_SHOWNOACTIVATE);
694*4882a593Smuzhiyun 
695*4882a593Smuzhiyun         /* Send first paint message */
696*4882a593Smuzhiyun         UpdateWindow(pWinPriv->hWnd);
697*4882a593Smuzhiyun     }
698*4882a593Smuzhiyun     else if (hWnd != NULL) {
699*4882a593Smuzhiyun         /* Destroy the Windows window if its parents are destroyed */
700*4882a593Smuzhiyun         winDestroyWindowsWindow(pWin);
701*4882a593Smuzhiyun         assert(pWinPriv->hWnd == NULL);
702*4882a593Smuzhiyun     }
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
705*4882a593Smuzhiyun     ErrorF("-winUpdateWindowsWindow\n");
706*4882a593Smuzhiyun #endif
707*4882a593Smuzhiyun }
708*4882a593Smuzhiyun 
709*4882a593Smuzhiyun /*
710*4882a593Smuzhiyun  * winGetWindowID -
711*4882a593Smuzhiyun  */
712*4882a593Smuzhiyun 
713*4882a593Smuzhiyun XID
winGetWindowID(WindowPtr pWin)714*4882a593Smuzhiyun winGetWindowID(WindowPtr pWin)
715*4882a593Smuzhiyun {
716*4882a593Smuzhiyun     WindowIDPairRec wi = { pWin, 0 };
717*4882a593Smuzhiyun     ClientPtr c = wClient(pWin);
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun     /* */
720*4882a593Smuzhiyun     FindClientResourcesByType(c, RT_WINDOW, winFindWindow, &wi);
721*4882a593Smuzhiyun 
722*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG
723*4882a593Smuzhiyun     ErrorF("winGetWindowID - Window ID: %u\n", (unsigned int)wi.id);
724*4882a593Smuzhiyun #endif
725*4882a593Smuzhiyun 
726*4882a593Smuzhiyun     return wi.id;
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun /*
730*4882a593Smuzhiyun  * winFindWindow -
731*4882a593Smuzhiyun  */
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun static void
winFindWindow(void * value,XID id,void * cdata)734*4882a593Smuzhiyun winFindWindow(void *value, XID id, void *cdata)
735*4882a593Smuzhiyun {
736*4882a593Smuzhiyun     WindowIDPairPtr wi = (WindowIDPairPtr) cdata;
737*4882a593Smuzhiyun 
738*4882a593Smuzhiyun     if (value == wi->value) {
739*4882a593Smuzhiyun         wi->id = id;
740*4882a593Smuzhiyun     }
741*4882a593Smuzhiyun }
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun /*
744*4882a593Smuzhiyun  * winReorderWindowsMultiWindow -
745*4882a593Smuzhiyun  */
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun void
winReorderWindowsMultiWindow(void)748*4882a593Smuzhiyun winReorderWindowsMultiWindow(void)
749*4882a593Smuzhiyun {
750*4882a593Smuzhiyun     HWND hwnd = NULL;
751*4882a593Smuzhiyun     WindowPtr pWin = NULL;
752*4882a593Smuzhiyun     WindowPtr pWinSib = NULL;
753*4882a593Smuzhiyun     XID vlist[2];
754*4882a593Smuzhiyun     static Bool fRestacking = FALSE;    /* Avoid recusive calls to this function */
755*4882a593Smuzhiyun     DWORD dwCurrentProcessID = GetCurrentProcessId();
756*4882a593Smuzhiyun     DWORD dwWindowProcessID = 0;
757*4882a593Smuzhiyun 
758*4882a593Smuzhiyun #if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
759*4882a593Smuzhiyun     winTrace("winReorderWindowsMultiWindow\n");
760*4882a593Smuzhiyun #endif
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun     if (fRestacking) {
763*4882a593Smuzhiyun         /* It is a recusive call so immediately exit */
764*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
765*4882a593Smuzhiyun         ErrorF("winReorderWindowsMultiWindow - "
766*4882a593Smuzhiyun                "exit because fRestacking == TRUE\n");
767*4882a593Smuzhiyun #endif
768*4882a593Smuzhiyun         return;
769*4882a593Smuzhiyun     }
770*4882a593Smuzhiyun     fRestacking = TRUE;
771*4882a593Smuzhiyun 
772*4882a593Smuzhiyun     /* Loop through top level Window windows, descending in Z order */
773*4882a593Smuzhiyun     for (hwnd = GetTopWindow(NULL);
774*4882a593Smuzhiyun          hwnd; hwnd = GetNextWindow(hwnd, GW_HWNDNEXT)) {
775*4882a593Smuzhiyun         /* Don't take care of other Cygwin/X process's windows */
776*4882a593Smuzhiyun         GetWindowThreadProcessId(hwnd, &dwWindowProcessID);
777*4882a593Smuzhiyun 
778*4882a593Smuzhiyun         if (GetProp(hwnd, WIN_WINDOW_PROP)
779*4882a593Smuzhiyun             && (dwWindowProcessID == dwCurrentProcessID)
780*4882a593Smuzhiyun             && !IsIconic(hwnd)) {       /* ignore minimized windows */
781*4882a593Smuzhiyun             pWinSib = pWin;
782*4882a593Smuzhiyun             pWin = GetProp(hwnd, WIN_WINDOW_PROP);
783*4882a593Smuzhiyun 
784*4882a593Smuzhiyun             if (!pWinSib) {     /* 1st window - raise to the top */
785*4882a593Smuzhiyun                 vlist[0] = Above;
786*4882a593Smuzhiyun 
787*4882a593Smuzhiyun                 ConfigureWindow(pWin, CWStackMode, vlist, wClient(pWin));
788*4882a593Smuzhiyun             }
789*4882a593Smuzhiyun             else {              /* 2nd or deeper windows - just below the previous one */
790*4882a593Smuzhiyun                 vlist[0] = winGetWindowID(pWinSib);
791*4882a593Smuzhiyun                 vlist[1] = Below;
792*4882a593Smuzhiyun 
793*4882a593Smuzhiyun                 ConfigureWindow(pWin, CWSibling | CWStackMode,
794*4882a593Smuzhiyun                                 vlist, wClient(pWin));
795*4882a593Smuzhiyun             }
796*4882a593Smuzhiyun         }
797*4882a593Smuzhiyun     }
798*4882a593Smuzhiyun 
799*4882a593Smuzhiyun     fRestacking = FALSE;
800*4882a593Smuzhiyun }
801*4882a593Smuzhiyun 
802*4882a593Smuzhiyun /*
803*4882a593Smuzhiyun  * CopyWindow - See Porting Layer Definition - p. 39
804*4882a593Smuzhiyun  */
805*4882a593Smuzhiyun void
winCopyWindowMultiWindow(WindowPtr pWin,DDXPointRec oldpt,RegionPtr oldRegion)806*4882a593Smuzhiyun winCopyWindowMultiWindow(WindowPtr pWin, DDXPointRec oldpt, RegionPtr oldRegion)
807*4882a593Smuzhiyun {
808*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
809*4882a593Smuzhiyun 
810*4882a593Smuzhiyun     winScreenPriv(pScreen);
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
813*4882a593Smuzhiyun     ErrorF("CopyWindowMultiWindow\n");
814*4882a593Smuzhiyun #endif
815*4882a593Smuzhiyun     WIN_UNWRAP(CopyWindow);
816*4882a593Smuzhiyun     (*pScreen->CopyWindow) (pWin, oldpt, oldRegion);
817*4882a593Smuzhiyun     WIN_WRAP(CopyWindow, winCopyWindowMultiWindow);
818*4882a593Smuzhiyun }
819*4882a593Smuzhiyun 
820*4882a593Smuzhiyun /*
821*4882a593Smuzhiyun  * MoveWindow - See Porting Layer Definition - p. 42
822*4882a593Smuzhiyun  */
823*4882a593Smuzhiyun void
winMoveWindowMultiWindow(WindowPtr pWin,int x,int y,WindowPtr pSib,VTKind kind)824*4882a593Smuzhiyun winMoveWindowMultiWindow(WindowPtr pWin, int x, int y,
825*4882a593Smuzhiyun                          WindowPtr pSib, VTKind kind)
826*4882a593Smuzhiyun {
827*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
828*4882a593Smuzhiyun 
829*4882a593Smuzhiyun     winScreenPriv(pScreen);
830*4882a593Smuzhiyun 
831*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
832*4882a593Smuzhiyun     ErrorF("MoveWindowMultiWindow to (%d, %d)\n", x, y);
833*4882a593Smuzhiyun #endif
834*4882a593Smuzhiyun 
835*4882a593Smuzhiyun     WIN_UNWRAP(MoveWindow);
836*4882a593Smuzhiyun     (*pScreen->MoveWindow) (pWin, x, y, pSib, kind);
837*4882a593Smuzhiyun     WIN_WRAP(MoveWindow, winMoveWindowMultiWindow);
838*4882a593Smuzhiyun }
839*4882a593Smuzhiyun 
840*4882a593Smuzhiyun /*
841*4882a593Smuzhiyun  * ResizeWindow - See Porting Layer Definition - p. 42
842*4882a593Smuzhiyun  */
843*4882a593Smuzhiyun void
winResizeWindowMultiWindow(WindowPtr pWin,int x,int y,unsigned int w,unsigned int h,WindowPtr pSib)844*4882a593Smuzhiyun winResizeWindowMultiWindow(WindowPtr pWin, int x, int y, unsigned int w,
845*4882a593Smuzhiyun                            unsigned int h, WindowPtr pSib)
846*4882a593Smuzhiyun {
847*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
848*4882a593Smuzhiyun 
849*4882a593Smuzhiyun     winScreenPriv(pScreen);
850*4882a593Smuzhiyun 
851*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
852*4882a593Smuzhiyun     ErrorF("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x, y, w, h);
853*4882a593Smuzhiyun #endif
854*4882a593Smuzhiyun     WIN_UNWRAP(ResizeWindow);
855*4882a593Smuzhiyun     (*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
856*4882a593Smuzhiyun     WIN_WRAP(ResizeWindow, winResizeWindowMultiWindow);
857*4882a593Smuzhiyun }
858*4882a593Smuzhiyun 
859*4882a593Smuzhiyun /*
860*4882a593Smuzhiyun  * winAdjustXWindow
861*4882a593Smuzhiyun  *
862*4882a593Smuzhiyun  * Move and resize X window with respect to corresponding Windows window.
863*4882a593Smuzhiyun  * This is called from WM_MOVE/WM_SIZE handlers when the user performs
864*4882a593Smuzhiyun  * any windowing operation (move, resize, minimize, maximize, restore).
865*4882a593Smuzhiyun  *
866*4882a593Smuzhiyun  * The functionality is the inverse of winPositionWindowMultiWindow, which
867*4882a593Smuzhiyun  * adjusts Windows window with respect to X window.
868*4882a593Smuzhiyun  */
869*4882a593Smuzhiyun int
winAdjustXWindow(WindowPtr pWin,HWND hwnd)870*4882a593Smuzhiyun winAdjustXWindow(WindowPtr pWin, HWND hwnd)
871*4882a593Smuzhiyun {
872*4882a593Smuzhiyun     RECT rcDraw;                /* Rect made from pWin->drawable to be adjusted */
873*4882a593Smuzhiyun     RECT rcWin;                 /* The source: WindowRect from hwnd */
874*4882a593Smuzhiyun     DrawablePtr pDraw;
875*4882a593Smuzhiyun     XID vlist[4];
876*4882a593Smuzhiyun     LONG dX, dY, dW, dH, x, y;
877*4882a593Smuzhiyun     DWORD dwStyle, dwExStyle;
878*4882a593Smuzhiyun 
879*4882a593Smuzhiyun #define WIDTH(rc) (rc.right - rc.left)
880*4882a593Smuzhiyun #define HEIGHT(rc) (rc.bottom - rc.top)
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
883*4882a593Smuzhiyun     ErrorF("winAdjustXWindow\n");
884*4882a593Smuzhiyun #endif
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun     if (IsIconic(hwnd)) {
887*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
888*4882a593Smuzhiyun         ErrorF("\timmediately return because the window is iconized\n");
889*4882a593Smuzhiyun #endif
890*4882a593Smuzhiyun         /*
891*4882a593Smuzhiyun          * If the Windows window is minimized, its WindowRect has
892*4882a593Smuzhiyun          * meaningless values so we don't adjust X window to it.
893*4882a593Smuzhiyun          */
894*4882a593Smuzhiyun         vlist[0] = 0;
895*4882a593Smuzhiyun         vlist[1] = 0;
896*4882a593Smuzhiyun         return ConfigureWindow(pWin, CWX | CWY, vlist, wClient(pWin));
897*4882a593Smuzhiyun     }
898*4882a593Smuzhiyun 
899*4882a593Smuzhiyun     pDraw = &pWin->drawable;
900*4882a593Smuzhiyun 
901*4882a593Smuzhiyun     /* Calculate the window rect from the drawable */
902*4882a593Smuzhiyun     x = pDraw->x + GetSystemMetrics(SM_XVIRTUALSCREEN);
903*4882a593Smuzhiyun     y = pDraw->y + GetSystemMetrics(SM_YVIRTUALSCREEN);
904*4882a593Smuzhiyun     SetRect(&rcDraw, x, y, x + pDraw->width, y + pDraw->height);
905*4882a593Smuzhiyun #ifdef CYGMULTIWINDOW_DEBUG
906*4882a593Smuzhiyun     winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n",
907*4882a593Smuzhiyun              (int)rcDraw.left, (int)rcDraw.top, (int)rcDraw.right, (int)rcDraw.bottom,
908*4882a593Smuzhiyun              (int)(rcDraw.right - rcDraw.left), (int)(rcDraw.bottom - rcDraw.top));
909*4882a593Smuzhiyun #endif
910*4882a593Smuzhiyun     dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
911*4882a593Smuzhiyun     dwStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
912*4882a593Smuzhiyun #ifdef CYGMULTIWINDOW_DEBUG
913*4882a593Smuzhiyun     winDebug("\tWindowStyle: %08x %08x\n", (unsigned int)dwStyle, (unsigned int)dwExStyle);
914*4882a593Smuzhiyun #endif
915*4882a593Smuzhiyun     AdjustWindowRectEx(&rcDraw, dwStyle, FALSE, dwExStyle);
916*4882a593Smuzhiyun 
917*4882a593Smuzhiyun     /* The source of adjust */
918*4882a593Smuzhiyun     GetWindowRect(hwnd, &rcWin);
919*4882a593Smuzhiyun #ifdef CYGMULTIWINDOW_DEBUG
920*4882a593Smuzhiyun     winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
921*4882a593Smuzhiyun              (int)rcWin.left, (int)rcWin.top, (int)rcWin.right, (int)rcWin.bottom,
922*4882a593Smuzhiyun              (int)(rcWin.right - rcWin.left), (int)(rcWin.bottom - rcWin.top));
923*4882a593Smuzhiyun     winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n",
924*4882a593Smuzhiyun              (int)rcDraw.left, (int)rcDraw.top, (int)rcDraw.right, (int)rcDraw.bottom,
925*4882a593Smuzhiyun              (int)(rcDraw.right - rcDraw.left), (int)(rcDraw.bottom - rcDraw.top));
926*4882a593Smuzhiyun #endif
927*4882a593Smuzhiyun 
928*4882a593Smuzhiyun     if (EqualRect(&rcDraw, &rcWin)) {
929*4882a593Smuzhiyun         /* Bail if no adjust is needed */
930*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
931*4882a593Smuzhiyun         ErrorF("\treturn because already adjusted\n");
932*4882a593Smuzhiyun #endif
933*4882a593Smuzhiyun         return 0;
934*4882a593Smuzhiyun     }
935*4882a593Smuzhiyun 
936*4882a593Smuzhiyun     /* Calculate delta values */
937*4882a593Smuzhiyun     dX = rcWin.left - rcDraw.left;
938*4882a593Smuzhiyun     dY = rcWin.top - rcDraw.top;
939*4882a593Smuzhiyun     dW = WIDTH(rcWin) - WIDTH(rcDraw);
940*4882a593Smuzhiyun     dH = HEIGHT(rcWin) - HEIGHT(rcDraw);
941*4882a593Smuzhiyun 
942*4882a593Smuzhiyun     /*
943*4882a593Smuzhiyun      * Adjust.
944*4882a593Smuzhiyun      * We may only need to move (vlist[0] and [1]), or only resize
945*4882a593Smuzhiyun      * ([2] and [3]) but currently we set all the parameters and leave
946*4882a593Smuzhiyun      * the decision to ConfigureWindow.  The reason is code simplicity.
947*4882a593Smuzhiyun      */
948*4882a593Smuzhiyun     vlist[0] = pDraw->x + dX - wBorderWidth(pWin);
949*4882a593Smuzhiyun     vlist[1] = pDraw->y + dY - wBorderWidth(pWin);
950*4882a593Smuzhiyun     vlist[2] = pDraw->width + dW;
951*4882a593Smuzhiyun     vlist[3] = pDraw->height + dH;
952*4882a593Smuzhiyun #if CYGWINDOWING_DEBUG
953*4882a593Smuzhiyun     ErrorF("\tConfigureWindow to (%u, %u) - %ux%u\n",
954*4882a593Smuzhiyun            (unsigned int)vlist[0], (unsigned int)vlist[1],
955*4882a593Smuzhiyun            (unsigned int)vlist[2], (unsigned int)vlist[3]);
956*4882a593Smuzhiyun #endif
957*4882a593Smuzhiyun     return ConfigureWindow(pWin, CWX | CWY | CWWidth | CWHeight,
958*4882a593Smuzhiyun                            vlist, wClient(pWin));
959*4882a593Smuzhiyun 
960*4882a593Smuzhiyun #undef WIDTH
961*4882a593Smuzhiyun #undef HEIGHT
962*4882a593Smuzhiyun }
963