1325 lines
35 KiB
C
1325 lines
35 KiB
C
/*
|
|
*Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
|
|
*
|
|
*Permission is hereby granted, free of charge, to any person obtaining
|
|
* a copy of this software and associated documentation files (the
|
|
*"Software"), to deal in the Software without restriction, including
|
|
*without limitation the rights to use, copy, modify, merge, publish,
|
|
*distribute, sublicense, and/or sell copies of the Software, and to
|
|
*permit persons to whom the Software is furnished to do so, subject to
|
|
*the following conditions:
|
|
*
|
|
*The above copyright notice and this permission notice shall be
|
|
*included in all copies or substantial portions of the Software.
|
|
*
|
|
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
*EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
*MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
*NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
|
|
*ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
*CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
*WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
*Except as contained in this notice, the name of the XFree86 Project
|
|
*shall not be used in advertising or otherwise to promote the sale, use
|
|
*or other dealings in this Software without prior written authorization
|
|
*from the XFree86 Project.
|
|
*
|
|
* Authors: Kensuke Matsuzaki
|
|
* Earle F. Philhower, III
|
|
* Harold L Hunt II
|
|
*/
|
|
#ifdef HAVE_XWIN_CONFIG_H
|
|
#include <xwin-config.h>
|
|
#endif
|
|
#include "win.h"
|
|
#include <winuser.h>
|
|
#define _WINDOWSWM_SERVER_
|
|
#include "windowswmstr.h"
|
|
#include "dixevents.h"
|
|
#include "propertyst.h"
|
|
#include <X11/Xatom.h>
|
|
#include "winmultiwindowclass.h"
|
|
#include "winmsg.h"
|
|
|
|
|
|
/*
|
|
* Constant defines
|
|
*/
|
|
|
|
#define MOUSE_POLLING_INTERVAL 500
|
|
#define MOUSE_ACTIVATE_DEFAULT TRUE
|
|
#define RAISE_ON_CLICK_DEFAULT FALSE
|
|
|
|
|
|
/*
|
|
* Global variables
|
|
*/
|
|
|
|
extern Bool g_fNoConfigureWindow;
|
|
extern Bool g_fSoftwareCursor;
|
|
|
|
|
|
/*
|
|
* Local globals
|
|
*/
|
|
|
|
static UINT_PTR g_uipMousePollingTimerID = 0;
|
|
|
|
|
|
/*
|
|
* Local function
|
|
*/
|
|
|
|
DEFINE_ATOM_HELPER(AtmWindowsWmRaiseOnClick, WINDOWSWM_RAISE_ON_CLICK)
|
|
DEFINE_ATOM_HELPER(AtmWindowsWMMouseActivate, WINDOWSWM_MOUSE_ACTIVATE)
|
|
/* DEFINE_ATOM_HELPER(AtmWindowsWMClientWindow, WINDOWSWM_CLIENT_WINDOW) */
|
|
|
|
/*
|
|
* ConstrainSize - Taken from TWM sources - Respects hints for sizing
|
|
*/
|
|
#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) )
|
|
static void
|
|
ConstrainSize (WinXSizeHints hints, int *widthp, int *heightp)
|
|
{
|
|
int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta;
|
|
int baseWidth, baseHeight;
|
|
int dwidth = *widthp, dheight = *heightp;
|
|
|
|
if (hints.flags & PMinSize)
|
|
{
|
|
minWidth = hints.min_width;
|
|
minHeight = hints.min_height;
|
|
}
|
|
else if (hints.flags & PBaseSize)
|
|
{
|
|
minWidth = hints.base_width;
|
|
minHeight = hints.base_height;
|
|
}
|
|
else
|
|
minWidth = minHeight = 1;
|
|
|
|
if (hints.flags & PBaseSize)
|
|
{
|
|
baseWidth = hints.base_width;
|
|
baseHeight = hints.base_height;
|
|
}
|
|
else if (hints.flags & PMinSize)
|
|
{
|
|
baseWidth = hints.min_width;
|
|
baseHeight = hints.min_height;
|
|
}
|
|
else
|
|
baseWidth = baseHeight = 0;
|
|
|
|
if (hints.flags & PMaxSize)
|
|
{
|
|
maxWidth = hints.max_width;
|
|
maxHeight = hints.max_height;
|
|
}
|
|
else
|
|
{
|
|
maxWidth = MAXINT;
|
|
maxHeight = MAXINT;
|
|
}
|
|
|
|
if (hints.flags & PResizeInc)
|
|
{
|
|
xinc = hints.width_inc;
|
|
yinc = hints.height_inc;
|
|
}
|
|
else
|
|
xinc = yinc = 1;
|
|
|
|
/*
|
|
* First, clamp to min and max values
|
|
*/
|
|
if (dwidth < minWidth)
|
|
dwidth = minWidth;
|
|
if (dheight < minHeight)
|
|
dheight = minHeight;
|
|
|
|
if (dwidth > maxWidth)
|
|
dwidth = maxWidth;
|
|
if (dheight > maxHeight)
|
|
dheight = maxHeight;
|
|
|
|
/*
|
|
* Second, fit to base + N * inc
|
|
*/
|
|
dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth;
|
|
dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight;
|
|
|
|
/*
|
|
* Third, adjust for aspect ratio
|
|
*/
|
|
|
|
/*
|
|
* The math looks like this:
|
|
*
|
|
* minAspectX dwidth maxAspectX
|
|
* ---------- <= ------- <= ----------
|
|
* minAspectY dheight maxAspectY
|
|
*
|
|
* If that is multiplied out, then the width and height are
|
|
* invalid in the following situations:
|
|
*
|
|
* minAspectX * dheight > minAspectY * dwidth
|
|
* maxAspectX * dheight < maxAspectY * dwidth
|
|
*
|
|
*/
|
|
|
|
if (hints.flags & PAspect)
|
|
{
|
|
if (hints.min_aspect.x * dheight > hints.min_aspect.y * dwidth)
|
|
{
|
|
delta = makemult(hints.min_aspect.x * dheight / hints.min_aspect.y - dwidth, xinc);
|
|
if (dwidth + delta <= maxWidth)
|
|
dwidth += delta;
|
|
else
|
|
{
|
|
delta = makemult(dheight - dwidth*hints.min_aspect.y/hints.min_aspect.x, yinc);
|
|
if (dheight - delta >= minHeight)
|
|
dheight -= delta;
|
|
}
|
|
}
|
|
|
|
if (hints.max_aspect.x * dheight < hints.max_aspect.y * dwidth)
|
|
{
|
|
delta = makemult(dwidth * hints.max_aspect.y / hints.max_aspect.x - dheight, yinc);
|
|
if (dheight + delta <= maxHeight)
|
|
dheight += delta;
|
|
else
|
|
{
|
|
delta = makemult(dwidth - hints.max_aspect.x*dheight/hints.max_aspect.y, xinc);
|
|
if (dwidth - delta >= minWidth)
|
|
dwidth -= delta;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Return computed values */
|
|
*widthp = dwidth;
|
|
*heightp = dheight;
|
|
}
|
|
#undef makemult
|
|
|
|
|
|
|
|
/*
|
|
* ValidateSizing - Ensures size request respects hints
|
|
*/
|
|
static int
|
|
ValidateSizing (HWND hwnd, WindowPtr pWin,
|
|
WPARAM wParam, LPARAM lParam)
|
|
{
|
|
WinXSizeHints sizeHints;
|
|
RECT *rect;
|
|
int iWidth, iHeight, iTopBorder;
|
|
POINT pt;
|
|
|
|
/* Invalid input checking */
|
|
if (pWin==NULL || lParam==0)
|
|
{
|
|
ErrorF ("Invalid input checking\n");
|
|
return FALSE;
|
|
}
|
|
|
|
/* No size hints, no checking */
|
|
if (!winMultiWindowGetWMNormalHints (pWin, &sizeHints))
|
|
{
|
|
ErrorF ("No size hints, no checking\n");
|
|
return FALSE;
|
|
}
|
|
|
|
/* Avoid divide-by-zero */
|
|
if (sizeHints.flags & PResizeInc)
|
|
{
|
|
if (sizeHints.width_inc == 0) sizeHints.width_inc = 1;
|
|
if (sizeHints.height_inc == 0) sizeHints.height_inc = 1;
|
|
}
|
|
|
|
rect = (RECT*)lParam;
|
|
|
|
iWidth = rect->right - rect->left;
|
|
iHeight = rect->bottom - rect->top;
|
|
|
|
/* Get title bar height, there must be an easier way?! */
|
|
pt.x = pt.y = 0;
|
|
ClientToScreen(hwnd, &pt);
|
|
iTopBorder = pt.y - rect->top;
|
|
|
|
/* Now remove size of any borders */
|
|
iWidth -= 2 * GetSystemMetrics(SM_CXSIZEFRAME);
|
|
iHeight -= GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder;
|
|
|
|
/* Constrain the size to legal values */
|
|
ConstrainSize (sizeHints, &iWidth, &iHeight);
|
|
|
|
/* Add back the borders */
|
|
iWidth += 2 * GetSystemMetrics(SM_CXSIZEFRAME);
|
|
iHeight += GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder;
|
|
|
|
/* Adjust size according to where we're dragging from */
|
|
switch(wParam) {
|
|
case WMSZ_TOP:
|
|
case WMSZ_TOPRIGHT:
|
|
case WMSZ_BOTTOM:
|
|
case WMSZ_BOTTOMRIGHT:
|
|
case WMSZ_RIGHT:
|
|
rect->right = rect->left + iWidth;
|
|
break;
|
|
default:
|
|
rect->left = rect->right - iWidth;
|
|
break;
|
|
}
|
|
switch(wParam) {
|
|
case WMSZ_BOTTOM:
|
|
case WMSZ_BOTTOMRIGHT:
|
|
case WMSZ_BOTTOMLEFT:
|
|
case WMSZ_RIGHT:
|
|
case WMSZ_LEFT:
|
|
rect->bottom = rect->top + iHeight;
|
|
break;
|
|
default:
|
|
rect->top = rect->bottom - iHeight;
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*
|
|
* IsRaiseOnClick
|
|
*/
|
|
|
|
static Bool
|
|
IsRaiseOnClick (WindowPtr pWin)
|
|
{
|
|
|
|
struct _Window *pwin;
|
|
struct _Property *prop;
|
|
WindowPtr pRoot = GetCurrentRootWindow ();
|
|
|
|
if (!pWin)
|
|
{
|
|
ErrorF ("IsRaiseOnClick - no prop use default value:%d\n",
|
|
RAISE_ON_CLICK_DEFAULT);
|
|
return RAISE_ON_CLICK_DEFAULT;
|
|
}
|
|
|
|
pwin = (struct _Window*) pWin;
|
|
|
|
if (pwin->optional)
|
|
prop = (struct _Property *) pwin->optional->userProps;
|
|
else
|
|
prop = NULL;
|
|
|
|
while (prop)
|
|
{
|
|
if (prop->propertyName == AtmWindowsWmRaiseOnClick ()
|
|
&& prop->type == XA_INTEGER
|
|
&& prop->format == 32)
|
|
{
|
|
return *(int*)prop->data;
|
|
}
|
|
else
|
|
prop = prop->next;
|
|
}
|
|
|
|
if (pWin != pRoot)
|
|
{
|
|
return IsRaiseOnClick (pRoot);
|
|
}
|
|
else
|
|
{
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("IsRaiseOnClick - no prop use default value:%d\n",
|
|
RAISE_ON_CLICK_DEFAULT);
|
|
#endif
|
|
return RAISE_ON_CLICK_DEFAULT;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* IsMouseActive
|
|
*/
|
|
|
|
static Bool
|
|
IsMouseActive (WindowPtr pWin)
|
|
{
|
|
|
|
struct _Window *pwin;
|
|
struct _Property *prop;
|
|
WindowPtr pRoot = GetCurrentRootWindow ();
|
|
|
|
if (!pWin)
|
|
{
|
|
ErrorF ("IsMouseActive - pWin was NULL use default value:%d\n",
|
|
MOUSE_ACTIVATE_DEFAULT);
|
|
return MOUSE_ACTIVATE_DEFAULT;
|
|
}
|
|
|
|
pwin = (struct _Window*) pWin;
|
|
|
|
if (pwin->optional)
|
|
prop = (struct _Property *) pwin->optional->userProps;
|
|
else
|
|
prop = NULL;
|
|
|
|
while (prop)
|
|
{
|
|
if (prop->propertyName == AtmWindowsWMMouseActivate ()
|
|
&& prop->type == XA_INTEGER
|
|
&& prop->format == 32)
|
|
{
|
|
return *(int*)prop->data;
|
|
}
|
|
else
|
|
prop = prop->next;
|
|
}
|
|
|
|
if (pWin != pRoot)
|
|
{
|
|
return IsMouseActive (pRoot);
|
|
}
|
|
else
|
|
{
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("IsMouseActive - no prop use default value:%d\n",
|
|
MOUSE_ACTIVATE_DEFAULT);
|
|
#endif
|
|
return MOUSE_ACTIVATE_DEFAULT;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* winMWExtWMWindowProc - Window procedure
|
|
*/
|
|
|
|
LRESULT CALLBACK
|
|
winMWExtWMWindowProc (HWND hwnd, UINT message,
|
|
WPARAM wParam, LPARAM lParam)
|
|
{
|
|
WindowPtr pWin = NULL;
|
|
win32RootlessWindowPtr pRLWinPriv = NULL;
|
|
ScreenPtr pScreen = NULL;
|
|
winPrivScreenPtr pScreenPriv = NULL;
|
|
winScreenInfo *pScreenInfo = NULL;
|
|
HWND hwndScreen = NULL;
|
|
POINT ptMouse;
|
|
static Bool s_fTracking = FALSE;
|
|
HDC hdcUpdate;
|
|
PAINTSTRUCT ps;
|
|
LPWINDOWPOS pWinPos = NULL;
|
|
RECT rcClient;
|
|
winWMMessageRec wmMsg;
|
|
Bool fWMMsgInitialized = FALSE;
|
|
|
|
/* Check if the Windows window property for our X window pointer is valid */
|
|
if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL)
|
|
{
|
|
pWin = pRLWinPriv->pFrame->win;
|
|
pScreen = pWin->drawable.pScreen;
|
|
if (pScreen) pScreenPriv = winGetScreenPriv(pScreen);
|
|
if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
|
|
if (pScreenPriv) hwndScreen = pScreenPriv->hwndScreen;
|
|
|
|
wmMsg.msg = 0;
|
|
wmMsg.hwndWindow = hwnd;
|
|
wmMsg.iWindow = (Window)pWin->drawable.id;
|
|
|
|
wmMsg.iX = pRLWinPriv->pFrame->x;
|
|
wmMsg.iY = pRLWinPriv->pFrame->y;
|
|
wmMsg.iWidth = pRLWinPriv->pFrame->width;
|
|
wmMsg.iHeight = pRLWinPriv->pFrame->height;
|
|
|
|
fWMMsgInitialized = TRUE;
|
|
#if CYGDEBUG
|
|
winDebugWin32Message("winMWExtWMWindowProc", hwnd, message, wParam, lParam);
|
|
|
|
winDebug ("\thWnd %08X\n", hwnd);
|
|
winDebug ("\tpScreenPriv %08X\n", pScreenPriv);
|
|
winDebug ("\tpScreenInfo %08X\n", pScreenInfo);
|
|
winDebug ("\thwndScreen %08X\n", hwndScreen);
|
|
winDebug ("winMWExtWMWindowProc (%08x) %08x %08x %08x\n",
|
|
pRLWinPriv, message, wParam, lParam);
|
|
#endif
|
|
}
|
|
/* Branch on message type */
|
|
switch (message)
|
|
{
|
|
case WM_CREATE:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_CREATE\n");
|
|
#endif
|
|
/* */
|
|
SetProp (hwnd,
|
|
WIN_WINDOW_PROP,
|
|
(HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams);
|
|
return 0;
|
|
|
|
case WM_CLOSE:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_CLOSE %d\n", pRLWinPriv->fClose);
|
|
#endif
|
|
/* Tell window-manager to close window */
|
|
if (pRLWinPriv->fClose)
|
|
{
|
|
DestroyWindow (hwnd);
|
|
}
|
|
else
|
|
{
|
|
if (winIsInternalWMRunning(pScreenInfo))
|
|
{
|
|
/* Tell our Window Manager thread to kill the window */
|
|
wmMsg.msg = WM_WM_KILL;
|
|
if (fWMMsgInitialized)
|
|
winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
|
|
}
|
|
winWindowsWMSendEvent(WindowsWMControllerNotify,
|
|
WindowsWMControllerNotifyMask,
|
|
1,
|
|
WindowsWMCloseWindow,
|
|
pWin->drawable.id,
|
|
0, 0, 0, 0);
|
|
}
|
|
return 0;
|
|
|
|
case WM_DESTROY:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_DESTROY\n");
|
|
#endif
|
|
/* Free the shaodw DC; which allows the bitmap to be freed */
|
|
DeleteDC (pRLWinPriv->hdcShadow);
|
|
pRLWinPriv->hdcShadow = NULL;
|
|
|
|
/* Free the shadow bitmap */
|
|
DeleteObject (pRLWinPriv->hbmpShadow);
|
|
pRLWinPriv->hbmpShadow = NULL;
|
|
|
|
/* Free the screen DC */
|
|
ReleaseDC (pRLWinPriv->hWnd, pRLWinPriv->hdcScreen);
|
|
pRLWinPriv->hdcScreen = NULL;
|
|
|
|
/* Free shadow buffer info header */
|
|
free (pRLWinPriv->pbmihShadow);
|
|
pRLWinPriv->pbmihShadow = NULL;
|
|
|
|
pRLWinPriv->fResized = FALSE;
|
|
pRLWinPriv->pfb = NULL;
|
|
free (pRLWinPriv);
|
|
RemoveProp (hwnd, WIN_WINDOW_PROP);
|
|
break;
|
|
|
|
case WM_MOUSEMOVE:
|
|
#if CYGMULTIWINDOW_DEBUG && 0
|
|
winDebug ("winMWExtWMWindowProc - WM_MOUSEMOVE\n");
|
|
#endif
|
|
/* Unpack the client area mouse coordinates */
|
|
ptMouse.x = GET_X_LPARAM(lParam);
|
|
ptMouse.y = GET_Y_LPARAM(lParam);
|
|
|
|
/* Translate the client area mouse coordinates to screen coordinates */
|
|
ClientToScreen (hwnd, &ptMouse);
|
|
|
|
/* Screen Coords from (-X, -Y) -> Root Window (0, 0) */
|
|
ptMouse.x -= GetSystemMetrics (SM_XVIRTUALSCREEN);
|
|
ptMouse.y -= GetSystemMetrics (SM_YVIRTUALSCREEN);
|
|
|
|
/* We can't do anything without privates */
|
|
if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
|
|
break;
|
|
|
|
/* Has the mouse pointer crossed screens? */
|
|
if (pScreen != miPointerCurrentScreen ())
|
|
miPointerSetNewScreen (pScreenInfo->dwScreen,
|
|
ptMouse.x - pScreenInfo->dwXOffset,
|
|
ptMouse.y - pScreenInfo->dwYOffset);
|
|
|
|
/* Are we tracking yet? */
|
|
if (!s_fTracking)
|
|
{
|
|
TRACKMOUSEEVENT tme;
|
|
|
|
/* Setup data structure */
|
|
ZeroMemory (&tme, sizeof (tme));
|
|
tme.cbSize = sizeof (tme);
|
|
tme.dwFlags = TME_LEAVE;
|
|
tme.hwndTrack = hwnd;
|
|
|
|
/* Call the tracking function */
|
|
if (!(*g_fpTrackMouseEvent) (&tme))
|
|
ErrorF ("winMWExtWMWindowProc - _TrackMouseEvent failed\n");
|
|
|
|
/* Flag that we are tracking now */
|
|
s_fTracking = TRUE;
|
|
}
|
|
|
|
/* Kill the timer used to poll mouse events */
|
|
if (g_uipMousePollingTimerID != 0)
|
|
{
|
|
KillTimer (pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID);
|
|
g_uipMousePollingTimerID = 0;
|
|
}
|
|
|
|
/* Deliver absolute cursor position to X Server */
|
|
miPointerAbsoluteCursor (ptMouse.x - pScreenInfo->dwXOffset,
|
|
ptMouse.y - pScreenInfo->dwYOffset,
|
|
g_c32LastInputEventTime = GetTickCount ());
|
|
return 0;
|
|
|
|
case WM_NCMOUSEMOVE:
|
|
#if CYGMULTIWINDOW_DEBUG && 0
|
|
winDebug ("winMWExtWMWindowProc - WM_NCMOUSEMOVE\n");
|
|
#endif
|
|
/*
|
|
* We break instead of returning 0 since we need to call
|
|
* DefWindowProc to get the mouse cursor changes
|
|
* and min/max/close button highlighting in Windows XP.
|
|
* The Platform SDK says that you should return 0 if you
|
|
* process this message, but it fails to mention that you
|
|
* will give up any default functionality if you do return 0.
|
|
*/
|
|
|
|
/* We can't do anything without privates */
|
|
if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
|
|
break;
|
|
|
|
/*
|
|
* Timer to poll mouse events. This is needed to make
|
|
* programs like xeyes follow the mouse properly.
|
|
*/
|
|
if (g_uipMousePollingTimerID == 0)
|
|
g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen,
|
|
WIN_POLLING_MOUSE_TIMER_ID,
|
|
MOUSE_POLLING_INTERVAL,
|
|
NULL);
|
|
break;
|
|
|
|
case WM_MOUSELEAVE:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_MOUSELEAVE\n");
|
|
#endif
|
|
/* Mouse has left our client area */
|
|
|
|
/* Flag that we are no longer tracking */
|
|
s_fTracking = FALSE;
|
|
|
|
/*
|
|
* Timer to poll mouse events. This is needed to make
|
|
* programs like xeyes follow the mouse properly.
|
|
*/
|
|
if (g_uipMousePollingTimerID == 0)
|
|
g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen,
|
|
WIN_POLLING_MOUSE_TIMER_ID,
|
|
MOUSE_POLLING_INTERVAL,
|
|
NULL);
|
|
return 0;
|
|
|
|
case WM_LBUTTONDBLCLK:
|
|
case WM_LBUTTONDOWN:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_LBUTTONDBLCLK\n");
|
|
#endif
|
|
if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
|
|
break;
|
|
SetCapture (hwnd);
|
|
return winMouseButtonsHandle (pScreen, ButtonPress, Button1, wParam);
|
|
|
|
case WM_LBUTTONUP:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_LBUTTONUP\n");
|
|
#endif
|
|
if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
|
|
break;
|
|
ReleaseCapture ();
|
|
return winMouseButtonsHandle (pScreen, ButtonRelease, Button1, wParam);
|
|
|
|
case WM_MBUTTONDBLCLK:
|
|
case WM_MBUTTONDOWN:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_MBUTTONDBLCLK\n");
|
|
#endif
|
|
if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
|
|
break;
|
|
SetCapture (hwnd);
|
|
return winMouseButtonsHandle (pScreen, ButtonPress, Button2, wParam);
|
|
|
|
case WM_MBUTTONUP:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_MBUTTONUP\n");
|
|
#endif
|
|
if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
|
|
break;
|
|
ReleaseCapture ();
|
|
return winMouseButtonsHandle (pScreen, ButtonRelease, Button2, wParam);
|
|
|
|
case WM_RBUTTONDBLCLK:
|
|
case WM_RBUTTONDOWN:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_RBUTTONDBLCLK\n");
|
|
#endif
|
|
if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
|
|
break;
|
|
SetCapture (hwnd);
|
|
return winMouseButtonsHandle (pScreen, ButtonPress, Button3, wParam);
|
|
|
|
case WM_RBUTTONUP:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_RBUTTONUP\n");
|
|
#endif
|
|
if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
|
|
break;
|
|
ReleaseCapture ();
|
|
return winMouseButtonsHandle (pScreen, ButtonRelease, Button3, wParam);
|
|
|
|
case WM_XBUTTONDBLCLK:
|
|
case WM_XBUTTONDOWN:
|
|
if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
|
|
break;
|
|
SetCapture (hwnd);
|
|
return winMouseButtonsHandle (pScreen, ButtonPress, HIWORD(wParam) + 5, wParam);
|
|
case WM_XBUTTONUP:
|
|
if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
|
|
break;
|
|
ReleaseCapture ();
|
|
return winMouseButtonsHandle (pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam);
|
|
|
|
case WM_MOUSEWHEEL:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_MOUSEWHEEL\n");
|
|
#endif
|
|
|
|
/* Pass the message to the root window */
|
|
SendMessage (hwndScreen, message, wParam, lParam);
|
|
return 0;
|
|
|
|
case WM_MOUSEACTIVATE:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE\n");
|
|
#endif
|
|
#if 1
|
|
/* Check if this window needs to be made active when clicked */
|
|
if (winIsInternalWMRunning(pScreenInfo) && pWin->overrideRedirect)
|
|
{
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE - "
|
|
"MA_NOACTIVATE\n");
|
|
#endif
|
|
|
|
/* */
|
|
return MA_NOACTIVATE;
|
|
}
|
|
#endif
|
|
if (!winIsInternalWMRunning(pScreenInfo) && !IsMouseActive (pWin))
|
|
return MA_NOACTIVATE;
|
|
|
|
break;
|
|
|
|
case WM_KILLFOCUS:
|
|
/* Pop any pressed keys since we are losing keyboard focus */
|
|
winKeybdReleaseKeys ();
|
|
return 0;
|
|
|
|
case WM_SYSDEADCHAR:
|
|
case WM_DEADCHAR:
|
|
/*
|
|
* NOTE: We do nothing with WM_*CHAR messages,
|
|
* nor does the root window, so we can just toss these messages.
|
|
*/
|
|
return 0;
|
|
|
|
case WM_SYSKEYDOWN:
|
|
case WM_KEYDOWN:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_*KEYDOWN\n");
|
|
#endif
|
|
|
|
/*
|
|
* Don't pass Alt-F4 key combo to root window,
|
|
* let Windows translate to WM_CLOSE and close this top-level window.
|
|
*
|
|
* NOTE: We purposely don't check the fUseWinKillKey setting because
|
|
* it should only apply to the key handling for the root window,
|
|
* not for top-level window-manager windows.
|
|
*
|
|
* ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window
|
|
* because that is a key combo that no X app should be expecting to
|
|
* receive, since it has historically been used to shutdown the X server.
|
|
* Passing Ctrl-Alt-Backspace to the root window preserves that
|
|
* behavior, assuming that -unixkill has been passed as a parameter.
|
|
*/
|
|
if (wParam == VK_F4 && (GetKeyState (VK_MENU) & 0x8000))
|
|
break;
|
|
|
|
/* Pass the message to the root window */
|
|
SendMessage (hwndScreen, message, wParam, lParam);
|
|
return 0;
|
|
|
|
case WM_SYSKEYUP:
|
|
case WM_KEYUP:
|
|
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_*KEYUP\n");
|
|
#endif
|
|
|
|
/* Pass the message to the root window */
|
|
SendMessage (hwndScreen, message, wParam, lParam);
|
|
return 0;
|
|
|
|
case WM_HOTKEY:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_HOTKEY\n");
|
|
#endif
|
|
|
|
/* Pass the message to the root window */
|
|
SendMessage (hwndScreen, message, wParam, lParam);
|
|
return 0;
|
|
|
|
case WM_PAINT:
|
|
|
|
/* BeginPaint gives us an hdc that clips to the invalidated region */
|
|
hdcUpdate = BeginPaint (hwnd, &ps);
|
|
|
|
/* Try to copy from the shadow buffer */
|
|
if (!BitBlt (hdcUpdate,
|
|
ps.rcPaint.left, ps.rcPaint.top,
|
|
ps.rcPaint.right - ps.rcPaint.left,
|
|
ps.rcPaint.bottom - ps.rcPaint.top,
|
|
pRLWinPriv->hdcShadow,
|
|
ps.rcPaint.left, ps.rcPaint.top,
|
|
SRCCOPY))
|
|
{
|
|
LPVOID lpMsgBuf;
|
|
|
|
/* Display a fancy error message */
|
|
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL,
|
|
GetLastError (),
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
(LPTSTR) &lpMsgBuf,
|
|
0, NULL);
|
|
|
|
ErrorF ("winMWExtWMWindowProc - BitBlt failed: %s\n",
|
|
(LPSTR)lpMsgBuf);
|
|
LocalFree (lpMsgBuf);
|
|
}
|
|
|
|
/* EndPaint frees the DC */
|
|
EndPaint (hwnd, &ps);
|
|
break;
|
|
|
|
case WM_ACTIVATE:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_ACTIVATE\n");
|
|
#endif
|
|
if (LOWORD(wParam) != WA_INACTIVE)
|
|
{
|
|
if (winIsInternalWMRunning(pScreenInfo))
|
|
{
|
|
#if 0
|
|
/* Raise the window to the top in Z order */
|
|
wmMsg.msg = WM_WM_RAISE;
|
|
if (fWMMsgInitialized)
|
|
winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
|
|
#endif
|
|
/* Tell our Window Manager thread to activate the window */
|
|
wmMsg.msg = WM_WM_ACTIVATE;
|
|
if (fWMMsgInitialized)
|
|
if (!pWin || !pWin->overrideRedirect) /* for OOo menus */
|
|
winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
|
|
}
|
|
winWindowsWMSendEvent(WindowsWMControllerNotify,
|
|
WindowsWMControllerNotifyMask,
|
|
1,
|
|
WindowsWMActivateWindow,
|
|
pWin->drawable.id,
|
|
0, 0,
|
|
0, 0);
|
|
}
|
|
return 0;
|
|
|
|
#if 1
|
|
case WM_WINDOWPOSCHANGING:
|
|
pWinPos = (LPWINDOWPOS)lParam;
|
|
if (!(pWinPos->flags & SWP_NOZORDER))
|
|
{
|
|
if (pRLWinPriv->fRestackingNow || pScreenPriv->fRestacking)
|
|
{
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("Win %08x is now restacking.\n", (unsigned int)pRLWinPriv);
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
if (winIsInternalWMRunning(pScreenInfo) || IsRaiseOnClick (pWin))
|
|
{
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("Win %08x has WINDOWSWM_RAISE_ON_CLICK.\n", (unsigned int)pRLWinPriv);
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("Win %08x forbid to change z order (%08x).\n",
|
|
(unsigned int)pRLWinPriv, (unsigned int)pWinPos->hwndInsertAfter);
|
|
#endif
|
|
pWinPos->flags |= SWP_NOZORDER;
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
case WM_MOVE:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_MOVE - %d ms\n",
|
|
(unsigned int)GetTickCount ());
|
|
#endif
|
|
if (g_fNoConfigureWindow) break;
|
|
#if 0
|
|
/* Bail if Windows window is not actually moving */
|
|
if (pRLWinPriv->dwX == (short) LOWORD(lParam)
|
|
&& pRLWinPriv->dwY == (short) HIWORD(lParam))
|
|
break;
|
|
|
|
/* Also bail if we're maximizing, we'll do the whole thing in WM_SIZE */
|
|
{
|
|
WINDOWPLACEMENT windPlace;
|
|
windPlace.length = sizeof (WINDOWPLACEMENT);
|
|
|
|
/* Get current window placement */
|
|
GetWindowPlacement (hwnd, &windPlace);
|
|
|
|
/* Bail if maximizing */
|
|
if (windPlace.showCmd == SW_MAXIMIZE
|
|
|| windPlace.showCmd == SW_SHOWMAXIMIZED)
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("\t(%d, %d)\n", (short) LOWORD(lParam), (short) HIWORD(lParam));
|
|
#endif
|
|
if (!pRLWinPriv->fMovingOrSizing)
|
|
{
|
|
if (winIsInternalWMRunning(pScreenInfo))
|
|
winAdjustXWindow (pWin, hwnd);
|
|
|
|
winMWExtWMMoveXWindow (pWin,
|
|
(LOWORD(lParam) - wBorderWidth (pWin)
|
|
- GetSystemMetrics (SM_XVIRTUALSCREEN)),
|
|
(HIWORD(lParam) - wBorderWidth (pWin)
|
|
- GetSystemMetrics (SM_YVIRTUALSCREEN)));
|
|
}
|
|
return 0;
|
|
|
|
case WM_SHOWWINDOW:
|
|
#if CYGMULTIWINDOW_DEBUG || TRUE
|
|
winDebug ("winMWExtWMWindowProc - WM_SHOWWINDOW - %d ms\n",
|
|
(unsigned int)GetTickCount ());
|
|
#endif
|
|
/* Bail out if the window is being hidden */
|
|
if (!wParam)
|
|
return 0;
|
|
|
|
if (!pScreenInfo->fInternalWM)//XXXX
|
|
return 0;
|
|
|
|
winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo);
|
|
|
|
if (winIsInternalWMRunning(pScreenInfo))
|
|
{
|
|
#if CYGMULTIWINDOW_DEBUG || TRUE
|
|
winDebug ("\tMapWindow\n");
|
|
#endif
|
|
/* Tell X to map the window */
|
|
MapWindow (pWin, wClient(pWin));
|
|
|
|
if (!pRLWinPriv->pFrame->win->overrideRedirect)
|
|
/* Bring the Windows window to the foreground */
|
|
SetForegroundWindow (hwnd);
|
|
|
|
/* Setup the Window Manager message */
|
|
wmMsg.msg = WM_WM_MAP;
|
|
wmMsg.iWidth = pRLWinPriv->pFrame->width;
|
|
wmMsg.iHeight = pRLWinPriv->pFrame->height;
|
|
|
|
/* Tell our Window Manager thread to map the window */
|
|
if (fWMMsgInitialized)
|
|
winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
|
|
}
|
|
break;
|
|
|
|
case WM_SIZING:
|
|
/* Need to legalize the size according to WM_NORMAL_HINTS */
|
|
/* for applications like xterm */
|
|
return ValidateSizing (hwnd, pWin, wParam, lParam);
|
|
|
|
case WM_WINDOWPOSCHANGED:
|
|
{
|
|
pWinPos = (LPWINDOWPOS) lParam;
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED\n");
|
|
winDebug("\tflags: %s%s%s%s%s%s%s%s%s%s%s%s\n",
|
|
(pWinPos->flags & SWP_DRAWFRAME)?"SWP_DRAWFRAME ":"",
|
|
(pWinPos->flags & SWP_FRAMECHANGED)?"SWP_FRAMECHANGED ":"",
|
|
(pWinPos->flags & SWP_HIDEWINDOW)?"SWP_HIDEWINDOW ":"",
|
|
(pWinPos->flags & SWP_NOACTIVATE)?"SWP_NOACTIVATE ":"",
|
|
(pWinPos->flags & SWP_NOCOPYBITS)?"SWP_NOCOPYBITS ":"",
|
|
(pWinPos->flags & SWP_NOMOVE)?"SWP_NOMOVE ":"",
|
|
(pWinPos->flags & SWP_NOOWNERZORDER)?"SWP_NOOWNERZORDER ":"",
|
|
(pWinPos->flags & SWP_NOSIZE)?"SWP_NOSIZE ":"",
|
|
(pWinPos->flags & SWP_NOREDRAW)?"SWP_NOREDRAW ":"",
|
|
(pWinPos->flags & SWP_NOSENDCHANGING)?"SWP_NOSENDCHANGING ":"",
|
|
(pWinPos->flags & SWP_NOZORDER)?"SWP_NOZORDER ":"",
|
|
(pWinPos->flags & SWP_SHOWWINDOW)?"SWP_SHOWWINDOW ":"");
|
|
winDebug("\tno_configure: %s\n", (g_fNoConfigureWindow?"Yes":"No"));
|
|
winDebug("\textend: (%d, %d, %d, %d)\n",
|
|
pWinPos->x, pWinPos->y, pWinPos->cx, pWinPos->cy);
|
|
|
|
#endif
|
|
if (pWinPos->flags & SWP_HIDEWINDOW) break;
|
|
|
|
/* Reorder if window z order was changed */
|
|
if ((pScreenPriv != NULL)
|
|
&& !(pWinPos->flags & SWP_NOZORDER)
|
|
&& !(pWinPos->flags & SWP_SHOWWINDOW)
|
|
&& winIsInternalWMRunning(pScreenInfo))
|
|
{
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("\twindow z order was changed\n");
|
|
#endif
|
|
if (pWinPos->hwndInsertAfter == HWND_TOP
|
|
||pWinPos->hwndInsertAfter == HWND_TOPMOST
|
|
||pWinPos->hwndInsertAfter == HWND_NOTOPMOST)
|
|
{
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("\traise to top\n");
|
|
#endif
|
|
/* Raise the window to the top in Z order */
|
|
wmMsg.msg = WM_WM_RAISE;
|
|
if (fWMMsgInitialized)
|
|
winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
|
|
}
|
|
#if 1
|
|
else if (pWinPos->hwndInsertAfter == HWND_BOTTOM)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
/* Check if this window is top of X windows. */
|
|
HWND hWndAbove = NULL;
|
|
DWORD dwCurrentProcessID = GetCurrentProcessId ();
|
|
DWORD dwWindowProcessID = 0;
|
|
|
|
for (hWndAbove = pWinPos->hwndInsertAfter;
|
|
hWndAbove != NULL;
|
|
hWndAbove = GetNextWindow (hWndAbove, GW_HWNDPREV))
|
|
{
|
|
/* Ignore other XWin process's window */
|
|
GetWindowThreadProcessId (hWndAbove, &dwWindowProcessID);
|
|
|
|
if ((dwWindowProcessID == dwCurrentProcessID)
|
|
&& GetProp (hWndAbove, WIN_WINDOW_PROP)
|
|
&& !IsWindowVisible (hWndAbove)
|
|
&& !IsIconic (hWndAbove) ) /* ignore minimized windows */
|
|
break;
|
|
}
|
|
/* If this is top of X windows in Windows stack,
|
|
raise it in X stack. */
|
|
if (hWndAbove == NULL)
|
|
{
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("\traise to top\n");
|
|
#endif
|
|
/* Raise the window to the top in Z order */
|
|
wmMsg.msg = WM_WM_RAISE;
|
|
if (fWMMsgInitialized)
|
|
winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if (!(pWinPos->flags & SWP_NOSIZE)) {
|
|
if (IsIconic(hwnd)){
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("\tIconic -> MINIMIZED\n");
|
|
#endif
|
|
if (winIsInternalWMRunning(pScreenInfo))
|
|
{
|
|
/* Raise the window to the top in Z order */
|
|
wmMsg.msg = WM_WM_LOWER;
|
|
if (fWMMsgInitialized)
|
|
winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
|
|
}
|
|
winWindowsWMSendEvent(WindowsWMControllerNotify,
|
|
WindowsWMControllerNotifyMask,
|
|
1,
|
|
WindowsWMMinimizeWindow,
|
|
pWin->drawable.id,
|
|
0, 0, 0, 0);
|
|
} else if (IsZoomed(hwnd)){
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("\tZoomed -> MAXIMIZED\n");
|
|
#endif
|
|
winWindowsWMSendEvent(WindowsWMControllerNotify,
|
|
WindowsWMControllerNotifyMask,
|
|
1,
|
|
WindowsWMMaximizeWindow,
|
|
pWin->drawable.id,
|
|
0, 0, 0, 0);
|
|
} else {
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("\tnone -> RESTORED\n");
|
|
#endif
|
|
winWindowsWMSendEvent(WindowsWMControllerNotify,
|
|
WindowsWMControllerNotifyMask,
|
|
1,
|
|
WindowsWMRestoreWindow,
|
|
pWin->drawable.id,
|
|
0, 0, 0, 0);
|
|
}
|
|
}
|
|
if (!g_fNoConfigureWindow ) {
|
|
|
|
if (!pRLWinPriv->fMovingOrSizing
|
|
/*&& (pWinPos->flags & SWP_SHOWWINDOW)*/) {
|
|
GetClientRect (hwnd, &rcClient);
|
|
MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2);
|
|
|
|
if (!(pWinPos->flags & SWP_NOMOVE)
|
|
&&!(pWinPos->flags & SWP_NOSIZE)) {
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("\tmove & resize\n");
|
|
#endif
|
|
if (winIsInternalWMRunning(pScreenInfo))
|
|
winAdjustXWindow (pWin, hwnd);
|
|
|
|
winMWExtWMMoveResizeXWindow (pWin,
|
|
rcClient.left - wBorderWidth (pWin)
|
|
- GetSystemMetrics (SM_XVIRTUALSCREEN),
|
|
rcClient.top - wBorderWidth (pWin)
|
|
- GetSystemMetrics (SM_YVIRTUALSCREEN),
|
|
rcClient.right - rcClient.left
|
|
- wBorderWidth (pWin)*2,
|
|
rcClient.bottom - rcClient.top
|
|
- wBorderWidth (pWin)*2);
|
|
} else if (!(pWinPos->flags & SWP_NOMOVE)) {
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("\tmove\n");
|
|
#endif
|
|
if (winIsInternalWMRunning(pScreenInfo))
|
|
winAdjustXWindow (pWin, hwnd);
|
|
|
|
winMWExtWMMoveResizeXWindow (pWin,
|
|
rcClient.left - wBorderWidth (pWin)
|
|
- GetSystemMetrics (SM_XVIRTUALSCREEN),
|
|
rcClient.top - wBorderWidth (pWin)
|
|
- GetSystemMetrics (SM_YVIRTUALSCREEN),
|
|
rcClient.right - rcClient.left
|
|
- wBorderWidth (pWin)*2,
|
|
rcClient.bottom - rcClient.top
|
|
- wBorderWidth (pWin)*2);
|
|
} else if (!(pWinPos->flags & SWP_NOMOVE)) {
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("\tmove\n");
|
|
#endif
|
|
if (winIsInternalWMRunning(pScreenInfo))
|
|
winAdjustXWindow (pWin, hwnd);
|
|
|
|
winMWExtWMMoveXWindow (pWin,
|
|
rcClient.left - wBorderWidth (pWin)
|
|
- GetSystemMetrics (SM_XVIRTUALSCREEN),
|
|
rcClient.top - wBorderWidth (pWin)
|
|
- GetSystemMetrics (SM_YVIRTUALSCREEN));
|
|
} else if (!(pWinPos->flags & SWP_NOSIZE)) {
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("\tresize\n");
|
|
#endif
|
|
if (winIsInternalWMRunning(pScreenInfo))
|
|
winAdjustXWindow (pWin, hwnd);
|
|
|
|
winMWExtWMResizeXWindow (pWin,
|
|
rcClient.right - rcClient.left
|
|
- wBorderWidth (pWin)*2,
|
|
rcClient.bottom - rcClient.top
|
|
- wBorderWidth (pWin)*2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED - done.\n");
|
|
#endif
|
|
return 0;
|
|
|
|
case WM_SIZE:
|
|
/* see dix/window.c */
|
|
/* FIXME: Maximize/Restore? */
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_SIZE - %d ms\n",
|
|
(unsigned int)GetTickCount ());
|
|
#endif
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("\t(%d, %d) %d\n", (short) LOWORD(lParam), (short) HIWORD(lParam), g_fNoConfigureWindow);
|
|
#endif
|
|
if (g_fNoConfigureWindow) break;
|
|
|
|
/* Branch on type of resizing occurring */
|
|
switch (wParam)
|
|
{
|
|
case SIZE_MINIMIZED:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("\tSIZE_MINIMIZED\n");
|
|
#endif
|
|
if (winIsInternalWMRunning(pScreenInfo))
|
|
{
|
|
/* Raise the window to the top in Z order */
|
|
wmMsg.msg = WM_WM_LOWER;
|
|
if (fWMMsgInitialized)
|
|
winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
|
|
}
|
|
winWindowsWMSendEvent(WindowsWMControllerNotify,
|
|
WindowsWMControllerNotifyMask,
|
|
1,
|
|
WindowsWMMinimizeWindow,
|
|
pWin->drawable.id,
|
|
0, 0,
|
|
LOWORD(lParam), HIWORD(lParam));
|
|
break;
|
|
|
|
case SIZE_RESTORED:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("\tSIZE_RESTORED\n");
|
|
#endif
|
|
winWindowsWMSendEvent(WindowsWMControllerNotify,
|
|
WindowsWMControllerNotifyMask,
|
|
1,
|
|
WindowsWMRestoreWindow,
|
|
pWin->drawable.id,
|
|
0, 0,
|
|
LOWORD(lParam), HIWORD(lParam));
|
|
break;
|
|
|
|
case SIZE_MAXIMIZED:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("\tSIZE_MAXIMIZED\n");
|
|
#endif
|
|
winWindowsWMSendEvent(WindowsWMControllerNotify,
|
|
WindowsWMControllerNotifyMask,
|
|
1,
|
|
WindowsWMMaximizeWindow,
|
|
pWin->drawable.id,
|
|
0, 0,
|
|
LOWORD(lParam), HIWORD(lParam));
|
|
break;
|
|
}
|
|
|
|
/* Perform the resize and notify the X client */
|
|
if (!pRLWinPriv->fMovingOrSizing)
|
|
{
|
|
if (winIsInternalWMRunning(pScreenInfo))
|
|
winAdjustXWindow (pWin, hwnd);
|
|
|
|
winMWExtWMResizeXWindow (pWin,
|
|
(short) LOWORD(lParam)
|
|
- wBorderWidth (pWin)*2,
|
|
(short) HIWORD(lParam)
|
|
- wBorderWidth (pWin)*2);
|
|
}
|
|
break;
|
|
|
|
case WM_ACTIVATEAPP:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_ACTIVATEAPP - %d ms\n",
|
|
(unsigned int)GetTickCount ());
|
|
#endif
|
|
if (wParam)
|
|
{
|
|
if (winIsInternalWMRunning(pScreenInfo))
|
|
{
|
|
}
|
|
else
|
|
{
|
|
}
|
|
winWindowsWMSendEvent(WindowsWMActivationNotify,
|
|
WindowsWMActivationNotifyMask,
|
|
1,
|
|
WindowsWMIsActive,
|
|
pWin->drawable.id,
|
|
0, 0,
|
|
0, 0);
|
|
}
|
|
else
|
|
{
|
|
winWindowsWMSendEvent(WindowsWMActivationNotify,
|
|
WindowsWMActivationNotifyMask,
|
|
1,
|
|
WindowsWMIsInactive,
|
|
pWin->drawable.id,
|
|
0, 0,
|
|
0, 0);
|
|
}
|
|
break;
|
|
|
|
case WM_SETCURSOR:
|
|
if (LOWORD(lParam) == HTCLIENT)
|
|
{
|
|
if (!g_fSoftwareCursor) SetCursor (pScreenPriv->cursor.handle);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
case WM_ENTERSIZEMOVE:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_ENTERSIZEMOVE - %d ms\n",
|
|
(unsigned int)GetTickCount ());
|
|
#endif
|
|
pRLWinPriv->fMovingOrSizing = TRUE;
|
|
break;
|
|
|
|
case WM_EXITSIZEMOVE:
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMWindowProc - WM_EXITSIZEMOVE - %d ms\n",
|
|
(unsigned int)GetTickCount ());
|
|
#endif
|
|
pRLWinPriv->fMovingOrSizing = FALSE;
|
|
|
|
GetClientRect (hwnd, &rcClient);
|
|
|
|
MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2);
|
|
|
|
if (winIsInternalWMRunning(pScreenInfo))
|
|
winAdjustXWindow (pWin, hwnd);
|
|
|
|
winMWExtWMMoveResizeXWindow (pWin,
|
|
rcClient.left - wBorderWidth (pWin)
|
|
- GetSystemMetrics (SM_XVIRTUALSCREEN),
|
|
rcClient.top - wBorderWidth (pWin)
|
|
- GetSystemMetrics (SM_YVIRTUALSCREEN),
|
|
rcClient.right - rcClient.left
|
|
- wBorderWidth (pWin)*2,
|
|
rcClient.bottom - rcClient.top
|
|
- wBorderWidth (pWin)*2);
|
|
break;
|
|
|
|
case WM_MANAGE:
|
|
ErrorF ("winMWExtWMWindowProc - WM_MANAGE\n");
|
|
break;
|
|
|
|
case WM_UNMANAGE:
|
|
ErrorF ("winMWExtWMWindowProc - WM_UNMANAGE\n");
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return DefWindowProc (hwnd, message, wParam, lParam);
|
|
}
|