Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xwin / winwin32rootlesswindow.c
CommitLineData
a09e091a
JB
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
44void
45winMWExtWMReorderWindows(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
105void
106winMWExtWMMoveXWindow(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
120void
121winMWExtWMResizeXWindow(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
135void
136winMWExtWMMoveResizeXWindow(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
155wBOOL CALLBACK
156winMWExtWMDecorateWindow(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
183void
184winMWExtWMUpdateWindowDecoration(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 (winIsInternalWMRunning(pScreenInfo)) {
198 if (!pRLWinPriv->pFrame->win->overrideRedirect)
199 fDecorate = TRUE;
200 }
201#if 0
202 if (wndPlace.showCmd == SW_HIDE)
203 return; //showCmd = SWP_HIDEWINDOW;
204 else
205 showCmd = SWP_SHOWWINDOW;
206#else
207 if (wndPlace.showCmd == SW_HIDE)
208 return;
209
210 if (IsWindowVisible(pRLWinPriv->hWnd))
211 showCmd = SWP_SHOWWINDOW;
212#endif
213
214 showCmd |= SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER;
215
216 winDebug("winMWExtWMUpdateWindowDecoration %p %s\n",
217 pRLWinPriv, fDecorate ? "Decorate" : "Bare");
218
219 /* Get the extended window style information */
220 dwExStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE);
221
222 if (fDecorate) {
223 RECT rcNew;
224 int iDx, iDy;
225 winWMMessageRec wmMsg;
226
227 winScreenPriv(pScreenInfo->pScreen);
228
229 /* */
230 if (!(dwExStyle & WS_EX_APPWINDOW)) {
231 winDebug("\tBare=>Decorate\n");
232 /* Setup a rectangle with the X window position and size */
233 SetRect(&rcNew,
234 pRLWinPriv->pFrame->x,
235 pRLWinPriv->pFrame->y,
236 pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width,
237 pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height);
238
239#ifdef CYGMULTIWINDOW_DEBUG
240 winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
241 rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
242 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
243#endif
244 /* */
245 AdjustWindowRectEx(&rcNew,
246 WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW,
247 FALSE, WS_EX_APPWINDOW);
248
249#ifdef CYGMULTIWINDOW_DEBUG
250 winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n",
251 rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
252 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
253#endif
254 /* Calculate position deltas */
255 iDx = pRLWinPriv->pFrame->x - rcNew.left;
256 iDy = pRLWinPriv->pFrame->y - rcNew.top;
257
258 /* Calculate new rectangle */
259 rcNew.left += iDx;
260 rcNew.right += iDx;
261 rcNew.top += iDy;
262 rcNew.bottom += iDy;
263
264 /* Set the window extended style flags */
265 SetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
266
267 /* Set the window standard style flags */
268 SetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE,
269 WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW);
270
271#ifdef CYGMULTIWINDOW_DEBUG
272 winDebug("\tWindowStyle: %08x %08x\n",
273 WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW,
274 WS_EX_APPWINDOW);
275#endif
276 /* Position the Windows window */
277#ifdef CYGMULTIWINDOW_DEBUG
278 winDebug("\tMoved {%d, %d, %d, %d}, {%d, %d}\n",
279 rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
280 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
281#endif
282 SetWindowPos(pRLWinPriv->hWnd, NULL,
283 rcNew.left, rcNew.top,
284 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
285 showCmd);
286
287 wmMsg.hwndWindow = pRLWinPriv->hWnd;
288 wmMsg.iWindow = (Window) pRLWinPriv->pFrame->win->drawable.id;
289 wmMsg.msg = WM_WM_NAME_EVENT;
290 winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
291
292 winMWExtWMReshapeFrame((RootlessFrameID) pRLWinPriv,
293 wBoundingShape(pRLWinPriv->pFrame->win));
294 }
295 }
296 else {
297 RECT rcNew;
298
299 /* */
300 if (dwExStyle & WS_EX_APPWINDOW) {
301 winDebug("\tDecorate=>Bare\n");
302 /* Setup a rectangle with the X window position and size */
303 SetRect(&rcNew,
304 pRLWinPriv->pFrame->x,
305 pRLWinPriv->pFrame->y,
306 pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width,
307 pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height);
308#if 0
309 /* */
310 AdjustWindowRectEx(&rcNew,
311 WS_POPUP | WS_CLIPCHILDREN,
312 FALSE, WS_EX_TOOLWINDOW);
313
314 /* Calculate position deltas */
315 iDx = pRLWinPriv->pFrame->x - rcNew.left;
316 iDy = pRLWinPriv->pFrame->y - rcNew.top;
317
318 /* Calculate new rectangle */
319 rcNew.left += iDx;
320 rcNew.right += iDx;
321 rcNew.top += iDy;
322 rcNew.bottom += iDy;
323#endif
324
325 /* Hide window temporary to remove from taskbar. */
326 ShowWindow(pRLWinPriv->hWnd, SW_HIDE);
327
328 /* Set the window extended style flags */
329 SetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
330
331 /* Set the window standard style flags */
332 SetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE,
333 WS_POPUP | WS_CLIPCHILDREN);
334
335 /* Position the Windows window */
336 SetWindowPos(pRLWinPriv->hWnd, NULL,
337 rcNew.left, rcNew.top,
338 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
339 showCmd);
340
341 winMWExtWMReshapeFrame((RootlessFrameID) pRLWinPriv,
342 wBoundingShape(pRLWinPriv->pFrame->win));
343 }
344 }
345}
346
347/*
348 * winIsInternalWMRunning (winScreenInfoPtr pScreenInfo)
349 */
350Bool
351winIsInternalWMRunning(winScreenInfoPtr pScreenInfo)
352{
353 return pScreenInfo->fInternalWM && !pScreenInfo->fAnotherWMRunning;
354}
355
356/*
357 * winMWExtWMRestackWindows
358 */
359
360void
361winMWExtWMRestackWindows(ScreenPtr pScreen)
362{
363 winScreenPriv(pScreen);
364 WindowPtr pRoot = pScreen->root;
365 WindowPtr pWin = NULL;
366 WindowPtr pWinPrev = NULL;
367 win32RootlessWindowPtr pRLWin = NULL;
368 win32RootlessWindowPtr pRLWinPrev = NULL;
369 int nWindow = 0;
370 HDWP hWinPosInfo = NULL;
371
372#if CYGMULTIWINDOW_DEBUG
373 winDebug("winMWExtWMRestackWindows\n");
374#endif
375
376 pScreenPriv->fRestacking = TRUE;
377
378 if (pRoot != NULL) {
379 for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib)
380 nWindow++;
381
382 hWinPosInfo = BeginDeferWindowPos(nWindow);
383
384 for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) {
385 if (pWin->realized) {
386 UINT uFlags;
387
388 pRLWin =
389 (win32RootlessWindowPtr) RootlessFrameForWindow(pWin,
390 FALSE);
391 if (pRLWin == NULL)
392 continue;
393
394 if (pWinPrev)
395 pRLWinPrev =
396 (win32RootlessWindowPtr)
397 RootlessFrameForWindow(pWinPrev, FALSE);
398
399 uFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW;
400 if (pRLWinPrev != NULL)
401 uFlags |= SWP_NOACTIVATE;
402
403#if CYGMULTIWINDOW_DEBUG
404 winDebug
405 ("winMWExtWMRestackWindows - DeferWindowPos (%08x, %08x)\n",
406 pRLWin->hWnd, pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP);
407#endif
408 hWinPosInfo = DeferWindowPos(hWinPosInfo, pRLWin->hWnd,
409 pRLWinPrev ? pRLWinPrev->
410 hWnd : HWND_TOP, 0, 0, 0, 0,
411 uFlags);
412 if (hWinPosInfo == NULL) {
413 ErrorF
414 ("winMWExtWMRestackWindows - DeferWindowPos () failed: %d\n",
415 (int) GetLastError());
416 return;
417 }
418 pWinPrev = pWin;
419 }
420 }
421 if (!EndDeferWindowPos(hWinPosInfo)) {
422 ErrorF
423 ("winMWExtWMRestackWindows - EndDeferWindowPos () failed: %d\n",
424 (int) GetLastError());
425 return;
426 }
427 }
428
429#if CYGMULTIWINDOW_DEBUG
430 winDebug("winMWExtWMRestackWindows - done\n");
431#endif
432 pScreenPriv->fRestacking = FALSE;
433}