First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xwin / winmultiwindowwindow.c
blob037c881b42f9401ecff6f6da8128a69ca944cdf8
1 /*
2 *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
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:
12 *The above copyright notice and this permission notice shall be
13 *included in all copies or substantial portions of the Software.
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.
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.
28 * Authors: Kensuke Matsuzaki
29 * Earle F. Philhower, III
30 * Harold L Hunt II
33 #ifdef HAVE_XWIN_CONFIG_H
34 #include <xwin-config.h>
35 #endif
36 #include "win.h"
37 #include "dixevents.h"
38 #include "winmultiwindowclass.h"
39 #include "winprefs.h"
42 * External global variables
45 extern HWND g_hDlgDepthChange;
47 extern void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon);
50 * Prototypes for local functions
53 void
54 winCreateWindowsWindow (WindowPtr pWin);
56 static void
57 winDestroyWindowsWindow (WindowPtr pWin);
59 static void
60 winUpdateWindowsWindow (WindowPtr pWin);
62 static void
63 winFindWindow (pointer value, XID id, pointer cdata);
66 * Constant defines
69 #define MOUSE_POLLING_INTERVAL 500
73 * Macros
76 #define SubSend(pWin) \
77 ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
79 #define StrSend(pWin) \
80 ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
82 #define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
86 * CreateWindow - See Porting Layer Definition - p. 37
89 Bool
90 winCreateWindowMultiWindow (WindowPtr pWin)
92 Bool fResult = TRUE;
93 ScreenPtr pScreen = pWin->drawable.pScreen;
94 winWindowPriv(pWin);
95 winScreenPriv(pScreen);
97 #if CYGMULTIWINDOW_DEBUG
98 winTrace ("winCreateWindowMultiWindow - pWin: %p\n", pWin);
99 #endif
101 WIN_UNWRAP(CreateWindow);
102 fResult = (*pScreen->CreateWindow) (pWin);
103 WIN_WRAP(CreateWindow, winCreateWindowMultiWindow);
105 /* Initialize some privates values */
106 pWinPriv->hRgn = NULL;
107 pWinPriv->hWnd = NULL;
108 pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen);
109 pWinPriv->fXKilled = FALSE;
111 return fResult;
116 * DestroyWindow - See Porting Layer Definition - p. 37
119 Bool
120 winDestroyWindowMultiWindow (WindowPtr pWin)
122 Bool fResult = TRUE;
123 ScreenPtr pScreen = pWin->drawable.pScreen;
124 winWindowPriv(pWin);
125 winScreenPriv(pScreen);
127 #if CYGMULTIWINDOW_DEBUG
128 ErrorF ("winDestroyWindowMultiWindow - pWin: %p\n", pWin);
129 #endif
131 WIN_UNWRAP(DestroyWindow);
132 fResult = (*pScreen->DestroyWindow)(pWin);
133 WIN_WRAP(DestroyWindow, winDestroyWindowMultiWindow);
135 /* Flag that the window has been destroyed */
136 pWinPriv->fXKilled = TRUE;
138 /* Kill the MS Windows window associated with this window */
139 winDestroyWindowsWindow (pWin);
141 return fResult;
146 * PositionWindow - See Porting Layer Definition - p. 37
148 * This function adjusts the position and size of Windows window
149 * with respect to the underlying X window. This is the inverse
150 * of winAdjustXWindow, which adjusts X window to Windows window.
153 Bool
154 winPositionWindowMultiWindow (WindowPtr pWin, int x, int y)
156 Bool fResult = TRUE;
157 int iX, iY, iWidth, iHeight;
158 ScreenPtr pScreen = pWin->drawable.pScreen;
159 winWindowPriv(pWin);
160 winScreenPriv(pScreen);
162 HWND hWnd = pWinPriv->hWnd;
163 RECT rcNew;
164 RECT rcOld;
165 #if CYGMULTIWINDOW_DEBUG
166 RECT rcClient;
167 RECT *lpRc;
168 #endif
169 DWORD dwExStyle;
170 DWORD dwStyle;
172 #if CYGMULTIWINDOW_DEBUG
173 winTrace ("winPositionWindowMultiWindow - pWin: %p\n", pWin);
174 #endif
176 WIN_UNWRAP(PositionWindow);
177 fResult = (*pScreen->PositionWindow)(pWin, x, y);
178 WIN_WRAP(PositionWindow, winPositionWindowMultiWindow);
180 #if CYGWINDOWING_DEBUG
181 ErrorF ("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n",
182 x, y);
183 #endif
185 /* Bail out if the Windows window handle is bad */
186 if (!hWnd)
188 #if CYGWINDOWING_DEBUG
189 ErrorF ("\timmediately return since hWnd is NULL\n");
190 #endif
191 return fResult;
194 /* Get the Windows window style and extended style */
195 dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE);
196 dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE);
198 /* Get the X and Y location of the X window */
199 iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
200 iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
202 /* Get the height and width of the X window */
203 iWidth = pWin->drawable.width;
204 iHeight = pWin->drawable.height;
206 /* Store the origin, height, and width in a rectangle structure */
207 SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight);
209 #if CYGMULTIWINDOW_DEBUG
210 lpRc = &rcNew;
211 ErrorF ("winPositionWindowMultiWindow - (%d ms)drawable (%d, %d)-(%d, %d)\n",
212 GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
213 #endif
216 * Calculate the required size of the Windows window rectangle,
217 * given the size of the Windows window client area.
219 AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle);
221 /* Get a rectangle describing the old Windows window */
222 GetWindowRect (hWnd, &rcOld);
224 #if CYGMULTIWINDOW_DEBUG
225 /* Get a rectangle describing the Windows window client area */
226 GetClientRect (hWnd, &rcClient);
228 lpRc = &rcNew;
229 ErrorF ("winPositionWindowMultiWindow - (%d ms)rcNew (%d, %d)-(%d, %d)\n",
230 GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
232 lpRc = &rcOld;
233 ErrorF ("winPositionWindowMultiWindow - (%d ms)rcOld (%d, %d)-(%d, %d)\n",
234 GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
236 lpRc = &rcClient;
237 ErrorF ("(%d ms)rcClient (%d, %d)-(%d, %d)\n",
238 GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
239 #endif
241 /* Check if the old rectangle and new rectangle are the same */
242 if (!EqualRect (&rcNew, &rcOld))
244 #if CYGMULTIWINDOW_DEBUG
245 ErrorF ("winPositionWindowMultiWindow - Need to move\n");
246 #endif
248 #if CYGWINDOWING_DEBUG
249 ErrorF ("\tMoveWindow to (%ld, %ld) - %ldx%ld\n", rcNew.left, rcNew.top,
250 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
251 #endif
252 /* Change the position and dimensions of the Windows window */
253 MoveWindow (hWnd,
254 rcNew.left, rcNew.top,
255 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
256 TRUE);
258 else
260 #if CYGMULTIWINDOW_DEBUG
261 ErrorF ("winPositionWindowMultiWindow - Not need to move\n");
262 #endif
265 return fResult;
270 * ChangeWindowAttributes - See Porting Layer Definition - p. 37
273 Bool
274 winChangeWindowAttributesMultiWindow (WindowPtr pWin, unsigned long mask)
276 Bool fResult = TRUE;
277 ScreenPtr pScreen = pWin->drawable.pScreen;
278 winWindowPriv(pWin);
279 winScreenPriv(pScreen);
281 #if CYGMULTIWINDOW_DEBUG
282 ErrorF ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin);
283 #endif
285 WIN_UNWRAP(ChangeWindowAttributes);
286 fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask);
287 WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesMultiWindow);
290 * NOTE: We do not currently need to do anything here.
293 return fResult;
298 * UnmapWindow - See Porting Layer Definition - p. 37
299 * Also referred to as UnrealizeWindow
302 Bool
303 winUnmapWindowMultiWindow (WindowPtr pWin)
305 Bool fResult = TRUE;
306 ScreenPtr pScreen = pWin->drawable.pScreen;
307 winWindowPriv(pWin);
308 winScreenPriv(pScreen);
310 #if CYGMULTIWINDOW_DEBUG
311 ErrorF ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin);
312 #endif
314 WIN_UNWRAP(UnrealizeWindow);
315 fResult = (*pScreen->UnrealizeWindow)(pWin);
316 WIN_WRAP(UnrealizeWindow, winUnmapWindowMultiWindow);
318 /* Flag that the window has been killed */
319 pWinPriv->fXKilled = TRUE;
321 /* Destroy the Windows window associated with this X window */
322 winDestroyWindowsWindow (pWin);
324 return fResult;
329 * MapWindow - See Porting Layer Definition - p. 37
330 * Also referred to as RealizeWindow
333 Bool
334 winMapWindowMultiWindow (WindowPtr pWin)
336 Bool fResult = TRUE;
337 ScreenPtr pScreen = pWin->drawable.pScreen;
338 winWindowPriv(pWin);
339 winScreenPriv(pScreen);
341 #if CYGMULTIWINDOW_DEBUG
342 ErrorF ("winMapWindowMultiWindow - pWin: %08x\n", pWin);
343 #endif
345 WIN_UNWRAP(RealizeWindow);
346 fResult = (*pScreen->RealizeWindow)(pWin);
347 WIN_WRAP(RealizeWindow, winMapWindowMultiWindow);
349 /* Flag that this window has not been destroyed */
350 pWinPriv->fXKilled = FALSE;
352 /* Refresh/redisplay the Windows window associated with this X window */
353 winUpdateWindowsWindow (pWin);
355 #ifdef SHAPE
356 /* Update the Windows window's shape */
357 winReshapeMultiWindow (pWin);
358 winUpdateRgnMultiWindow (pWin);
359 #endif
361 return fResult;
366 * ReparentWindow - See Porting Layer Definition - p. 42
369 void
370 winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent)
372 ScreenPtr pScreen = pWin->drawable.pScreen;
373 winWindowPriv(pWin);
374 winScreenPriv(pScreen);
376 #if CYGMULTIWINDOW_DEBUG
377 ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin);
378 #endif
380 WIN_UNWRAP(ReparentWindow);
381 if (pScreen->ReparentWindow)
382 (*pScreen->ReparentWindow)(pWin, pPriorParent);
383 WIN_WRAP(ReparentWindow, winReparentWindowMultiWindow);
385 /* Update the Windows window associated with this X window */
386 winUpdateWindowsWindow (pWin);
391 * RestackWindow - Shuffle the z-order of a window
394 void
395 winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib)
397 WindowPtr pPrevWin;
398 UINT uFlags;
399 HWND hInsertAfter;
400 HWND hWnd = NULL;
401 ScreenPtr pScreen = pWin->drawable.pScreen;
402 winWindowPriv(pWin);
403 winScreenPriv(pScreen);
405 #if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
406 winTrace ("winRestackMultiWindow - %08x\n", pWin);
407 #endif
409 WIN_UNWRAP(RestackWindow);
410 if (pScreen->RestackWindow)
411 (*pScreen->RestackWindow)(pWin, pOldNextSib);
412 WIN_WRAP(RestackWindow, winRestackWindowMultiWindow);
414 #if 1
416 * Calling winReorderWindowsMultiWindow here means our window manager
417 * (i.e. Windows Explorer) has initiative to determine Z order.
419 if (pWin->nextSib != pOldNextSib)
420 winReorderWindowsMultiWindow ();
421 #else
422 /* Bail out if no window privates or window handle is invalid */
423 if (!pWinPriv || !pWinPriv->hWnd)
424 return;
426 /* Get a pointer to our previous sibling window */
427 pPrevWin = pWin->prevSib;
430 * Look for a sibling window with
431 * valid privates and window handle
433 while (pPrevWin
434 && !winGetWindowPriv(pPrevWin)
435 && !winGetWindowPriv(pPrevWin)->hWnd)
436 pPrevWin = pPrevWin->prevSib;
438 /* Check if we found a valid sibling */
439 if (pPrevWin)
441 /* Valid sibling - get handle to insert window after */
442 hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd;
443 uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
445 hWnd = GetNextWindow (pWinPriv->hWnd, GW_HWNDPREV);
449 if (GetProp (hWnd, WIN_WINDOW_PROP))
451 if (hWnd == winGetWindowPriv(pPrevWin)->hWnd)
453 uFlags |= SWP_NOZORDER;
455 break;
457 hWnd = GetNextWindow (hWnd, GW_HWNDPREV);
459 while (hWnd);
461 else
463 /* No valid sibling - make this window the top window */
464 hInsertAfter = HWND_TOP;
465 uFlags = SWP_NOMOVE | SWP_NOSIZE;
468 /* Perform the restacking operation in Windows */
469 SetWindowPos (pWinPriv->hWnd,
470 hInsertAfter,
471 0, 0,
472 0, 0,
473 uFlags);
474 #endif
479 * winCreateWindowsWindow - Create a Windows window associated with an X window
482 void
483 winCreateWindowsWindow (WindowPtr pWin)
485 int iX, iY;
486 int iWidth;
487 int iHeight;
488 HWND hWnd;
489 WNDCLASSEX wc;
490 winWindowPriv(pWin);
491 HICON hIcon;
492 HICON hIconSmall;
493 #define CLASS_NAME_LENGTH 512
494 char pszClass[CLASS_NAME_LENGTH], pszWindowID[12];
495 char *res_name, *res_class, *res_role;
496 static int s_iWindowID = 0;
497 winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv;
498 WinXSizeHints hints;
500 #if CYGMULTIWINDOW_DEBUG
501 ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin);
502 #endif
504 iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
505 iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
507 /* Default positions if none specified */
508 if (!winMultiWindowGetWMNormalHints(pWin, &hints))
509 hints.flags = 0;
510 if ( !(hints.flags & (USPosition|PPosition)) &&
511 !winMultiWindowGetTransientFor (pWin, NULL) &&
512 !pWin->overrideRedirect )
514 iX = CW_USEDEFAULT;
515 iY = CW_USEDEFAULT;
518 iWidth = pWin->drawable.width;
519 iHeight = pWin->drawable.height;
521 winSelectIcons(pWin, &hIcon, &hIconSmall);
523 /* Set standard class name prefix so we can identify window easily */
524 strncpy (pszClass, WINDOW_CLASS_X, sizeof(pszClass));
526 if (winMultiWindowGetClassHint (pWin, &res_name, &res_class))
528 strncat (pszClass, "-", 1);
529 strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass));
530 strncat (pszClass, "-", 1);
531 strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass));
533 /* Check if a window class is provided by the WM_WINDOW_ROLE property,
534 * if not use the WM_CLASS information.
535 * For further information see:
536 * http://tronche.com/gui/x/icccm/sec-5.html
538 if (winMultiWindowGetWindowRole (pWin, &res_role) )
540 strcat (pszClass, "-");
541 strcat (pszClass, res_role);
542 free (res_role);
545 free (res_name);
546 free (res_class);
549 /* Add incrementing window ID to make unique class name */
550 snprintf (pszWindowID, sizeof(pszWindowID), "-%x", s_iWindowID++);
551 pszWindowID[sizeof(pszWindowID)-1] = 0;
552 strcat (pszClass, pszWindowID);
554 #if CYGMULTIWINDOW_DEBUG
555 ErrorF ("winCreateWindowsWindow - Creating class: %s\n", pszClass);
556 #endif
558 /* Setup our window class */
559 wc.cbSize = sizeof(wc);
560 wc.style = CS_HREDRAW | CS_VREDRAW;
561 wc.lpfnWndProc = winTopLevelWindowProc;
562 wc.cbClsExtra = 0;
563 wc.cbWndExtra = 0;
564 wc.hInstance = g_hInstance;
565 wc.hIcon = hIcon;
566 wc.hIconSm = hIconSmall;
567 wc.hCursor = 0;
568 wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
569 wc.lpszMenuName = NULL;
570 wc.lpszClassName = pszClass;
571 RegisterClassEx (&wc);
573 /* Create the window */
574 /* Make it OVERLAPPED in create call since WS_POPUP doesn't support */
575 /* CW_USEDEFAULT, change back to popup after creation */
576 hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */
577 pszClass, /* Class name */
578 WINDOW_TITLE_X, /* Window name */
579 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
580 iX, /* Horizontal position */
581 iY, /* Vertical position */
582 iWidth, /* Right edge */
583 iHeight, /* Bottom edge */
584 (HWND) NULL, /* No parent or owner window */
585 (HMENU) NULL, /* No menu */
586 GetModuleHandle (NULL), /* Instance handle */
587 pWin); /* ScreenPrivates */
588 if (hWnd == NULL)
590 ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
591 (int) GetLastError ());
594 /* Change style back to popup, already placed... */
595 SetWindowLong (hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
596 SetWindowPos (hWnd, 0, 0, 0, 0, 0,
597 SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
598 /* Make sure it gets the proper system menu for a WS_POPUP, too */
599 GetSystemMenu (hWnd, TRUE);
601 pWinPriv->hWnd = hWnd;
603 /* Cause any .XWinrc menus to be added in main WNDPROC */
604 PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0);
606 SetProp (pWinPriv->hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin));
608 /* Flag that this Windows window handles its own activation */
609 SetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0);
611 /* Call engine-specific create window procedure */
612 (*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin);
616 Bool winInDestroyWindowsWindow = FALSE;
618 * winDestroyWindowsWindow - Destroy a Windows window associated
619 * with an X window
621 static void
622 winDestroyWindowsWindow (WindowPtr pWin)
624 MSG msg;
625 winWindowPriv(pWin);
626 HICON hiconClass;
627 HICON hiconSmClass;
628 HMODULE hInstance;
629 int iReturn;
630 char pszClass[512];
631 BOOL oldstate = winInDestroyWindowsWindow;
633 #if CYGMULTIWINDOW_DEBUG
634 ErrorF ("winDestroyWindowsWindow\n");
635 #endif
637 /* Bail out if the Windows window handle is invalid */
638 if (pWinPriv->hWnd == NULL)
639 return;
641 winInDestroyWindowsWindow = TRUE;
643 /* Store the info we need to destroy after this window is gone */
644 hInstance = (HINSTANCE) GetClassLong (pWinPriv->hWnd, GCL_HMODULE);
645 hiconClass = (HICON) GetClassLong (pWinPriv->hWnd, GCL_HICON);
646 hiconSmClass = (HICON) GetClassLong (pWinPriv->hWnd, GCL_HICONSM);
647 iReturn = GetClassName (pWinPriv->hWnd, pszClass, 512);
649 SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, NULL);
650 /* Destroy the Windows window */
651 DestroyWindow (pWinPriv->hWnd);
653 /* Null our handle to the Window so referencing it will cause an error */
654 pWinPriv->hWnd = NULL;
656 /* Process all messages on our queue */
657 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
659 if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg))
661 DispatchMessage (&msg);
665 /* Only if we were able to get the name */
666 if (iReturn)
668 #if CYGMULTIWINDOW_DEBUG
669 ErrorF ("winDestroyWindowsWindow - Unregistering %s: ", pszClass);
670 #endif
671 iReturn = UnregisterClass (pszClass, hInstance);
673 #if CYGMULTIWINDOW_DEBUG
674 ErrorF ("winDestroyWindowsWindow - %d Deleting Icon: ", iReturn);
675 #endif
677 winDestroyIcon(hiconClass);
678 winDestroyIcon(hiconSmClass);
681 winInDestroyWindowsWindow = oldstate;
683 #if CYGMULTIWINDOW_DEBUG
684 ErrorF ("-winDestroyWindowsWindow\n");
685 #endif
690 * winUpdateWindowsWindow - Redisplay/redraw a Windows window
691 * associated with an X window
694 static void
695 winUpdateWindowsWindow (WindowPtr pWin)
697 winWindowPriv(pWin);
698 HWND hWnd = pWinPriv->hWnd;
700 #if CYGMULTIWINDOW_DEBUG
701 ErrorF ("winUpdateWindowsWindow\n");
702 #endif
704 /* Check if the Windows window's parents have been destroyed */
705 if (pWin->parent != NULL
706 && pWin->parent->parent == NULL
707 && pWin->mapped)
709 /* Create the Windows window if it has been destroyed */
710 if (hWnd == NULL)
712 winCreateWindowsWindow (pWin);
713 assert (pWinPriv->hWnd != NULL);
716 /* Display the window without activating it */
717 ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE);
719 /* Send first paint message */
720 UpdateWindow (pWinPriv->hWnd);
722 else if (hWnd != NULL)
724 /* Destroy the Windows window if its parents are destroyed */
725 winDestroyWindowsWindow (pWin);
726 assert (pWinPriv->hWnd == NULL);
729 #if CYGMULTIWINDOW_DEBUG
730 ErrorF ("-winUpdateWindowsWindow\n");
731 #endif
736 * winGetWindowID -
740 winGetWindowID (WindowPtr pWin)
742 WindowIDPairRec wi = {pWin, 0};
743 ClientPtr c = wClient(pWin);
745 /* */
746 FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi);
748 #if CYGMULTIWINDOW_DEBUG
749 ErrorF ("winGetWindowID - Window ID: %d\n", wi.id);
750 #endif
752 return wi.id;
757 * winFindWindow -
760 static void
761 winFindWindow (pointer value, XID id, pointer cdata)
763 WindowIDPairPtr wi = (WindowIDPairPtr)cdata;
765 if (value == wi->value)
767 wi->id = id;
773 * winReorderWindowsMultiWindow -
776 void
777 winReorderWindowsMultiWindow (void)
779 HWND hwnd = NULL;
780 WindowPtr pWin = NULL;
781 WindowPtr pWinSib = NULL;
782 XID vlist[2];
783 static Bool fRestacking = FALSE; /* Avoid recusive calls to this function */
784 DWORD dwCurrentProcessID = GetCurrentProcessId ();
785 DWORD dwWindowProcessID = 0;
787 #if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
788 winTrace ("winReorderWindowsMultiWindow\n");
789 #endif
791 if (fRestacking)
793 /* It is a recusive call so immediately exit */
794 #if CYGWINDOWING_DEBUG
795 ErrorF ("winReorderWindowsMultiWindow - "
796 "exit because fRestacking == TRUE\n");
797 #endif
798 return;
800 fRestacking = TRUE;
802 /* Loop through top level Window windows, descending in Z order */
803 for ( hwnd = GetTopWindow (NULL);
804 hwnd;
805 hwnd = GetNextWindow (hwnd, GW_HWNDNEXT) )
807 /* Don't take care of other Cygwin/X process's windows */
808 GetWindowThreadProcessId (hwnd, &dwWindowProcessID);
810 if ( GetProp (hwnd, WIN_WINDOW_PROP)
811 && (dwWindowProcessID == dwCurrentProcessID)
812 && !IsIconic (hwnd) ) /* ignore minimized windows */
814 pWinSib = pWin;
815 pWin = GetProp (hwnd, WIN_WINDOW_PROP);
817 if (!pWinSib)
818 { /* 1st window - raise to the top */
819 vlist[0] = Above;
821 ConfigureWindow (pWin, CWStackMode, vlist, wClient(pWin));
823 else
824 { /* 2nd or deeper windows - just below the previous one */
825 vlist[0] = winGetWindowID (pWinSib);
826 vlist[1] = Below;
828 ConfigureWindow (pWin, CWSibling | CWStackMode,
829 vlist, wClient(pWin));
834 fRestacking = FALSE;
839 * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE
842 void
843 winMinimizeWindow (Window id)
845 WindowPtr pWin;
846 winPrivWinPtr pWinPriv;
847 #ifdef XWIN_MULTIWINDOWEXTWM
848 win32RootlessWindowPtr pRLWinPriv;
849 #endif
850 HWND hWnd;
851 ScreenPtr pScreen = NULL;
852 winPrivScreenPtr pScreenPriv = NULL;
853 winScreenInfo *pScreenInfo = NULL;
855 #if CYGWINDOWING_DEBUG
856 ErrorF ("winMinimizeWindow\n");
857 #endif
859 pWin = LookupIDByType (id, RT_WINDOW);
860 if (!pWin)
862 ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__);
863 return;
866 pScreen = pWin->drawable.pScreen;
867 if (pScreen) pScreenPriv = winGetScreenPriv(pScreen);
868 if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
870 #ifdef XWIN_MULTIWINDOWEXTWM
871 if (pScreenPriv && pScreenInfo->fInternalWM)
873 pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
874 hWnd = pRLWinPriv->hWnd;
876 else
877 #else
878 if (pScreenPriv)
879 #endif
881 pWinPriv = winGetWindowPriv (pWin);
882 hWnd = pWinPriv->hWnd;
885 ShowWindow (hWnd, SW_MINIMIZE);
890 * CopyWindow - See Porting Layer Definition - p. 39
892 void
893 winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt,
894 RegionPtr oldRegion)
896 ScreenPtr pScreen = pWin->drawable.pScreen;
897 winWindowPriv(pWin);
898 winScreenPriv(pScreen);
900 #if CYGWINDOWING_DEBUG
901 ErrorF ("CopyWindowMultiWindow\n");
902 #endif
903 WIN_UNWRAP(CopyWindow);
904 (*pScreen->CopyWindow)(pWin, oldpt, oldRegion);
905 WIN_WRAP(CopyWindow, winCopyWindowMultiWindow);
910 * MoveWindow - See Porting Layer Definition - p. 42
912 void
913 winMoveWindowMultiWindow (WindowPtr pWin, int x, int y,
914 WindowPtr pSib, VTKind kind)
916 ScreenPtr pScreen = pWin->drawable.pScreen;
917 winWindowPriv(pWin);
918 winScreenPriv(pScreen);
920 #if CYGWINDOWING_DEBUG
921 ErrorF ("MoveWindowMultiWindow to (%d, %d)\n", x, y);
922 #endif
924 WIN_UNWRAP(MoveWindow);
925 (*pScreen->MoveWindow)(pWin, x, y, pSib, kind);
926 WIN_WRAP(MoveWindow, winMoveWindowMultiWindow);
931 * ResizeWindow - See Porting Layer Definition - p. 42
933 void
934 winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w,
935 unsigned int h, WindowPtr pSib)
937 ScreenPtr pScreen = pWin->drawable.pScreen;
938 winWindowPriv(pWin);
939 winScreenPriv(pScreen);
941 #if CYGWINDOWING_DEBUG
942 ErrorF ("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x, y, w, h);
943 #endif
944 WIN_UNWRAP(ResizeWindow);
945 (*pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
946 WIN_WRAP(ResizeWindow, winResizeWindowMultiWindow);
951 * winAdjustXWindow
953 * Move and resize X window with respect to corresponding Windows window.
954 * This is called from WM_MOVE/WM_SIZE handlers when the user performs
955 * any windowing operation (move, resize, minimize, maximize, restore).
957 * The functionality is the inverse of winPositionWindowMultiWindow, which
958 * adjusts Windows window with respect to X window.
961 winAdjustXWindow (WindowPtr pWin, HWND hwnd)
963 RECT rcDraw; /* Rect made from pWin->drawable to be adjusted */
964 RECT rcWin; /* The source: WindowRect from hwnd */
965 DrawablePtr pDraw;
966 XID vlist[4];
967 LONG dX, dY, dW, dH, x, y;
968 DWORD dwStyle, dwExStyle;
970 #define WIDTH(rc) (rc.right - rc.left)
971 #define HEIGHT(rc) (rc.bottom - rc.top)
973 #if CYGWINDOWING_DEBUG
974 ErrorF ("winAdjustXWindow\n");
975 #endif
977 if (IsIconic (hwnd))
979 #if CYGWINDOWING_DEBUG
980 ErrorF ("\timmediately return because the window is iconized\n");
981 #endif
983 * If the Windows window is minimized, its WindowRect has
984 * meaningless values so we don't adjust X window to it.
986 vlist[0] = 0;
987 vlist[1] = 0;
988 return ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin));
991 pDraw = &pWin->drawable;
993 /* Calculate the window rect from the drawable */
994 x = pDraw->x + GetSystemMetrics (SM_XVIRTUALSCREEN);
995 y = pDraw->y + GetSystemMetrics (SM_YVIRTUALSCREEN);
996 SetRect (&rcDraw, x, y, x + pDraw->width, y + pDraw->height);
997 #ifdef CYGMULTIWINDOW_DEBUG
998 winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n",
999 rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom,
1000 rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top);
1001 #endif
1002 dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE);
1003 dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE);
1004 #ifdef CYGMULTIWINDOW_DEBUG
1005 winDebug("\tWindowStyle: %08x %08x\n", dwStyle, dwExStyle);
1006 #endif
1007 AdjustWindowRectEx (&rcDraw, dwStyle, FALSE, dwExStyle);
1009 /* The source of adjust */
1010 GetWindowRect (hwnd, &rcWin);
1011 #ifdef CYGMULTIWINDOW_DEBUG
1012 winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
1013 rcWin.left, rcWin.top, rcWin.right, rcWin.bottom,
1014 rcWin.right - rcWin.left, rcWin.bottom - rcWin.top);
1015 winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n",
1016 rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom,
1017 rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top);
1018 #endif
1020 if (EqualRect (&rcDraw, &rcWin)) {
1021 /* Bail if no adjust is needed */
1022 #if CYGWINDOWING_DEBUG
1023 ErrorF ("\treturn because already adjusted\n");
1024 #endif
1025 return 0;
1028 /* Calculate delta values */
1029 dX = rcWin.left - rcDraw.left;
1030 dY = rcWin.top - rcDraw.top;
1031 dW = WIDTH(rcWin) - WIDTH(rcDraw);
1032 dH = HEIGHT(rcWin) - HEIGHT(rcDraw);
1035 * Adjust.
1036 * We may only need to move (vlist[0] and [1]), or only resize
1037 * ([2] and [3]) but currently we set all the parameters and leave
1038 * the decision to ConfigureWindow. The reason is code simplicity.
1040 vlist[0] = pDraw->x + dX - wBorderWidth(pWin);
1041 vlist[1] = pDraw->y + dY - wBorderWidth(pWin);
1042 vlist[2] = pDraw->width + dW;
1043 vlist[3] = pDraw->height + dH;
1044 #if CYGWINDOWING_DEBUG
1045 ErrorF ("\tConfigureWindow to (%ld, %ld) - %ldx%ld\n", vlist[0], vlist[1],
1046 vlist[2], vlist[3]);
1047 #endif
1048 return ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight,
1049 vlist, wClient(pWin));
1051 #undef WIDTH
1052 #undef HEIGHT