3bbfe7b179
Tested by at least ajacoutot@, dcoppa@ & jasper@
434 lines
14 KiB
C
434 lines
14 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);
|
|
}
|
|
|
|
/*
|
|
|
|
|
|
* 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) {
|
|
if (pRLWinPriv != NULL && pRLWinPriv->pFrame != NULL &&
|
|
pRLWinPriv->pFrame->win != 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;
|
|
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 %p %s\n",
|
|
pRLWinPriv, fDecorate ? "Decorate" : "Bare");
|
|
|
|
/* Get the extended window style information */
|
|
dwExStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE);
|
|
|
|
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;
|
|
}
|