428261197a
Tested by ajacoutot@, krw@, shadchin@ and jasper@ on various configurations including multihead with both zaphod and xrandr.
477 lines
12 KiB
C
477 lines
12 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 "winprefs.h"
|
|
|
|
#if 0
|
|
/*
|
|
* winMWExtWMReorderWindows
|
|
*/
|
|
|
|
void
|
|
winMWExtWMReorderWindows (ScreenPtr pScreen)
|
|
{
|
|
winScreenPriv(pScreen);
|
|
HWND hwnd = NULL;
|
|
win32RootlessWindowPtr pRLWin = NULL;
|
|
win32RootlessWindowPtr pRLWinSib = NULL;
|
|
DWORD dwCurrentProcessID = GetCurrentProcessId ();
|
|
DWORD dwWindowProcessID = 0;
|
|
XID vlist[2];
|
|
|
|
#if CYGMULTIWINDOW_DEBUG && FALSE
|
|
winDebug ("winMWExtWMReorderWindows\n");
|
|
#endif
|
|
|
|
pScreenPriv->fRestacking = TRUE;
|
|
|
|
if (pScreenPriv->fWindowOrderChanged)
|
|
{
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMReorderWindows - Need to restack\n");
|
|
#endif
|
|
hwnd = GetTopWindow (NULL);
|
|
|
|
while (hwnd)
|
|
{
|
|
GetWindowThreadProcessId (hwnd, &dwWindowProcessID);
|
|
|
|
if ((dwWindowProcessID == dwCurrentProcessID)
|
|
&& GetProp (hwnd, WIN_WINDOW_PROP))
|
|
{
|
|
pRLWinSib = pRLWin;
|
|
pRLWin = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP);
|
|
|
|
if (pRLWinSib)
|
|
{
|
|
vlist[0] = pRLWinSib->pFrame->win->drawable.id;
|
|
vlist[1] = Below;
|
|
|
|
ConfigureWindow (pRLWin->pFrame->win, CWSibling | CWStackMode,
|
|
vlist, wClient(pRLWin->pFrame->win));
|
|
}
|
|
else
|
|
{
|
|
/* 1st window - raise to the top */
|
|
vlist[0] = Above;
|
|
|
|
ConfigureWindow (pRLWin->pFrame->win, CWStackMode,
|
|
vlist, wClient(pRLWin->pFrame->win));
|
|
}
|
|
}
|
|
hwnd = GetNextWindow (hwnd, GW_HWNDNEXT);
|
|
}
|
|
}
|
|
|
|
pScreenPriv->fRestacking = FALSE;
|
|
pScreenPriv->fWindowOrderChanged = FALSE;
|
|
}
|
|
#endif
|
|
|
|
|
|
/*
|
|
* winMWExtWMMoveXWindow
|
|
*/
|
|
|
|
void
|
|
winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y)
|
|
{
|
|
CARD32 *vlist = malloc(sizeof(CARD32)*2);
|
|
|
|
vlist[0] = x;
|
|
vlist[1] = y;
|
|
ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin));
|
|
free(vlist);
|
|
}
|
|
|
|
|
|
/*
|
|
* winMWExtWMResizeXWindow
|
|
*/
|
|
|
|
void
|
|
winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h)
|
|
{
|
|
CARD32 *vlist = malloc(sizeof(CARD32)*2);
|
|
|
|
vlist[0] = w;
|
|
vlist[1] = h;
|
|
ConfigureWindow (pWin, CWWidth | CWHeight, vlist, wClient(pWin));
|
|
free(vlist);
|
|
}
|
|
|
|
|
|
/*
|
|
* winMWExtWMMoveResizeXWindow
|
|
*/
|
|
|
|
void
|
|
winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h)
|
|
{
|
|
CARD32 *vlist = malloc(sizeof(long)*4);
|
|
|
|
vlist[0] = x;
|
|
vlist[1] = y;
|
|
vlist[2] = w;
|
|
vlist[3] = h;
|
|
|
|
ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight, vlist, wClient(pWin));
|
|
free(vlist);
|
|
}
|
|
|
|
|
|
/*
|
|
* winMWExtWMUpdateIcon
|
|
* Change the Windows window icon
|
|
*/
|
|
|
|
void
|
|
winMWExtWMUpdateIcon (Window id)
|
|
{
|
|
WindowPtr pWin;
|
|
HICON hIcon, hiconOld;
|
|
|
|
dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess);
|
|
hIcon = winOverrideIcon ((unsigned long)pWin);
|
|
|
|
if (!hIcon)
|
|
hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON));
|
|
|
|
if (hIcon)
|
|
{
|
|
win32RootlessWindowPtr pRLWinPriv
|
|
= (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
|
|
|
|
if (pRLWinPriv->hWnd)
|
|
{
|
|
|
|
hiconOld = (HICON) SendMessage (pRLWinPriv->hWnd,
|
|
WM_SETICON, ICON_BIG, (LPARAM) hIcon);
|
|
winDestroyIcon(hiconOld);
|
|
}
|
|
hIcon=NULL;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* winMWExtWMDecorateWindow - Update window style. Called by EnumWindows.
|
|
*/
|
|
|
|
wBOOL CALLBACK
|
|
winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam)
|
|
{
|
|
win32RootlessWindowPtr pRLWinPriv = NULL;
|
|
ScreenPtr pScreen = NULL;
|
|
winPrivScreenPtr pScreenPriv = NULL;
|
|
winScreenInfo *pScreenInfo = NULL;
|
|
|
|
/* Check if the Windows window property for our X window pointer is valid */
|
|
if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL)
|
|
{
|
|
pScreen = pRLWinPriv->pFrame->win->drawable.pScreen;
|
|
if (pScreen) pScreenPriv = winGetScreenPriv(pScreen);
|
|
if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
|
|
if (pRLWinPriv && pScreenInfo) winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*
|
|
* winMWExtWMUpdateWindowDecoration - Update window style.
|
|
*/
|
|
|
|
void
|
|
winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv,
|
|
winScreenInfoPtr pScreenInfo)
|
|
{
|
|
Bool fDecorate = FALSE;
|
|
DWORD dwExStyle = 0;
|
|
DWORD dwStyle = 0;
|
|
WINDOWPLACEMENT wndPlace;
|
|
UINT showCmd = 0;
|
|
|
|
wndPlace.length = sizeof (WINDOWPLACEMENT);
|
|
|
|
/* Get current window placement */
|
|
GetWindowPlacement (pRLWinPriv->hWnd, &wndPlace);
|
|
|
|
if (winIsInternalWMRunning(pScreenInfo))
|
|
{
|
|
if (!pRLWinPriv->pFrame->win->overrideRedirect)
|
|
fDecorate = TRUE;
|
|
}
|
|
#if 0
|
|
if (wndPlace.showCmd == SW_HIDE)
|
|
return;//showCmd = SWP_HIDEWINDOW;
|
|
else
|
|
showCmd = SWP_SHOWWINDOW;
|
|
#else
|
|
if (wndPlace.showCmd == SW_HIDE)
|
|
return;
|
|
|
|
if (IsWindowVisible (pRLWinPriv->hWnd))
|
|
showCmd = SWP_SHOWWINDOW;
|
|
#endif
|
|
|
|
showCmd |= SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER;
|
|
|
|
winDebug ("winMWExtWMUpdateWindowDecoration %08x %s\n",
|
|
(int)pRLWinPriv, fDecorate?"Decorate":"Bare");
|
|
|
|
/* Get the standard and extended window style information */
|
|
dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE);
|
|
dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE);
|
|
|
|
if (fDecorate)
|
|
{
|
|
RECT rcNew;
|
|
int iDx, iDy;
|
|
winWMMessageRec wmMsg;
|
|
winScreenPriv(pScreenInfo->pScreen);
|
|
|
|
/* */
|
|
if (!(dwExStyle & WS_EX_APPWINDOW))
|
|
{
|
|
winDebug ("\tBare=>Decorate\n");
|
|
/* Setup a rectangle with the X window position and size */
|
|
SetRect (&rcNew,
|
|
pRLWinPriv->pFrame->x,
|
|
pRLWinPriv->pFrame->y,
|
|
pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width,
|
|
pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height);
|
|
|
|
#ifdef CYGMULTIWINDOW_DEBUG
|
|
winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
|
|
rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
|
|
rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
|
|
#endif
|
|
/* */
|
|
AdjustWindowRectEx (&rcNew,
|
|
WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW,
|
|
FALSE,
|
|
WS_EX_APPWINDOW);
|
|
|
|
#ifdef CYGMULTIWINDOW_DEBUG
|
|
winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n",
|
|
rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
|
|
rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
|
|
#endif
|
|
/* Calculate position deltas */
|
|
iDx = pRLWinPriv->pFrame->x - rcNew.left;
|
|
iDy = pRLWinPriv->pFrame->y - rcNew.top;
|
|
|
|
/* Calculate new rectangle */
|
|
rcNew.left += iDx;
|
|
rcNew.right += iDx;
|
|
rcNew.top += iDy;
|
|
rcNew.bottom += iDy;
|
|
|
|
/* Set the window extended style flags */
|
|
SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
|
|
|
|
/* Set the window standard style flags */
|
|
SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE,
|
|
WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW);
|
|
|
|
#ifdef CYGMULTIWINDOW_DEBUG
|
|
winDebug("\tWindowStyle: %08x %08x\n",
|
|
WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW,
|
|
WS_EX_APPWINDOW);
|
|
#endif
|
|
/* Position the Windows window */
|
|
#ifdef CYGMULTIWINDOW_DEBUG
|
|
winDebug("\tMoved {%d, %d, %d, %d}, {%d, %d}\n",
|
|
rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
|
|
rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
|
|
#endif
|
|
SetWindowPos (pRLWinPriv->hWnd, NULL,
|
|
rcNew.left, rcNew.top,
|
|
rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
|
|
showCmd);
|
|
|
|
|
|
wmMsg.hwndWindow = pRLWinPriv->hWnd;
|
|
wmMsg.iWindow = (Window)pRLWinPriv->pFrame->win->drawable.id;
|
|
wmMsg.msg = WM_WM_NAME_EVENT;
|
|
winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
|
|
|
|
winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv ,
|
|
wBoundingShape(pRLWinPriv->pFrame->win));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RECT rcNew;
|
|
|
|
/* */
|
|
if (dwExStyle & WS_EX_APPWINDOW)
|
|
{
|
|
winDebug ("\tDecorate=>Bare\n");
|
|
/* Setup a rectangle with the X window position and size */
|
|
SetRect (&rcNew,
|
|
pRLWinPriv->pFrame->x,
|
|
pRLWinPriv->pFrame->y,
|
|
pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width,
|
|
pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height);
|
|
#if 0
|
|
/* */
|
|
AdjustWindowRectEx (&rcNew,
|
|
WS_POPUP | WS_CLIPCHILDREN,
|
|
FALSE,
|
|
WS_EX_TOOLWINDOW);
|
|
|
|
/* Calculate position deltas */
|
|
iDx = pRLWinPriv->pFrame->x - rcNew.left;
|
|
iDy = pRLWinPriv->pFrame->y - rcNew.top;
|
|
|
|
/* Calculate new rectangle */
|
|
rcNew.left += iDx;
|
|
rcNew.right += iDx;
|
|
rcNew.top += iDy;
|
|
rcNew.bottom += iDy;
|
|
#endif
|
|
|
|
/* Hide window temporary to remove from taskbar. */
|
|
ShowWindow( pRLWinPriv->hWnd, SW_HIDE );
|
|
|
|
/* Set the window extended style flags */
|
|
SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
|
|
|
|
/* Set the window standard style flags */
|
|
SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE,
|
|
WS_POPUP | WS_CLIPCHILDREN);
|
|
|
|
/* Position the Windows window */
|
|
SetWindowPos (pRLWinPriv->hWnd, NULL,
|
|
rcNew.left, rcNew.top,
|
|
rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
|
|
showCmd);
|
|
|
|
winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv ,
|
|
wBoundingShape(pRLWinPriv->pFrame->win));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* winIsInternalWMRunning (winScreenInfoPtr pScreenInfo)
|
|
*/
|
|
Bool
|
|
winIsInternalWMRunning (winScreenInfoPtr pScreenInfo)
|
|
{
|
|
return pScreenInfo->fInternalWM && !pScreenInfo->fAnotherWMRunning;
|
|
}
|
|
|
|
|
|
/*
|
|
* winMWExtWMRestackWindows
|
|
*/
|
|
|
|
void
|
|
winMWExtWMRestackWindows (ScreenPtr pScreen)
|
|
{
|
|
winScreenPriv(pScreen);
|
|
WindowPtr pRoot = pScreen->root;
|
|
WindowPtr pWin = NULL;
|
|
WindowPtr pWinPrev = NULL;
|
|
win32RootlessWindowPtr pRLWin = NULL;
|
|
win32RootlessWindowPtr pRLWinPrev = NULL;
|
|
int nWindow = 0;
|
|
HDWP hWinPosInfo = NULL;
|
|
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMRestackWindows\n");
|
|
#endif
|
|
|
|
pScreenPriv->fRestacking = TRUE;
|
|
|
|
if (pRoot != NULL)
|
|
{
|
|
for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib)
|
|
nWindow ++;
|
|
|
|
hWinPosInfo = BeginDeferWindowPos(nWindow);
|
|
|
|
for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib)
|
|
{
|
|
if (pWin->realized)
|
|
{
|
|
UINT uFlags;
|
|
|
|
pRLWin = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
|
|
if (pRLWin == NULL) continue;
|
|
|
|
if (pWinPrev)
|
|
pRLWinPrev = (win32RootlessWindowPtr) RootlessFrameForWindow (pWinPrev, FALSE);
|
|
|
|
uFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW;
|
|
if (pRLWinPrev != NULL) uFlags |= SWP_NOACTIVATE;
|
|
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMRestackWindows - DeferWindowPos (%08x, %08x)\n",
|
|
pRLWin->hWnd,
|
|
pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP);
|
|
#endif
|
|
hWinPosInfo = DeferWindowPos (hWinPosInfo, pRLWin->hWnd,
|
|
pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP,
|
|
0, 0, 0, 0,
|
|
uFlags);
|
|
if (hWinPosInfo == NULL)
|
|
{
|
|
ErrorF ("winMWExtWMRestackWindows - DeferWindowPos () failed: %d\n",
|
|
(int) GetLastError ());
|
|
return;
|
|
}
|
|
pWinPrev = pWin;
|
|
}
|
|
}
|
|
if (!EndDeferWindowPos (hWinPosInfo))
|
|
{
|
|
ErrorF ("winMWExtWMRestackWindows - EndDeferWindowPos () failed: %d\n",
|
|
(int) GetLastError ());
|
|
return;
|
|
}
|
|
}
|
|
|
|
#if CYGMULTIWINDOW_DEBUG
|
|
winDebug ("winMWExtWMRestackWindows - done\n");
|
|
#endif
|
|
pScreenPriv->fRestacking = FALSE;
|
|
}
|