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