1 /*
2  *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
3  *
4  *Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  *"Software"), to deal in the Software without restriction, including
7  *without limitation the rights to use, copy, modify, merge, publish,
8  *distribute, sublicense, and/or sell copies of the Software, and to
9  *permit persons to whom the Software is furnished to do so, subject to
10  *the following conditions:
11  *
12  *The above copyright notice and this permission notice shall be
13  *included in all copies or substantial portions of the Software.
14  *
15  *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
19  *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20  *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21  *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  *
23  *Except as contained in this notice, the name of the XFree86 Project
24  *shall not be used in advertising or otherwise to promote the sale, use
25  *or other dealings in this Software without prior written authorization
26  *from the XFree86 Project.
27  *
28  * Authors:	Kensuke Matsuzaki
29  *		Earle F. Philhower, III
30  *		Harold L Hunt II
31  */
32 
33 #ifdef HAVE_XWIN_CONFIG_H
34 #include <xwin-config.h>
35 #endif
36 #include "win.h"
37 #include "winprefs.h"
38 
39 #if 0
40 /*
41  * winMWExtWMReorderWindows
42  */
43 
44 void
45 winMWExtWMReorderWindows(ScreenPtr pScreen)
46 {
47     winScreenPriv(pScreen);
48     HWND hwnd = NULL;
49     win32RootlessWindowPtr pRLWin = NULL;
50     win32RootlessWindowPtr pRLWinSib = NULL;
51     DWORD dwCurrentProcessID = GetCurrentProcessId();
52     DWORD dwWindowProcessID = 0;
53     XID vlist[2];
54 
55 #if CYGMULTIWINDOW_DEBUG && FALSE
56     winDebug("winMWExtWMReorderWindows\n");
57 #endif
58 
59     pScreenPriv->fRestacking = TRUE;
60 
61     if (pScreenPriv->fWindowOrderChanged) {
62 #if CYGMULTIWINDOW_DEBUG
63         winDebug("winMWExtWMReorderWindows - Need to restack\n");
64 #endif
65         hwnd = GetTopWindow(NULL);
66 
67         while (hwnd) {
68             GetWindowThreadProcessId(hwnd, &dwWindowProcessID);
69 
70             if ((dwWindowProcessID == dwCurrentProcessID)
71                 && GetProp(hwnd, WIN_WINDOW_PROP)) {
72                 pRLWinSib = pRLWin;
73                 pRLWin =
74                     (win32RootlessWindowPtr) GetProp(hwnd, WIN_WINDOW_PROP);
75 
76                 if (pRLWinSib) {
77                     vlist[0] = pRLWinSib->pFrame->win->drawable.id;
78                     vlist[1] = Below;
79 
80                     ConfigureWindow(pRLWin->pFrame->win,
81                                     CWSibling | CWStackMode, vlist,
82                                     wClient(pRLWin->pFrame->win));
83                 }
84                 else {
85                     /* 1st window - raise to the top */
86                     vlist[0] = Above;
87 
88                     ConfigureWindow(pRLWin->pFrame->win, CWStackMode,
89                                     vlist, wClient(pRLWin->pFrame->win));
90                 }
91             }
92             hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);
93         }
94     }
95 
96     pScreenPriv->fRestacking = FALSE;
97     pScreenPriv->fWindowOrderChanged = FALSE;
98 }
99 #endif
100 
101 /*
102  * winMWExtWMMoveXWindow
103  */
104 
105 void
winMWExtWMMoveXWindow(WindowPtr pWin,int x,int y)106 winMWExtWMMoveXWindow(WindowPtr pWin, int x, int y)
107 {
108     CARD32 *vlist = malloc(sizeof(CARD32) * 2);
109 
110     vlist[0] = x;
111     vlist[1] = y;
112     ConfigureWindow(pWin, CWX | CWY, vlist, wClient(pWin));
113     free(vlist);
114 }
115 
116 /*
117  * winMWExtWMResizeXWindow
118  */
119 
120 void
winMWExtWMResizeXWindow(WindowPtr pWin,int w,int h)121 winMWExtWMResizeXWindow(WindowPtr pWin, int w, int h)
122 {
123     CARD32 *vlist = malloc(sizeof(CARD32) * 2);
124 
125     vlist[0] = w;
126     vlist[1] = h;
127     ConfigureWindow(pWin, CWWidth | CWHeight, vlist, wClient(pWin));
128     free(vlist);
129 }
130 
131 /*
132  * winMWExtWMMoveResizeXWindow
133  */
134 
135 void
winMWExtWMMoveResizeXWindow(WindowPtr pWin,int x,int y,int w,int h)136 winMWExtWMMoveResizeXWindow(WindowPtr pWin, int x, int y, int w, int h)
137 {
138     CARD32 *vlist = malloc(sizeof(long) * 4);
139 
140     vlist[0] = x;
141     vlist[1] = y;
142     vlist[2] = w;
143     vlist[3] = h;
144 
145     ConfigureWindow(pWin, CWX | CWY | CWWidth | CWHeight, vlist, wClient(pWin));
146     free(vlist);
147 }
148 
149 /*
150 
151 
152  * winMWExtWMDecorateWindow - Update window style. Called by EnumWindows.
153  */
154 
155 wBOOL CALLBACK
winMWExtWMDecorateWindow(HWND hwnd,LPARAM lParam)156 winMWExtWMDecorateWindow(HWND hwnd, LPARAM lParam)
157 {
158     win32RootlessWindowPtr pRLWinPriv = NULL;
159     ScreenPtr pScreen = NULL;
160     winPrivScreenPtr pScreenPriv = NULL;
161     winScreenInfo *pScreenInfo = NULL;
162 
163     /* Check if the Windows window property for our X window pointer is valid */
164     if ((pRLWinPriv =
165          (win32RootlessWindowPtr) GetProp(hwnd, WIN_WINDOW_PROP)) != NULL) {
166         if (pRLWinPriv != NULL && pRLWinPriv->pFrame != NULL &&
167             pRLWinPriv->pFrame->win != NULL)
168             pScreen = pRLWinPriv->pFrame->win->drawable.pScreen;
169         if (pScreen)
170             pScreenPriv = winGetScreenPriv(pScreen);
171         if (pScreenPriv)
172             pScreenInfo = pScreenPriv->pScreenInfo;
173         if (pRLWinPriv && pScreenInfo)
174             winMWExtWMUpdateWindowDecoration(pRLWinPriv, pScreenInfo);
175     }
176     return TRUE;
177 }
178 
179 /*
180  * winMWExtWMUpdateWindowDecoration - Update window style.
181  */
182 
183 void
winMWExtWMUpdateWindowDecoration(win32RootlessWindowPtr pRLWinPriv,winScreenInfoPtr pScreenInfo)184 winMWExtWMUpdateWindowDecoration(win32RootlessWindowPtr pRLWinPriv,
185                                  winScreenInfoPtr pScreenInfo)
186 {
187     Bool fDecorate = FALSE;
188     DWORD dwExStyle = 0;
189     WINDOWPLACEMENT wndPlace;
190     UINT showCmd = 0;
191 
192     wndPlace.length = sizeof(WINDOWPLACEMENT);
193 
194     /* Get current window placement */
195     GetWindowPlacement(pRLWinPriv->hWnd, &wndPlace);
196 
197 #if 0
198     if (wndPlace.showCmd == SW_HIDE)
199         return;                 //showCmd = SWP_HIDEWINDOW;
200     else
201         showCmd = SWP_SHOWWINDOW;
202 #else
203     if (wndPlace.showCmd == SW_HIDE)
204         return;
205 
206     if (IsWindowVisible(pRLWinPriv->hWnd))
207         showCmd = SWP_SHOWWINDOW;
208 #endif
209 
210     showCmd |= SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER;
211 
212     winDebug("winMWExtWMUpdateWindowDecoration %p %s\n",
213              pRLWinPriv, fDecorate ? "Decorate" : "Bare");
214 
215     /* Get the extended window style information */
216     dwExStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE);
217 
218     if (fDecorate) {
219         RECT rcNew;
220         int iDx, iDy;
221         winWMMessageRec wmMsg;
222 
223         winScreenPriv(pScreenInfo->pScreen);
224 
225         /* */
226         if (!(dwExStyle & WS_EX_APPWINDOW)) {
227             winDebug("\tBare=>Decorate\n");
228             /* Setup a rectangle with the X window position and size */
229             SetRect(&rcNew,
230                     pRLWinPriv->pFrame->x,
231                     pRLWinPriv->pFrame->y,
232                     pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width,
233                     pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height);
234 
235 #ifdef CYGMULTIWINDOW_DEBUG
236             winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
237                      rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
238                      rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
239 #endif
240             /* */
241             AdjustWindowRectEx(&rcNew,
242                                WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW,
243                                FALSE, WS_EX_APPWINDOW);
244 
245 #ifdef CYGMULTIWINDOW_DEBUG
246             winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n",
247                      rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
248                      rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
249 #endif
250             /* Calculate position deltas */
251             iDx = pRLWinPriv->pFrame->x - rcNew.left;
252             iDy = pRLWinPriv->pFrame->y - rcNew.top;
253 
254             /* Calculate new rectangle */
255             rcNew.left += iDx;
256             rcNew.right += iDx;
257             rcNew.top += iDy;
258             rcNew.bottom += iDy;
259 
260             /* Set the window extended style flags */
261             SetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
262 
263             /* Set the window standard style flags */
264             SetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE,
265                              WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW);
266 
267 #ifdef CYGMULTIWINDOW_DEBUG
268             winDebug("\tWindowStyle: %08x %08x\n",
269                      WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW,
270                      WS_EX_APPWINDOW);
271 #endif
272             /* Position the Windows window */
273 #ifdef CYGMULTIWINDOW_DEBUG
274             winDebug("\tMoved {%d, %d, %d, %d}, {%d, %d}\n",
275                      rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
276                      rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
277 #endif
278             SetWindowPos(pRLWinPriv->hWnd, NULL,
279                          rcNew.left, rcNew.top,
280                          rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
281                          showCmd);
282 
283             wmMsg.hwndWindow = pRLWinPriv->hWnd;
284             wmMsg.iWindow = (Window) pRLWinPriv->pFrame->win->drawable.id;
285             wmMsg.msg = WM_WM_NAME_EVENT;
286             winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
287 
288             winMWExtWMReshapeFrame((RootlessFrameID) pRLWinPriv,
289                                    wBoundingShape(pRLWinPriv->pFrame->win));
290         }
291     }
292     else {
293         RECT rcNew;
294 
295         /* */
296         if (dwExStyle & WS_EX_APPWINDOW) {
297             winDebug("\tDecorate=>Bare\n");
298             /* Setup a rectangle with the X window position and size */
299             SetRect(&rcNew,
300                     pRLWinPriv->pFrame->x,
301                     pRLWinPriv->pFrame->y,
302                     pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width,
303                     pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height);
304 #if 0
305             /* */
306             AdjustWindowRectEx(&rcNew,
307                                WS_POPUP | WS_CLIPCHILDREN,
308                                FALSE, WS_EX_TOOLWINDOW);
309 
310             /* Calculate position deltas */
311             iDx = pRLWinPriv->pFrame->x - rcNew.left;
312             iDy = pRLWinPriv->pFrame->y - rcNew.top;
313 
314             /* Calculate new rectangle */
315             rcNew.left += iDx;
316             rcNew.right += iDx;
317             rcNew.top += iDy;
318             rcNew.bottom += iDy;
319 #endif
320 
321             /* Hide window temporary to remove from taskbar. */
322             ShowWindow(pRLWinPriv->hWnd, SW_HIDE);
323 
324             /* Set the window extended style flags */
325             SetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
326 
327             /* Set the window standard style flags */
328             SetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE,
329                              WS_POPUP | WS_CLIPCHILDREN);
330 
331             /* Position the Windows window */
332             SetWindowPos(pRLWinPriv->hWnd, NULL,
333                          rcNew.left, rcNew.top,
334                          rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
335                          showCmd);
336 
337             winMWExtWMReshapeFrame((RootlessFrameID) pRLWinPriv,
338                                    wBoundingShape(pRLWinPriv->pFrame->win));
339         }
340     }
341 }
342 
343 /*
344  * winMWExtWMRestackWindows
345  */
346 
347 void
winMWExtWMRestackWindows(ScreenPtr pScreen)348 winMWExtWMRestackWindows(ScreenPtr pScreen)
349 {
350     winScreenPriv(pScreen);
351     WindowPtr pRoot = pScreen->root;
352     WindowPtr pWin = NULL;
353     WindowPtr pWinPrev = NULL;
354     win32RootlessWindowPtr pRLWin = NULL;
355     win32RootlessWindowPtr pRLWinPrev = NULL;
356     int nWindow = 0;
357     HDWP hWinPosInfo = NULL;
358 
359 #if CYGMULTIWINDOW_DEBUG
360     winDebug("winMWExtWMRestackWindows\n");
361 #endif
362 
363     pScreenPriv->fRestacking = TRUE;
364 
365     if (pRoot != NULL) {
366         for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib)
367             nWindow++;
368 
369         hWinPosInfo = BeginDeferWindowPos(nWindow);
370 
371         for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) {
372             if (pWin->realized) {
373                 UINT uFlags;
374 
375                 pRLWin =
376                     (win32RootlessWindowPtr) RootlessFrameForWindow(pWin,
377                                                                     FALSE);
378                 if (pRLWin == NULL)
379                     continue;
380 
381                 if (pWinPrev)
382                     pRLWinPrev =
383                         (win32RootlessWindowPtr)
384                         RootlessFrameForWindow(pWinPrev, FALSE);
385 
386                 uFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW;
387                 if (pRLWinPrev != NULL)
388                     uFlags |= SWP_NOACTIVATE;
389 
390 #if CYGMULTIWINDOW_DEBUG
391                 winDebug
392                     ("winMWExtWMRestackWindows - DeferWindowPos (%p, %p)\n",
393                      pRLWin->hWnd, pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP);
394 #endif
395                 hWinPosInfo = DeferWindowPos(hWinPosInfo, pRLWin->hWnd,
396                                              pRLWinPrev ? pRLWinPrev->
397                                              hWnd : HWND_TOP, 0, 0, 0, 0,
398                                              uFlags);
399                 if (hWinPosInfo == NULL) {
400                     ErrorF
401                         ("winMWExtWMRestackWindows - DeferWindowPos () failed: %d\n",
402                          (int) GetLastError());
403                     return;
404                 }
405                 pWinPrev = pWin;
406             }
407         }
408         if (!EndDeferWindowPos(hWinPosInfo)) {
409             ErrorF
410                 ("winMWExtWMRestackWindows - EndDeferWindowPos () failed: %d\n",
411                  (int) GetLastError());
412             return;
413         }
414     }
415 
416 #if CYGMULTIWINDOW_DEBUG
417     winDebug("winMWExtWMRestackWindows - done\n");
418 #endif
419     pScreenPriv->fRestacking = FALSE;
420 }
421