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