xserver-multidpi/hw/xwin/winwin32rootlesswindow.c

467 lines
14 KiB
C
Raw Normal View History

2004-06-21 15:19:32 +02:00
/*
*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
2004-06-21 15:19:32 +02:00
#include "win.h"
#include "winprefs.h"
#if 0
/*
* winMWExtWMReorderWindows
*/
void
winMWExtWMReorderWindows(ScreenPtr pScreen)
2004-06-21 15:19:32 +02:00
{
winScreenPriv(pScreen);
HWND hwnd = NULL;
win32RootlessWindowPtr pRLWin = NULL;
win32RootlessWindowPtr pRLWinSib = NULL;
DWORD dwCurrentProcessID = GetCurrentProcessId();
DWORD dwWindowProcessID = 0;
XID vlist[2];
2004-06-21 15:19:32 +02:00
#if CYGMULTIWINDOW_DEBUG && FALSE
winDebug("winMWExtWMReorderWindows\n");
2004-06-21 15:19:32 +02:00
#endif
pScreenPriv->fRestacking = TRUE;
2004-06-21 15:19:32 +02:00
if (pScreenPriv->fWindowOrderChanged) {
2004-06-21 15:19:32 +02:00
#if CYGMULTIWINDOW_DEBUG
winDebug("winMWExtWMReorderWindows - Need to restack\n");
2004-06-21 15:19:32 +02:00
#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);
}
2004-06-21 15:19:32 +02:00
}
pScreenPriv->fRestacking = FALSE;
pScreenPriv->fWindowOrderChanged = FALSE;
2004-06-21 15:19:32 +02:00
}
#endif
/*
* winMWExtWMMoveXWindow
*/
void
winMWExtWMMoveXWindow(WindowPtr pWin, int x, int y)
2004-06-21 15:19:32 +02:00
{
CARD32 *vlist = malloc(sizeof(CARD32) * 2);
2004-06-21 15:19:32 +02:00
vlist[0] = x;
vlist[1] = y;
ConfigureWindow(pWin, CWX | CWY, vlist, wClient(pWin));
free(vlist);
2004-06-21 15:19:32 +02:00
}
/*
* winMWExtWMResizeXWindow
*/
void
winMWExtWMResizeXWindow(WindowPtr pWin, int w, int h)
2004-06-21 15:19:32 +02:00
{
CARD32 *vlist = malloc(sizeof(CARD32) * 2);
2004-06-21 15:19:32 +02:00
vlist[0] = w;
vlist[1] = h;
ConfigureWindow(pWin, CWWidth | CWHeight, vlist, wClient(pWin));
free(vlist);
2004-06-21 15:19:32 +02:00
}
/*
* winMWExtWMMoveResizeXWindow
*/
void
winMWExtWMMoveResizeXWindow(WindowPtr pWin, int x, int y, int w, int h)
2004-06-21 15:19:32 +02:00
{
CARD32 *vlist = malloc(sizeof(long) * 4);
2004-06-21 15:19:32 +02:00
vlist[0] = x;
vlist[1] = y;
vlist[2] = w;
vlist[3] = h;
2004-06-21 15:19:32 +02:00
ConfigureWindow(pWin, CWX | CWY | CWWidth | CWHeight, vlist, wClient(pWin));
free(vlist);
2004-06-21 15:19:32 +02:00
}
/*
* winMWExtWMUpdateIcon
* Change the Windows window icon
*/
void
winMWExtWMUpdateIcon(Window id)
2004-06-21 15:19:32 +02:00
{
WindowPtr pWin;
HICON hIcon, hiconOld;
2004-06-21 15:19:32 +02:00
dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient,
DixUnknownAccess);
hIcon = winOverrideIcon((unsigned long) pWin);
2004-06-21 15:19:32 +02:00
if (!hIcon)
hIcon = winXIconToHICON(pWin, GetSystemMetrics(SM_CXICON));
2004-06-21 15:19:32 +02:00
if (hIcon) {
win32RootlessWindowPtr pRLWinPriv
= (win32RootlessWindowPtr) RootlessFrameForWindow(pWin, FALSE);
2004-06-21 15:19:32 +02:00
if (pRLWinPriv->hWnd) {
hiconOld = (HICON) SendMessage(pRLWinPriv->hWnd,
WM_SETICON, ICON_BIG,
(LPARAM) hIcon);
winDestroyIcon(hiconOld);
}
hIcon = NULL;
2004-06-21 15:19:32 +02:00
}
}
2004-11-04 12:52:22 +01:00
/*
* winMWExtWMDecorateWindow - Update window style. Called by EnumWindows.
*/
2004-12-05 22:33:23 +01:00
wBOOL CALLBACK
winMWExtWMDecorateWindow(HWND hwnd, LPARAM lParam)
2004-11-04 12:52:22 +01:00
{
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);
2004-11-04 12:52:22 +01:00
}
return TRUE;
2004-11-04 12:52:22 +01:00
}
/*
* winMWExtWMUpdateWindowDecoration - Update window style.
*/
void
winMWExtWMUpdateWindowDecoration(win32RootlessWindowPtr pRLWinPriv,
winScreenInfoPtr pScreenInfo)
2004-11-04 12:52:22 +01:00
{
Bool fDecorate = FALSE;
DWORD dwExStyle = 0;
DWORD dwStyle = 0;
WINDOWPLACEMENT wndPlace;
UINT showCmd = 0;
2004-11-04 12:52:22 +01:00
wndPlace.length = sizeof(WINDOWPLACEMENT);
2004-11-04 12:52:22 +01:00
/* Get current window placement */
GetWindowPlacement(pRLWinPriv->hWnd, &wndPlace);
2004-11-04 12:52:22 +01:00
if (winIsInternalWMRunning(pScreenInfo)) {
if (!pRLWinPriv->pFrame->win->overrideRedirect)
fDecorate = TRUE;
2004-11-04 12:52:22 +01:00
}
#if 0
if (wndPlace.showCmd == SW_HIDE)
return; //showCmd = SWP_HIDEWINDOW;
else
showCmd = SWP_SHOWWINDOW;
2004-11-04 12:52:22 +01:00
#else
if (wndPlace.showCmd == SW_HIDE)
return;
2004-11-04 12:52:22 +01:00
if (IsWindowVisible(pRLWinPriv->hWnd))
showCmd = SWP_SHOWWINDOW;
2004-11-04 12:52:22 +01:00
#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);
2004-11-04 12:52:22 +01:00
#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);
2004-11-04 12:52:22 +01:00
#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;
2004-11-04 12:52:22 +01:00
/* Calculate new rectangle */
rcNew.left += iDx;
rcNew.right += iDx;
rcNew.top += iDy;
rcNew.bottom += iDy;
2004-11-04 12:52:22 +01:00
/* Set the window extended style flags */
SetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
2004-11-04 12:52:22 +01:00
/* Set the window standard style flags */
SetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE,
WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW);
2004-11-04 12:52:22 +01:00
#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));
}
2004-11-04 12:52:22 +01:00
}
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);
2004-11-04 12:52:22 +01:00
#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;
2004-11-04 12:52:22 +01:00
#endif
/* Hide window temporary to remove from taskbar. */
ShowWindow(pRLWinPriv->hWnd, SW_HIDE);
2004-11-04 12:52:22 +01:00
/* Set the window extended style flags */
SetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
2004-11-04 12:52:22 +01:00
/* Set the window standard style flags */
SetWindowLongPtr(pRLWinPriv->hWnd, GWL_STYLE,
WS_POPUP | WS_CLIPCHILDREN);
2004-11-04 12:52:22 +01:00
/* Position the Windows window */
SetWindowPos(pRLWinPriv->hWnd, NULL,
rcNew.left, rcNew.top,
rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
showCmd);
2004-11-04 12:52:22 +01:00
winMWExtWMReshapeFrame((RootlessFrameID) pRLWinPriv,
wBoundingShape(pRLWinPriv->pFrame->win));
}
2004-11-04 12:52:22 +01:00
}
}
/*
* winIsInternalWMRunning (winScreenInfoPtr pScreenInfo)
*/
Bool
winIsInternalWMRunning(winScreenInfoPtr pScreenInfo)
2004-11-04 12:52:22 +01:00
{
return pScreenInfo->fInternalWM && !pScreenInfo->fAnotherWMRunning;
2004-11-04 12:52:22 +01:00
}
/*
* winMWExtWMRestackWindows
*/
void
winMWExtWMRestackWindows(ScreenPtr pScreen)
2004-11-04 12:52:22 +01:00
{
winScreenPriv(pScreen);
WindowPtr pRoot = pScreen->root;
WindowPtr pWin = NULL;
WindowPtr pWinPrev = NULL;
win32RootlessWindowPtr pRLWin = NULL;
win32RootlessWindowPtr pRLWinPrev = NULL;
int nWindow = 0;
HDWP hWinPosInfo = NULL;
2004-11-04 12:52:22 +01:00
#if CYGMULTIWINDOW_DEBUG
winDebug("winMWExtWMRestackWindows\n");
2004-11-04 12:52:22 +01:00
#endif
pScreenPriv->fRestacking = TRUE;
2004-11-04 12:52:22 +01:00
if (pRoot != NULL) {
for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib)
nWindow++;
2004-11-04 12:52:22 +01:00
hWinPosInfo = BeginDeferWindowPos(nWindow);
2004-11-04 12:52:22 +01:00
for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) {
if (pWin->realized) {
UINT uFlags;
2004-11-04 12:52:22 +01:00
pRLWin =
(win32RootlessWindowPtr) RootlessFrameForWindow(pWin,
FALSE);
if (pRLWin == NULL)
continue;
2004-11-04 12:52:22 +01:00
if (pWinPrev)
pRLWinPrev =
(win32RootlessWindowPtr)
RootlessFrameForWindow(pWinPrev, FALSE);
2004-11-04 12:52:22 +01:00
uFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW;
if (pRLWinPrev != NULL)
uFlags |= SWP_NOACTIVATE;
2004-11-04 12:52:22 +01:00
#if CYGMULTIWINDOW_DEBUG
winDebug
("winMWExtWMRestackWindows - DeferWindowPos (%08x, %08x)\n",
pRLWin->hWnd, pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP);
2004-11-04 12:52:22 +01:00
#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;
}
2004-11-04 12:52:22 +01:00
}
#if CYGMULTIWINDOW_DEBUG
winDebug("winMWExtWMRestackWindows - done\n");
2004-11-04 12:52:22 +01:00
#endif
pScreenPriv->fRestacking = FALSE;
2004-11-04 12:52:22 +01:00
}