Imported Upstream version 1.11.4
[ubuntu-omap:xserver.git] / hw / xwin / winwin32rootlesswindow.c
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     {
63 #if CYGMULTIWINDOW_DEBUG
64       winDebug ("winMWExtWMReorderWindows - Need to restack\n");
65 #endif
66       hwnd = GetTopWindow (NULL);
67
68       while (hwnd)
69         {
70           GetWindowThreadProcessId (hwnd, &dwWindowProcessID);
71
72           if ((dwWindowProcessID == dwCurrentProcessID)
73               && GetProp (hwnd, WIN_WINDOW_PROP))
74             {
75               pRLWinSib = pRLWin;
76               pRLWin = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP);
77               
78               if (pRLWinSib)
79                 {
80                   vlist[0] = pRLWinSib->pFrame->win->drawable.id;
81                   vlist[1] = Below;
82
83                   ConfigureWindow (pRLWin->pFrame->win, CWSibling | CWStackMode,
84                                    vlist, wClient(pRLWin->pFrame->win));
85                 }
86               else
87                 {
88                   /* 1st window - raise to the top */
89                   vlist[0] = Above;
90
91                   ConfigureWindow (pRLWin->pFrame->win, CWStackMode,
92                                    vlist, wClient(pRLWin->pFrame->win));
93                 }
94             }
95           hwnd = GetNextWindow (hwnd, GW_HWNDNEXT);
96         }
97     }
98
99   pScreenPriv->fRestacking = FALSE;
100   pScreenPriv->fWindowOrderChanged = FALSE;
101 }
102 #endif
103
104
105 /*
106  * winMWExtWMMoveXWindow
107  */
108
109 void
110 winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y)
111 {
112   CARD32 *vlist = malloc(sizeof(CARD32)*2);
113
114   vlist[0] = x;
115   vlist[1] = y;
116   ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin));
117   free(vlist);
118 }
119
120
121 /*
122  * winMWExtWMResizeXWindow
123  */
124
125 void
126 winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h)
127 {
128   CARD32 *vlist = malloc(sizeof(CARD32)*2);
129
130   vlist[0] = w;
131   vlist[1] = h;
132   ConfigureWindow (pWin, CWWidth | CWHeight, vlist, wClient(pWin));
133   free(vlist);
134 }
135
136
137 /*
138  * winMWExtWMMoveResizeXWindow
139  */
140
141 void
142 winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h)
143 {
144   CARD32 *vlist = malloc(sizeof(long)*4);
145
146   vlist[0] = x;
147   vlist[1] = y;
148   vlist[2] = w;
149   vlist[3] = h;
150
151   ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight, vlist, wClient(pWin));
152   free(vlist);
153 }
154
155
156 /*
157  * winMWExtWMUpdateIcon
158  * Change the Windows window icon
159  */
160
161 void
162 winMWExtWMUpdateIcon (Window id)
163 {
164   WindowPtr             pWin;
165   HICON                 hIcon, hiconOld;
166
167   dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess);
168   hIcon = winOverrideIcon ((unsigned long)pWin);
169
170   if (!hIcon)
171     hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON));
172
173   if (hIcon)
174     {
175       win32RootlessWindowPtr pRLWinPriv
176         = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
177
178       if (pRLWinPriv->hWnd)
179         {
180
181           hiconOld = (HICON) SendMessage (pRLWinPriv->hWnd,
182                      WM_SETICON, ICON_BIG, (LPARAM) hIcon);
183           winDestroyIcon(hiconOld);
184         }
185       hIcon=NULL;
186     }
187 }
188
189
190 /*
191  * winMWExtWMDecorateWindow - Update window style. Called by EnumWindows.
192  */
193
194 wBOOL CALLBACK
195 winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam)
196 {
197   win32RootlessWindowPtr pRLWinPriv = NULL;
198   ScreenPtr             pScreen = NULL;
199   winPrivScreenPtr      pScreenPriv = NULL;
200   winScreenInfo         *pScreenInfo = NULL;
201
202   /* Check if the Windows window property for our X window pointer is valid */
203   if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL)
204     {
205       pScreen                           = pRLWinPriv->pFrame->win->drawable.pScreen;
206       if (pScreen) pScreenPriv          = winGetScreenPriv(pScreen);
207       if (pScreenPriv) pScreenInfo      = pScreenPriv->pScreenInfo;
208       if (pRLWinPriv && pScreenInfo) winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo);
209     }
210   return TRUE;
211 }
212
213
214 /*
215  * winMWExtWMUpdateWindowDecoration - Update window style.
216  */
217
218 void
219 winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv,
220                                   winScreenInfoPtr pScreenInfo)
221 {
222   Bool          fDecorate = FALSE;
223   DWORD         dwExStyle = 0;
224   DWORD         dwStyle = 0;
225   WINDOWPLACEMENT wndPlace;
226   UINT          showCmd = 0;
227
228   wndPlace.length = sizeof (WINDOWPLACEMENT);
229
230   /* Get current window placement */
231   GetWindowPlacement (pRLWinPriv->hWnd, &wndPlace);
232
233   if (winIsInternalWMRunning(pScreenInfo))
234     {
235       if (!pRLWinPriv->pFrame->win->overrideRedirect)
236         fDecorate = TRUE;
237     }
238 #if 0
239   if (wndPlace.showCmd == SW_HIDE)
240     return;//showCmd = SWP_HIDEWINDOW;
241   else
242     showCmd = SWP_SHOWWINDOW;
243 #else
244   if (wndPlace.showCmd == SW_HIDE)
245     return;
246
247   if (IsWindowVisible (pRLWinPriv->hWnd))
248     showCmd = SWP_SHOWWINDOW;
249 #endif
250
251   showCmd |= SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER;
252
253   winDebug ("winMWExtWMUpdateWindowDecoration %08x %s\n",
254             (int)pRLWinPriv, fDecorate?"Decorate":"Bare");
255
256   /* Get the standard and extended window style information */
257   dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE);
258   dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE);
259
260   if (fDecorate)
261     {
262       RECT              rcNew;
263       int               iDx, iDy;
264       winWMMessageRec   wmMsg;
265       winScreenPriv(pScreenInfo->pScreen);
266
267       /* */
268       if (!(dwExStyle & WS_EX_APPWINDOW))
269         {
270           winDebug ("\tBare=>Decorate\n");
271           /* Setup a rectangle with the X window position and size */
272           SetRect (&rcNew,
273                    pRLWinPriv->pFrame->x,
274                    pRLWinPriv->pFrame->y,
275                    pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width,
276                    pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height);
277
278 #ifdef CYGMULTIWINDOW_DEBUG
279           winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n", 
280               rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
281               rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
282 #endif
283           /* */
284           AdjustWindowRectEx (&rcNew,
285                               WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW,
286                               FALSE,
287                               WS_EX_APPWINDOW);
288
289 #ifdef CYGMULTIWINDOW_DEBUG
290           winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n", 
291               rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
292               rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
293 #endif
294           /* Calculate position deltas */
295           iDx = pRLWinPriv->pFrame->x - rcNew.left;
296           iDy = pRLWinPriv->pFrame->y - rcNew.top;
297
298           /* Calculate new rectangle */
299           rcNew.left += iDx;
300           rcNew.right += iDx;
301           rcNew.top += iDy;
302           rcNew.bottom += iDy;
303
304           /* Set the window extended style flags */
305           SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
306
307           /* Set the window standard style flags */
308           SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE,
309                             WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW);
310
311 #ifdef CYGMULTIWINDOW_DEBUG
312           winDebug("\tWindowStyle: %08x %08x\n",
313               WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW,
314               WS_EX_APPWINDOW);
315 #endif
316           /* Position the Windows window */
317 #ifdef CYGMULTIWINDOW_DEBUG
318           winDebug("\tMoved {%d, %d, %d, %d}, {%d, %d}\n", 
319               rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
320               rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
321 #endif
322           SetWindowPos (pRLWinPriv->hWnd, NULL,
323                         rcNew.left, rcNew.top,
324                         rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
325                         showCmd);
326             
327
328           wmMsg.hwndWindow = pRLWinPriv->hWnd;
329           wmMsg.iWindow = (Window)pRLWinPriv->pFrame->win->drawable.id;
330           wmMsg.msg = WM_WM_NAME_EVENT;
331           winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
332
333           winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv ,
334                                   wBoundingShape(pRLWinPriv->pFrame->win));
335         }
336     }
337   else
338     {
339       RECT              rcNew;
340
341       /* */
342       if (dwExStyle & WS_EX_APPWINDOW)
343         {
344           winDebug ("\tDecorate=>Bare\n");
345           /* Setup a rectangle with the X window position and size */
346           SetRect (&rcNew,
347                    pRLWinPriv->pFrame->x,
348                    pRLWinPriv->pFrame->y,
349                    pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width,
350                    pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height);
351 #if 0
352           /* */
353           AdjustWindowRectEx (&rcNew,
354                               WS_POPUP | WS_CLIPCHILDREN,
355                               FALSE,
356                               WS_EX_TOOLWINDOW);
357
358           /* Calculate position deltas */
359           iDx = pRLWinPriv->pFrame->x - rcNew.left;
360           iDy = pRLWinPriv->pFrame->y - rcNew.top;
361
362           /* Calculate new rectangle */
363           rcNew.left += iDx;
364           rcNew.right += iDx;
365           rcNew.top += iDy;
366           rcNew.bottom += iDy;
367 #endif
368
369           /* Hide window temporary to remove from taskbar. */
370           ShowWindow( pRLWinPriv->hWnd, SW_HIDE );
371
372           /* Set the window extended style flags */
373           SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
374
375           /* Set the window standard style flags */
376           SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE,
377                             WS_POPUP | WS_CLIPCHILDREN);
378
379           /* Position the Windows window */
380           SetWindowPos (pRLWinPriv->hWnd, NULL,
381                         rcNew.left, rcNew.top,
382                         rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
383                         showCmd);
384
385           winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv ,
386                                   wBoundingShape(pRLWinPriv->pFrame->win));
387         }
388     }
389 }
390
391
392 /*
393  * winIsInternalWMRunning (winScreenInfoPtr pScreenInfo)
394  */
395 Bool
396 winIsInternalWMRunning (winScreenInfoPtr pScreenInfo)
397 {
398   return pScreenInfo->fInternalWM && !pScreenInfo->fAnotherWMRunning;
399 }
400
401
402 /*
403  * winMWExtWMRestackWindows
404  */
405
406 void
407 winMWExtWMRestackWindows (ScreenPtr pScreen)
408 {
409   winScreenPriv(pScreen);
410   WindowPtr pRoot = pScreen->root;
411   WindowPtr pWin = NULL;
412   WindowPtr pWinPrev = NULL;
413   win32RootlessWindowPtr pRLWin = NULL;
414   win32RootlessWindowPtr pRLWinPrev = NULL;
415   int  nWindow = 0;
416   HDWP hWinPosInfo = NULL;
417
418 #if CYGMULTIWINDOW_DEBUG
419   winDebug ("winMWExtWMRestackWindows\n");
420 #endif
421
422   pScreenPriv->fRestacking = TRUE;
423
424   if (pRoot != NULL)
425     {
426       for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib)
427         nWindow ++;
428
429       hWinPosInfo = BeginDeferWindowPos(nWindow);
430
431       for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib)
432         {
433           if (pWin->realized)
434             {
435               UINT uFlags;
436
437               pRLWin = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
438               if (pRLWin == NULL) continue;
439
440               if (pWinPrev)
441                 pRLWinPrev = (win32RootlessWindowPtr) RootlessFrameForWindow (pWinPrev, FALSE);
442
443               uFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW;
444               if (pRLWinPrev != NULL) uFlags |= SWP_NOACTIVATE;
445
446 #if CYGMULTIWINDOW_DEBUG
447               winDebug ("winMWExtWMRestackWindows - DeferWindowPos (%08x, %08x)\n",
448                         pRLWin->hWnd,
449                         pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP);
450 #endif
451               hWinPosInfo = DeferWindowPos (hWinPosInfo, pRLWin->hWnd,
452                                             pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP,
453                                             0, 0, 0, 0,
454                                             uFlags);
455               if (hWinPosInfo == NULL)
456                 {
457                   ErrorF ("winMWExtWMRestackWindows - DeferWindowPos () failed: %d\n",
458                           (int) GetLastError ());
459                   return;
460                 }
461               pWinPrev = pWin;
462             }
463         }
464       if (!EndDeferWindowPos (hWinPosInfo))
465         {
466           ErrorF ("winMWExtWMRestackWindows - EndDeferWindowPos () failed: %d\n",
467                   (int) GetLastError ());
468           return;
469         }
470     }
471
472 #if CYGMULTIWINDOW_DEBUG
473   winDebug ("winMWExtWMRestackWindows - done\n");
474 #endif
475   pScreenPriv->fRestacking = FALSE;
476 }