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
32 #ifdef HAVE_XWIN_CONFIG_H
33 #include <xwin-config.h>
37 #define _WINDOWSWM_SERVER_
38 #include "windowswmstr.h"
39 #include "dixevents.h"
40 #include "propertyst.h"
41 #include <X11/Xatom.h>
42 #include "winmultiwindowclass.h"
51 #define MOUSE_POLLING_INTERVAL 500
52 #define MOUSE_ACTIVATE_DEFAULT TRUE
53 #define RAISE_ON_CLICK_DEFAULT FALSE
60 extern Bool g_fNoConfigureWindow
;
61 extern Bool g_fSoftwareCursor
;
68 static UINT_PTR g_uipMousePollingTimerID
= 0;
75 DEFINE_ATOM_HELPER(AtmWindowsWmRaiseOnClick
, WINDOWSWM_RAISE_ON_CLICK
)
76 DEFINE_ATOM_HELPER(AtmWindowsWMMouseActivate
, WINDOWSWM_MOUSE_ACTIVATE
)
77 /* DEFINE_ATOM_HELPER(AtmWindowsWMClientWindow, WINDOWSWM_CLIENT_WINDOW) */
80 * ConstrainSize - Taken from TWM sources - Respects hints for sizing
82 #define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) )
84 ConstrainSize (WinXSizeHints hints
, int *widthp
, int *heightp
)
86 int minWidth
, minHeight
, maxWidth
, maxHeight
, xinc
, yinc
, delta
;
87 int baseWidth
, baseHeight
;
88 int dwidth
= *widthp
, dheight
= *heightp
;
90 if (hints
.flags
& PMinSize
)
92 minWidth
= hints
.min_width
;
93 minHeight
= hints
.min_height
;
95 else if (hints
.flags
& PBaseSize
)
97 minWidth
= hints
.base_width
;
98 minHeight
= hints
.base_height
;
101 minWidth
= minHeight
= 1;
103 if (hints
.flags
& PBaseSize
)
105 baseWidth
= hints
.base_width
;
106 baseHeight
= hints
.base_height
;
108 else if (hints
.flags
& PMinSize
)
110 baseWidth
= hints
.min_width
;
111 baseHeight
= hints
.min_height
;
114 baseWidth
= baseHeight
= 0;
116 if (hints
.flags
& PMaxSize
)
118 maxWidth
= hints
.max_width
;
119 maxHeight
= hints
.max_height
;
127 if (hints
.flags
& PResizeInc
)
129 xinc
= hints
.width_inc
;
130 yinc
= hints
.height_inc
;
136 * First, clamp to min and max values
138 if (dwidth
< minWidth
)
140 if (dheight
< minHeight
)
143 if (dwidth
> maxWidth
)
145 if (dheight
> maxHeight
)
149 * Second, fit to base + N * inc
151 dwidth
= ((dwidth
- baseWidth
) / xinc
* xinc
) + baseWidth
;
152 dheight
= ((dheight
- baseHeight
) / yinc
* yinc
) + baseHeight
;
155 * Third, adjust for aspect ratio
159 * The math looks like this:
161 * minAspectX dwidth maxAspectX
162 * ---------- <= ------- <= ----------
163 * minAspectY dheight maxAspectY
165 * If that is multiplied out, then the width and height are
166 * invalid in the following situations:
168 * minAspectX * dheight > minAspectY * dwidth
169 * maxAspectX * dheight < maxAspectY * dwidth
173 if (hints
.flags
& PAspect
)
175 if (hints
.min_aspect
.x
* dheight
> hints
.min_aspect
.y
* dwidth
)
177 delta
= makemult(hints
.min_aspect
.x
* dheight
/ hints
.min_aspect
.y
- dwidth
, xinc
);
178 if (dwidth
+ delta
<= maxWidth
)
182 delta
= makemult(dheight
- dwidth
*hints
.min_aspect
.y
/hints
.min_aspect
.x
, yinc
);
183 if (dheight
- delta
>= minHeight
)
188 if (hints
.max_aspect
.x
* dheight
< hints
.max_aspect
.y
* dwidth
)
190 delta
= makemult(dwidth
* hints
.max_aspect
.y
/ hints
.max_aspect
.x
- dheight
, yinc
);
191 if (dheight
+ delta
<= maxHeight
)
195 delta
= makemult(dwidth
- hints
.max_aspect
.x
*dheight
/hints
.max_aspect
.y
, xinc
);
196 if (dwidth
- delta
>= minWidth
)
202 /* Return computed values */
211 * ValidateSizing - Ensures size request respects hints
214 ValidateSizing (HWND hwnd
, WindowPtr pWin
,
215 WPARAM wParam
, LPARAM lParam
)
217 WinXSizeHints sizeHints
;
219 int iWidth
, iHeight
, iTopBorder
;
222 /* Invalid input checking */
223 if (pWin
==NULL
|| lParam
==0)
225 ErrorF ("Invalid input checking\n");
229 /* No size hints, no checking */
230 if (!winMultiWindowGetWMNormalHints (pWin
, &sizeHints
))
232 ErrorF ("No size hints, no checking\n");
236 /* Avoid divide-by-zero */
237 if (sizeHints
.flags
& PResizeInc
)
239 if (sizeHints
.width_inc
== 0) sizeHints
.width_inc
= 1;
240 if (sizeHints
.height_inc
== 0) sizeHints
.height_inc
= 1;
243 rect
= (RECT
*)lParam
;
245 iWidth
= rect
->right
- rect
->left
;
246 iHeight
= rect
->bottom
- rect
->top
;
248 /* Get title bar height, there must be an easier way?! */
250 ClientToScreen(hwnd
, &pt
);
251 iTopBorder
= pt
.y
- rect
->top
;
253 /* Now remove size of any borders */
254 iWidth
-= 2 * GetSystemMetrics(SM_CXSIZEFRAME
);
255 iHeight
-= GetSystemMetrics(SM_CYSIZEFRAME
) + iTopBorder
;
257 /* Constrain the size to legal values */
258 ConstrainSize (sizeHints
, &iWidth
, &iHeight
);
260 /* Add back the borders */
261 iWidth
+= 2 * GetSystemMetrics(SM_CXSIZEFRAME
);
262 iHeight
+= GetSystemMetrics(SM_CYSIZEFRAME
) + iTopBorder
;
264 /* Adjust size according to where we're dragging from */
269 case WMSZ_BOTTOMRIGHT
:
271 rect
->right
= rect
->left
+ iWidth
;
274 rect
->left
= rect
->right
- iWidth
;
279 case WMSZ_BOTTOMRIGHT
:
280 case WMSZ_BOTTOMLEFT
:
283 rect
->bottom
= rect
->top
+ iHeight
;
286 rect
->top
= rect
->bottom
- iHeight
;
298 IsRaiseOnClick (WindowPtr pWin
)
301 struct _Window
*pwin
;
302 struct _Property
*prop
;
303 WindowPtr pRoot
= GetCurrentRootWindow ();
307 ErrorF ("IsRaiseOnClick - no prop use default value:%d\n",
308 RAISE_ON_CLICK_DEFAULT
);
309 return RAISE_ON_CLICK_DEFAULT
;
312 pwin
= (struct _Window
*) pWin
;
315 prop
= (struct _Property
*) pwin
->optional
->userProps
;
321 if (prop
->propertyName
== AtmWindowsWmRaiseOnClick ()
322 && prop
->type
== XA_INTEGER
323 && prop
->format
== 32)
325 return *(int*)prop
->data
;
333 return IsRaiseOnClick (pRoot
);
337 #if CYGMULTIWINDOW_DEBUG
338 winDebug ("IsRaiseOnClick - no prop use default value:%d\n",
339 RAISE_ON_CLICK_DEFAULT
);
341 return RAISE_ON_CLICK_DEFAULT
;
351 IsMouseActive (WindowPtr pWin
)
354 struct _Window
*pwin
;
355 struct _Property
*prop
;
356 WindowPtr pRoot
= GetCurrentRootWindow ();
360 ErrorF ("IsMouseActive - pWin was NULL use default value:%d\n",
361 MOUSE_ACTIVATE_DEFAULT
);
362 return MOUSE_ACTIVATE_DEFAULT
;
365 pwin
= (struct _Window
*) pWin
;
368 prop
= (struct _Property
*) pwin
->optional
->userProps
;
374 if (prop
->propertyName
== AtmWindowsWMMouseActivate ()
375 && prop
->type
== XA_INTEGER
376 && prop
->format
== 32)
378 return *(int*)prop
->data
;
386 return IsMouseActive (pRoot
);
390 #if CYGMULTIWINDOW_DEBUG
391 winDebug ("IsMouseActive - no prop use default value:%d\n",
392 MOUSE_ACTIVATE_DEFAULT
);
394 return MOUSE_ACTIVATE_DEFAULT
;
400 * winMWExtWMWindowProc - Window procedure
404 winMWExtWMWindowProc (HWND hwnd
, UINT message
,
405 WPARAM wParam
, LPARAM lParam
)
407 WindowPtr pWin
= NULL
;
408 win32RootlessWindowPtr pRLWinPriv
= NULL
;
409 ScreenPtr pScreen
= NULL
;
410 winPrivScreenPtr pScreenPriv
= NULL
;
411 winScreenInfo
*pScreenInfo
= NULL
;
412 HWND hwndScreen
= NULL
;
414 static Bool s_fTracking
= FALSE
;
417 LPWINDOWPOS pWinPos
= NULL
;
419 winWMMessageRec wmMsg
;
420 Bool fWMMsgInitialized
= FALSE
;
422 /* Check if the Windows window property for our X window pointer is valid */
423 if ((pRLWinPriv
= (win32RootlessWindowPtr
)GetProp (hwnd
, WIN_WINDOW_PROP
)) != NULL
)
425 pWin
= pRLWinPriv
->pFrame
->win
;
426 pScreen
= pWin
->drawable
.pScreen
;
427 if (pScreen
) pScreenPriv
= winGetScreenPriv(pScreen
);
428 if (pScreenPriv
) pScreenInfo
= pScreenPriv
->pScreenInfo
;
429 if (pScreenPriv
) hwndScreen
= pScreenPriv
->hwndScreen
;
432 wmMsg
.hwndWindow
= hwnd
;
433 wmMsg
.iWindow
= (Window
)pWin
->drawable
.id
;
435 wmMsg
.iX
= pRLWinPriv
->pFrame
->x
;
436 wmMsg
.iY
= pRLWinPriv
->pFrame
->y
;
437 wmMsg
.iWidth
= pRLWinPriv
->pFrame
->width
;
438 wmMsg
.iHeight
= pRLWinPriv
->pFrame
->height
;
440 fWMMsgInitialized
= TRUE
;
442 winDebugWin32Message("winMWExtWMWindowProc", hwnd
, message
, wParam
, lParam
);
444 winDebug ("\thWnd %08X\n", hwnd
);
445 winDebug ("\tpScreenPriv %08X\n", pScreenPriv
);
446 winDebug ("\tpScreenInfo %08X\n", pScreenInfo
);
447 winDebug ("\thwndScreen %08X\n", hwndScreen
);
448 winDebug ("winMWExtWMWindowProc (%08x) %08x %08x %08x\n",
449 pRLWinPriv
, message
, wParam
, lParam
);
452 /* Branch on message type */
456 #if CYGMULTIWINDOW_DEBUG
457 winDebug ("winMWExtWMWindowProc - WM_CREATE\n");
462 (HANDLE
)((LPCREATESTRUCT
) lParam
)->lpCreateParams
);
466 #if CYGMULTIWINDOW_DEBUG
467 winDebug ("winMWExtWMWindowProc - WM_CLOSE %d\n", pRLWinPriv
->fClose
);
469 /* Tell window-manager to close window */
470 if (pRLWinPriv
->fClose
)
472 DestroyWindow (hwnd
);
476 if (winIsInternalWMRunning(pScreenInfo
))
478 /* Tell our Window Manager thread to kill the window */
479 wmMsg
.msg
= WM_WM_KILL
;
480 if (fWMMsgInitialized
)
481 winSendMessageToWM (pScreenPriv
->pWMInfo
, &wmMsg
);
483 winWindowsWMSendEvent(WindowsWMControllerNotify
,
484 WindowsWMControllerNotifyMask
,
486 WindowsWMCloseWindow
,
493 #if CYGMULTIWINDOW_DEBUG
494 winDebug ("winMWExtWMWindowProc - WM_DESTROY\n");
496 /* Free the shaodw DC; which allows the bitmap to be freed */
497 DeleteDC (pRLWinPriv
->hdcShadow
);
498 pRLWinPriv
->hdcShadow
= NULL
;
500 /* Free the shadow bitmap */
501 DeleteObject (pRLWinPriv
->hbmpShadow
);
502 pRLWinPriv
->hbmpShadow
= NULL
;
504 /* Free the screen DC */
505 ReleaseDC (pRLWinPriv
->hWnd
, pRLWinPriv
->hdcScreen
);
506 pRLWinPriv
->hdcScreen
= NULL
;
508 /* Free shadow buffer info header */
509 free (pRLWinPriv
->pbmihShadow
);
510 pRLWinPriv
->pbmihShadow
= NULL
;
512 pRLWinPriv
->fResized
= FALSE
;
513 pRLWinPriv
->pfb
= NULL
;
515 RemoveProp (hwnd
, WIN_WINDOW_PROP
);
519 #if CYGMULTIWINDOW_DEBUG && 0
520 winDebug ("winMWExtWMWindowProc - WM_MOUSEMOVE\n");
522 /* Unpack the client area mouse coordinates */
523 ptMouse
.x
= GET_X_LPARAM(lParam
);
524 ptMouse
.y
= GET_Y_LPARAM(lParam
);
526 /* Translate the client area mouse coordinates to screen coordinates */
527 ClientToScreen (hwnd
, &ptMouse
);
529 /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */
530 ptMouse
.x
-= GetSystemMetrics (SM_XVIRTUALSCREEN
);
531 ptMouse
.y
-= GetSystemMetrics (SM_YVIRTUALSCREEN
);
533 /* We can't do anything without privates */
534 if (pScreenPriv
== NULL
|| pScreenInfo
->fIgnoreInput
)
537 /* Has the mouse pointer crossed screens? */
538 if (pScreen
!= miPointerGetScreen(inputInfo
.pointer
))
539 miPointerSetScreen (inputInfo
.pointer
, pScreenInfo
->dwScreen
,
540 ptMouse
.x
- pScreenInfo
->dwXOffset
,
541 ptMouse
.y
- pScreenInfo
->dwYOffset
);
543 /* Are we tracking yet? */
548 /* Setup data structure */
549 ZeroMemory (&tme
, sizeof (tme
));
550 tme
.cbSize
= sizeof (tme
);
551 tme
.dwFlags
= TME_LEAVE
;
552 tme
.hwndTrack
= hwnd
;
554 /* Call the tracking function */
555 if (!(*g_fpTrackMouseEvent
) (&tme
))
556 ErrorF ("winMWExtWMWindowProc - _TrackMouseEvent failed\n");
558 /* Flag that we are tracking now */
562 /* Kill the timer used to poll mouse events */
563 if (g_uipMousePollingTimerID
!= 0)
565 KillTimer (pScreenPriv
->hwndScreen
, WIN_POLLING_MOUSE_TIMER_ID
);
566 g_uipMousePollingTimerID
= 0;
569 /* Deliver absolute cursor position to X Server */
570 miPointerAbsoluteCursor (ptMouse
.x
- pScreenInfo
->dwXOffset
,
571 ptMouse
.y
- pScreenInfo
->dwYOffset
,
572 g_c32LastInputEventTime
= GetTickCount ());
576 #if CYGMULTIWINDOW_DEBUG && 0
577 winDebug ("winMWExtWMWindowProc - WM_NCMOUSEMOVE\n");
580 * We break instead of returning 0 since we need to call
581 * DefWindowProc to get the mouse cursor changes
582 * and min/max/close button highlighting in Windows XP.
583 * The Platform SDK says that you should return 0 if you
584 * process this message, but it fails to mention that you
585 * will give up any default functionality if you do return 0.
588 /* We can't do anything without privates */
589 if (pScreenPriv
== NULL
|| pScreenInfo
->fIgnoreInput
)
593 * Timer to poll mouse events. This is needed to make
594 * programs like xeyes follow the mouse properly.
596 if (g_uipMousePollingTimerID
== 0)
597 g_uipMousePollingTimerID
= SetTimer (pScreenPriv
->hwndScreen
,
598 WIN_POLLING_MOUSE_TIMER_ID
,
599 MOUSE_POLLING_INTERVAL
,
604 #if CYGMULTIWINDOW_DEBUG
605 winDebug ("winMWExtWMWindowProc - WM_MOUSELEAVE\n");
607 /* Mouse has left our client area */
609 /* Flag that we are no longer tracking */
613 * Timer to poll mouse events. This is needed to make
614 * programs like xeyes follow the mouse properly.
616 if (g_uipMousePollingTimerID
== 0)
617 g_uipMousePollingTimerID
= SetTimer (pScreenPriv
->hwndScreen
,
618 WIN_POLLING_MOUSE_TIMER_ID
,
619 MOUSE_POLLING_INTERVAL
,
623 case WM_LBUTTONDBLCLK
:
625 #if CYGMULTIWINDOW_DEBUG
626 winDebug ("winMWExtWMWindowProc - WM_LBUTTONDBLCLK\n");
628 if (pScreenPriv
== NULL
|| pScreenInfo
->fIgnoreInput
)
631 return winMouseButtonsHandle (pScreen
, ButtonPress
, Button1
, wParam
);
634 #if CYGMULTIWINDOW_DEBUG
635 winDebug ("winMWExtWMWindowProc - WM_LBUTTONUP\n");
637 if (pScreenPriv
== NULL
|| pScreenInfo
->fIgnoreInput
)
640 return winMouseButtonsHandle (pScreen
, ButtonRelease
, Button1
, wParam
);
642 case WM_MBUTTONDBLCLK
:
644 #if CYGMULTIWINDOW_DEBUG
645 winDebug ("winMWExtWMWindowProc - WM_MBUTTONDBLCLK\n");
647 if (pScreenPriv
== NULL
|| pScreenInfo
->fIgnoreInput
)
650 return winMouseButtonsHandle (pScreen
, ButtonPress
, Button2
, wParam
);
653 #if CYGMULTIWINDOW_DEBUG
654 winDebug ("winMWExtWMWindowProc - WM_MBUTTONUP\n");
656 if (pScreenPriv
== NULL
|| pScreenInfo
->fIgnoreInput
)
659 return winMouseButtonsHandle (pScreen
, ButtonRelease
, Button2
, wParam
);
661 case WM_RBUTTONDBLCLK
:
663 #if CYGMULTIWINDOW_DEBUG
664 winDebug ("winMWExtWMWindowProc - WM_RBUTTONDBLCLK\n");
666 if (pScreenPriv
== NULL
|| pScreenInfo
->fIgnoreInput
)
669 return winMouseButtonsHandle (pScreen
, ButtonPress
, Button3
, wParam
);
672 #if CYGMULTIWINDOW_DEBUG
673 winDebug ("winMWExtWMWindowProc - WM_RBUTTONUP\n");
675 if (pScreenPriv
== NULL
|| pScreenInfo
->fIgnoreInput
)
678 return winMouseButtonsHandle (pScreen
, ButtonRelease
, Button3
, wParam
);
680 case WM_XBUTTONDBLCLK
:
682 if (pScreenPriv
== NULL
|| pScreenInfo
->fIgnoreInput
)
685 return winMouseButtonsHandle (pScreen
, ButtonPress
, HIWORD(wParam
) + 5, wParam
);
687 if (pScreenPriv
== NULL
|| pScreenInfo
->fIgnoreInput
)
690 return winMouseButtonsHandle (pScreen
, ButtonRelease
, HIWORD(wParam
) + 5, wParam
);
693 #if CYGMULTIWINDOW_DEBUG
694 winDebug ("winMWExtWMWindowProc - WM_MOUSEWHEEL\n");
697 /* Pass the message to the root window */
698 SendMessage (hwndScreen
, message
, wParam
, lParam
);
701 case WM_MOUSEACTIVATE
:
702 #if CYGMULTIWINDOW_DEBUG
703 winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE\n");
706 /* Check if this window needs to be made active when clicked */
707 if (winIsInternalWMRunning(pScreenInfo
) && pWin
->overrideRedirect
)
709 #if CYGMULTIWINDOW_DEBUG
710 winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE - "
715 return MA_NOACTIVATE
;
718 if (!winIsInternalWMRunning(pScreenInfo
) && !IsMouseActive (pWin
))
719 return MA_NOACTIVATE
;
724 /* Pop any pressed keys since we are losing keyboard focus */
725 winKeybdReleaseKeys ();
731 * NOTE: We do nothing with WM_*CHAR messages,
732 * nor does the root window, so we can just toss these messages.
738 #if CYGMULTIWINDOW_DEBUG
739 winDebug ("winMWExtWMWindowProc - WM_*KEYDOWN\n");
743 * Don't pass Alt-F4 key combo to root window,
744 * let Windows translate to WM_CLOSE and close this top-level window.
746 * NOTE: We purposely don't check the fUseWinKillKey setting because
747 * it should only apply to the key handling for the root window,
748 * not for top-level window-manager windows.
750 * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window
751 * because that is a key combo that no X app should be expecting to
752 * receive, since it has historically been used to shutdown the X server.
753 * Passing Ctrl-Alt-Backspace to the root window preserves that
754 * behavior, assuming that -unixkill has been passed as a parameter.
756 if (wParam
== VK_F4
&& (GetKeyState (VK_MENU
) & 0x8000))
759 /* Pass the message to the root window */
760 SendMessage (hwndScreen
, message
, wParam
, lParam
);
766 #if CYGMULTIWINDOW_DEBUG
767 winDebug ("winMWExtWMWindowProc - WM_*KEYUP\n");
770 /* Pass the message to the root window */
771 SendMessage (hwndScreen
, message
, wParam
, lParam
);
775 #if CYGMULTIWINDOW_DEBUG
776 winDebug ("winMWExtWMWindowProc - WM_HOTKEY\n");
779 /* Pass the message to the root window */
780 SendMessage (hwndScreen
, message
, wParam
, lParam
);
785 /* BeginPaint gives us an hdc that clips to the invalidated region */
786 hdcUpdate
= BeginPaint (hwnd
, &ps
);
788 /* Try to copy from the shadow buffer */
789 if (!BitBlt (hdcUpdate
,
790 ps
.rcPaint
.left
, ps
.rcPaint
.top
,
791 ps
.rcPaint
.right
- ps
.rcPaint
.left
,
792 ps
.rcPaint
.bottom
- ps
.rcPaint
.top
,
793 pRLWinPriv
->hdcShadow
,
794 ps
.rcPaint
.left
, ps
.rcPaint
.top
,
799 /* Display a fancy error message */
800 FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
|
801 FORMAT_MESSAGE_FROM_SYSTEM
|
802 FORMAT_MESSAGE_IGNORE_INSERTS
,
805 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
809 ErrorF ("winMWExtWMWindowProc - BitBlt failed: %s\n",
811 LocalFree (lpMsgBuf
);
814 /* EndPaint frees the DC */
815 EndPaint (hwnd
, &ps
);
819 #if CYGMULTIWINDOW_DEBUG
820 winDebug ("winMWExtWMWindowProc - WM_ACTIVATE\n");
822 if (LOWORD(wParam
) != WA_INACTIVE
)
824 if (winIsInternalWMRunning(pScreenInfo
))
827 /* Raise the window to the top in Z order */
828 wmMsg
.msg
= WM_WM_RAISE
;
829 if (fWMMsgInitialized
)
830 winSendMessageToWM (pScreenPriv
->pWMInfo
, &wmMsg
);
832 /* Tell our Window Manager thread to activate the window */
833 wmMsg
.msg
= WM_WM_ACTIVATE
;
834 if (fWMMsgInitialized
)
835 if (!pWin
|| !pWin
->overrideRedirect
) /* for OOo menus */
836 winSendMessageToWM (pScreenPriv
->pWMInfo
, &wmMsg
);
838 winWindowsWMSendEvent(WindowsWMControllerNotify
,
839 WindowsWMControllerNotifyMask
,
841 WindowsWMActivateWindow
,
849 case WM_WINDOWPOSCHANGING
:
850 pWinPos
= (LPWINDOWPOS
)lParam
;
851 if (!(pWinPos
->flags
& SWP_NOZORDER
))
853 if (pRLWinPriv
->fRestackingNow
|| pScreenPriv
->fRestacking
)
855 #if CYGMULTIWINDOW_DEBUG
856 winDebug ("Win %08x is now restacking.\n", (unsigned int)pRLWinPriv
);
861 if (winIsInternalWMRunning(pScreenInfo
) || IsRaiseOnClick (pWin
))
863 #if CYGMULTIWINDOW_DEBUG
864 winDebug ("Win %08x has WINDOWSWM_RAISE_ON_CLICK.\n", (unsigned int)pRLWinPriv
);
869 #if CYGMULTIWINDOW_DEBUG
870 winDebug ("Win %08x forbid to change z order (%08x).\n",
871 (unsigned int)pRLWinPriv
, (unsigned int)pWinPos
->hwndInsertAfter
);
873 pWinPos
->flags
|= SWP_NOZORDER
;
879 #if CYGMULTIWINDOW_DEBUG
880 winDebug ("winMWExtWMWindowProc - WM_MOVE - %d ms\n",
881 (unsigned int)GetTickCount ());
883 if (g_fNoConfigureWindow
) break;
885 /* Bail if Windows window is not actually moving */
886 if (pRLWinPriv
->dwX
== (short) LOWORD(lParam
)
887 && pRLWinPriv
->dwY
== (short) HIWORD(lParam
))
890 /* Also bail if we're maximizing, we'll do the whole thing in WM_SIZE */
892 WINDOWPLACEMENT windPlace
;
893 windPlace
.length
= sizeof (WINDOWPLACEMENT
);
895 /* Get current window placement */
896 GetWindowPlacement (hwnd
, &windPlace
);
898 /* Bail if maximizing */
899 if (windPlace
.showCmd
== SW_MAXIMIZE
900 || windPlace
.showCmd
== SW_SHOWMAXIMIZED
)
905 #if CYGMULTIWINDOW_DEBUG
906 winDebug ("\t(%d, %d)\n", (short) LOWORD(lParam
), (short) HIWORD(lParam
));
908 if (!pRLWinPriv
->fMovingOrSizing
)
910 if (winIsInternalWMRunning(pScreenInfo
))
911 winAdjustXWindow (pWin
, hwnd
);
913 winMWExtWMMoveXWindow (pWin
,
914 (LOWORD(lParam
) - wBorderWidth (pWin
)
915 - GetSystemMetrics (SM_XVIRTUALSCREEN
)),
916 (HIWORD(lParam
) - wBorderWidth (pWin
)
917 - GetSystemMetrics (SM_YVIRTUALSCREEN
)));
922 #if CYGMULTIWINDOW_DEBUG || TRUE
923 winDebug ("winMWExtWMWindowProc - WM_SHOWWINDOW - %d ms\n",
924 (unsigned int)GetTickCount ());
926 /* Bail out if the window is being hidden */
930 if (!pScreenInfo
->fInternalWM
)//XXXX
933 winMWExtWMUpdateWindowDecoration (pRLWinPriv
, pScreenInfo
);
935 if (winIsInternalWMRunning(pScreenInfo
))
937 #if CYGMULTIWINDOW_DEBUG || TRUE
938 winDebug ("\tMapWindow\n");
940 /* Tell X to map the window */
941 MapWindow (pWin
, wClient(pWin
));
943 if (!pRLWinPriv
->pFrame
->win
->overrideRedirect
)
944 /* Bring the Windows window to the foreground */
945 SetForegroundWindow (hwnd
);
947 /* Setup the Window Manager message */
948 wmMsg
.msg
= WM_WM_MAP
;
949 wmMsg
.iWidth
= pRLWinPriv
->pFrame
->width
;
950 wmMsg
.iHeight
= pRLWinPriv
->pFrame
->height
;
952 /* Tell our Window Manager thread to map the window */
953 if (fWMMsgInitialized
)
954 winSendMessageToWM (pScreenPriv
->pWMInfo
, &wmMsg
);
959 /* Need to legalize the size according to WM_NORMAL_HINTS */
960 /* for applications like xterm */
961 return ValidateSizing (hwnd
, pWin
, wParam
, lParam
);
963 case WM_WINDOWPOSCHANGED
:
965 pWinPos
= (LPWINDOWPOS
) lParam
;
966 #if CYGMULTIWINDOW_DEBUG
967 winDebug("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED\n");
968 winDebug("\tflags: %s%s%s%s%s%s%s%s%s%s%s%s\n",
969 (pWinPos
->flags
& SWP_DRAWFRAME
)?"SWP_DRAWFRAME ":"",
970 (pWinPos
->flags
& SWP_FRAMECHANGED
)?"SWP_FRAMECHANGED ":"",
971 (pWinPos
->flags
& SWP_HIDEWINDOW
)?"SWP_HIDEWINDOW ":"",
972 (pWinPos
->flags
& SWP_NOACTIVATE
)?"SWP_NOACTIVATE ":"",
973 (pWinPos
->flags
& SWP_NOCOPYBITS
)?"SWP_NOCOPYBITS ":"",
974 (pWinPos
->flags
& SWP_NOMOVE
)?"SWP_NOMOVE ":"",
975 (pWinPos
->flags
& SWP_NOOWNERZORDER
)?"SWP_NOOWNERZORDER ":"",
976 (pWinPos
->flags
& SWP_NOSIZE
)?"SWP_NOSIZE ":"",
977 (pWinPos
->flags
& SWP_NOREDRAW
)?"SWP_NOREDRAW ":"",
978 (pWinPos
->flags
& SWP_NOSENDCHANGING
)?"SWP_NOSENDCHANGING ":"",
979 (pWinPos
->flags
& SWP_NOZORDER
)?"SWP_NOZORDER ":"",
980 (pWinPos
->flags
& SWP_SHOWWINDOW
)?"SWP_SHOWWINDOW ":"");
981 winDebug("\tno_configure: %s\n", (g_fNoConfigureWindow
?"Yes":"No"));
982 winDebug("\textend: (%d, %d, %d, %d)\n",
983 pWinPos
->x
, pWinPos
->y
, pWinPos
->cx
, pWinPos
->cy
);
986 if (pWinPos
->flags
& SWP_HIDEWINDOW
) break;
988 /* Reorder if window z order was changed */
989 if ((pScreenPriv
!= NULL
)
990 && !(pWinPos
->flags
& SWP_NOZORDER
)
991 && !(pWinPos
->flags
& SWP_SHOWWINDOW
)
992 && winIsInternalWMRunning(pScreenInfo
))
994 #if CYGMULTIWINDOW_DEBUG
995 winDebug ("\twindow z order was changed\n");
997 if (pWinPos
->hwndInsertAfter
== HWND_TOP
998 ||pWinPos
->hwndInsertAfter
== HWND_TOPMOST
999 ||pWinPos
->hwndInsertAfter
== HWND_NOTOPMOST
)
1001 #if CYGMULTIWINDOW_DEBUG
1002 winDebug ("\traise to top\n");
1004 /* Raise the window to the top in Z order */
1005 wmMsg
.msg
= WM_WM_RAISE
;
1006 if (fWMMsgInitialized
)
1007 winSendMessageToWM (pScreenPriv
->pWMInfo
, &wmMsg
);
1010 else if (pWinPos
->hwndInsertAfter
== HWND_BOTTOM
)
1015 /* Check if this window is top of X windows. */
1016 HWND hWndAbove
= NULL
;
1017 DWORD dwCurrentProcessID
= GetCurrentProcessId ();
1018 DWORD dwWindowProcessID
= 0;
1020 for (hWndAbove
= pWinPos
->hwndInsertAfter
;
1022 hWndAbove
= GetNextWindow (hWndAbove
, GW_HWNDPREV
))
1024 /* Ignore other XWin process's window */
1025 GetWindowThreadProcessId (hWndAbove
, &dwWindowProcessID
);
1027 if ((dwWindowProcessID
== dwCurrentProcessID
)
1028 && GetProp (hWndAbove
, WIN_WINDOW_PROP
)
1029 && !IsWindowVisible (hWndAbove
)
1030 && !IsIconic (hWndAbove
) ) /* ignore minimized windows */
1033 /* If this is top of X windows in Windows stack,
1034 raise it in X stack. */
1035 if (hWndAbove
== NULL
)
1037 #if CYGMULTIWINDOW_DEBUG
1038 winDebug ("\traise to top\n");
1040 /* Raise the window to the top in Z order */
1041 wmMsg
.msg
= WM_WM_RAISE
;
1042 if (fWMMsgInitialized
)
1043 winSendMessageToWM (pScreenPriv
->pWMInfo
, &wmMsg
);
1049 if (!(pWinPos
->flags
& SWP_NOSIZE
)) {
1050 if (IsIconic(hwnd
)){
1051 #if CYGMULTIWINDOW_DEBUG
1052 winDebug ("\tIconic -> MINIMIZED\n");
1054 if (winIsInternalWMRunning(pScreenInfo
))
1056 /* Raise the window to the top in Z order */
1057 wmMsg
.msg
= WM_WM_LOWER
;
1058 if (fWMMsgInitialized
)
1059 winSendMessageToWM (pScreenPriv
->pWMInfo
, &wmMsg
);
1061 winWindowsWMSendEvent(WindowsWMControllerNotify
,
1062 WindowsWMControllerNotifyMask
,
1064 WindowsWMMinimizeWindow
,
1067 } else if (IsZoomed(hwnd
)){
1068 #if CYGMULTIWINDOW_DEBUG
1069 winDebug ("\tZoomed -> MAXIMIZED\n");
1071 winWindowsWMSendEvent(WindowsWMControllerNotify
,
1072 WindowsWMControllerNotifyMask
,
1074 WindowsWMMaximizeWindow
,
1078 #if CYGMULTIWINDOW_DEBUG
1079 winDebug ("\tnone -> RESTORED\n");
1081 winWindowsWMSendEvent(WindowsWMControllerNotify
,
1082 WindowsWMControllerNotifyMask
,
1084 WindowsWMRestoreWindow
,
1089 if (!g_fNoConfigureWindow
) {
1091 if (!pRLWinPriv
->fMovingOrSizing
1092 /*&& (pWinPos->flags & SWP_SHOWWINDOW)*/) {
1093 GetClientRect (hwnd
, &rcClient
);
1094 MapWindowPoints (hwnd
, HWND_DESKTOP
, (LPPOINT
)&rcClient
, 2);
1096 if (!(pWinPos
->flags
& SWP_NOMOVE
)
1097 &&!(pWinPos
->flags
& SWP_NOSIZE
)) {
1098 #if CYGMULTIWINDOW_DEBUG
1099 winDebug ("\tmove & resize\n");
1101 if (winIsInternalWMRunning(pScreenInfo
))
1102 winAdjustXWindow (pWin
, hwnd
);
1104 winMWExtWMMoveResizeXWindow (pWin
,
1105 rcClient
.left
- wBorderWidth (pWin
)
1106 - GetSystemMetrics (SM_XVIRTUALSCREEN
),
1107 rcClient
.top
- wBorderWidth (pWin
)
1108 - GetSystemMetrics (SM_YVIRTUALSCREEN
),
1109 rcClient
.right
- rcClient
.left
1110 - wBorderWidth (pWin
)*2,
1111 rcClient
.bottom
- rcClient
.top
1112 - wBorderWidth (pWin
)*2);
1113 } else if (!(pWinPos
->flags
& SWP_NOMOVE
)) {
1114 #if CYGMULTIWINDOW_DEBUG
1115 winDebug ("\tmove\n");
1117 if (winIsInternalWMRunning(pScreenInfo
))
1118 winAdjustXWindow (pWin
, hwnd
);
1120 winMWExtWMMoveResizeXWindow (pWin
,
1121 rcClient
.left
- wBorderWidth (pWin
)
1122 - GetSystemMetrics (SM_XVIRTUALSCREEN
),
1123 rcClient
.top
- wBorderWidth (pWin
)
1124 - GetSystemMetrics (SM_YVIRTUALSCREEN
),
1125 rcClient
.right
- rcClient
.left
1126 - wBorderWidth (pWin
)*2,
1127 rcClient
.bottom
- rcClient
.top
1128 - wBorderWidth (pWin
)*2);
1129 } else if (!(pWinPos
->flags
& SWP_NOMOVE
)) {
1130 #if CYGMULTIWINDOW_DEBUG
1131 winDebug ("\tmove\n");
1133 if (winIsInternalWMRunning(pScreenInfo
))
1134 winAdjustXWindow (pWin
, hwnd
);
1136 winMWExtWMMoveXWindow (pWin
,
1137 rcClient
.left
- wBorderWidth (pWin
)
1138 - GetSystemMetrics (SM_XVIRTUALSCREEN
),
1139 rcClient
.top
- wBorderWidth (pWin
)
1140 - GetSystemMetrics (SM_YVIRTUALSCREEN
));
1141 } else if (!(pWinPos
->flags
& SWP_NOSIZE
)) {
1142 #if CYGMULTIWINDOW_DEBUG
1143 winDebug ("\tresize\n");
1145 if (winIsInternalWMRunning(pScreenInfo
))
1146 winAdjustXWindow (pWin
, hwnd
);
1148 winMWExtWMResizeXWindow (pWin
,
1149 rcClient
.right
- rcClient
.left
1150 - wBorderWidth (pWin
)*2,
1151 rcClient
.bottom
- rcClient
.top
1152 - wBorderWidth (pWin
)*2);
1157 #if CYGMULTIWINDOW_DEBUG
1158 winDebug ("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED - done.\n");
1163 /* see dix/window.c */
1164 /* FIXME: Maximize/Restore? */
1165 #if CYGMULTIWINDOW_DEBUG
1166 winDebug ("winMWExtWMWindowProc - WM_SIZE - %d ms\n",
1167 (unsigned int)GetTickCount ());
1169 #if CYGMULTIWINDOW_DEBUG
1170 winDebug ("\t(%d, %d) %d\n", (short) LOWORD(lParam
), (short) HIWORD(lParam
), g_fNoConfigureWindow
);
1172 if (g_fNoConfigureWindow
) break;
1174 /* Branch on type of resizing occurring */
1177 case SIZE_MINIMIZED
:
1178 #if CYGMULTIWINDOW_DEBUG
1179 winDebug ("\tSIZE_MINIMIZED\n");
1181 if (winIsInternalWMRunning(pScreenInfo
))
1183 /* Raise the window to the top in Z order */
1184 wmMsg
.msg
= WM_WM_LOWER
;
1185 if (fWMMsgInitialized
)
1186 winSendMessageToWM (pScreenPriv
->pWMInfo
, &wmMsg
);
1188 winWindowsWMSendEvent(WindowsWMControllerNotify
,
1189 WindowsWMControllerNotifyMask
,
1191 WindowsWMMinimizeWindow
,
1194 LOWORD(lParam
), HIWORD(lParam
));
1198 #if CYGMULTIWINDOW_DEBUG
1199 winDebug ("\tSIZE_RESTORED\n");
1201 winWindowsWMSendEvent(WindowsWMControllerNotify
,
1202 WindowsWMControllerNotifyMask
,
1204 WindowsWMRestoreWindow
,
1207 LOWORD(lParam
), HIWORD(lParam
));
1210 case SIZE_MAXIMIZED
:
1211 #if CYGMULTIWINDOW_DEBUG
1212 winDebug ("\tSIZE_MAXIMIZED\n");
1214 winWindowsWMSendEvent(WindowsWMControllerNotify
,
1215 WindowsWMControllerNotifyMask
,
1217 WindowsWMMaximizeWindow
,
1220 LOWORD(lParam
), HIWORD(lParam
));
1224 /* Perform the resize and notify the X client */
1225 if (!pRLWinPriv
->fMovingOrSizing
)
1227 if (winIsInternalWMRunning(pScreenInfo
))
1228 winAdjustXWindow (pWin
, hwnd
);
1230 winMWExtWMResizeXWindow (pWin
,
1231 (short) LOWORD(lParam
)
1232 - wBorderWidth (pWin
)*2,
1233 (short) HIWORD(lParam
)
1234 - wBorderWidth (pWin
)*2);
1238 case WM_ACTIVATEAPP
:
1239 #if CYGMULTIWINDOW_DEBUG
1240 winDebug ("winMWExtWMWindowProc - WM_ACTIVATEAPP - %d ms\n",
1241 (unsigned int)GetTickCount ());
1245 if (winIsInternalWMRunning(pScreenInfo
))
1251 winWindowsWMSendEvent(WindowsWMActivationNotify
,
1252 WindowsWMActivationNotifyMask
,
1261 winWindowsWMSendEvent(WindowsWMActivationNotify
,
1262 WindowsWMActivationNotifyMask
,
1264 WindowsWMIsInactive
,
1272 if (LOWORD(lParam
) == HTCLIENT
)
1274 if (!g_fSoftwareCursor
) SetCursor (pScreenPriv
->cursor
.handle
);
1279 case WM_ENTERSIZEMOVE
:
1280 #if CYGMULTIWINDOW_DEBUG
1281 winDebug ("winMWExtWMWindowProc - WM_ENTERSIZEMOVE - %d ms\n",
1282 (unsigned int)GetTickCount ());
1284 pRLWinPriv
->fMovingOrSizing
= TRUE
;
1287 case WM_EXITSIZEMOVE
:
1288 #if CYGMULTIWINDOW_DEBUG
1289 winDebug ("winMWExtWMWindowProc - WM_EXITSIZEMOVE - %d ms\n",
1290 (unsigned int)GetTickCount ());
1292 pRLWinPriv
->fMovingOrSizing
= FALSE
;
1294 GetClientRect (hwnd
, &rcClient
);
1296 MapWindowPoints (hwnd
, HWND_DESKTOP
, (LPPOINT
)&rcClient
, 2);
1298 if (winIsInternalWMRunning(pScreenInfo
))
1299 winAdjustXWindow (pWin
, hwnd
);
1301 winMWExtWMMoveResizeXWindow (pWin
,
1302 rcClient
.left
- wBorderWidth (pWin
)
1303 - GetSystemMetrics (SM_XVIRTUALSCREEN
),
1304 rcClient
.top
- wBorderWidth (pWin
)
1305 - GetSystemMetrics (SM_YVIRTUALSCREEN
),
1306 rcClient
.right
- rcClient
.left
1307 - wBorderWidth (pWin
)*2,
1308 rcClient
.bottom
- rcClient
.top
1309 - wBorderWidth (pWin
)*2);
1313 ErrorF ("winMWExtWMWindowProc - WM_MANAGE\n");
1317 ErrorF ("winMWExtWMWindowProc - WM_UNMANAGE\n");
1324 return DefWindowProc (hwnd
, message
, wParam
, lParam
);