diff options
Diffstat (limited to 'xorg-server/hw/xwin/winwin32rootlesswindow.c')
-rw-r--r-- | xorg-server/hw/xwin/winwin32rootlesswindow.c | 476 |
1 files changed, 476 insertions, 0 deletions
diff --git a/xorg-server/hw/xwin/winwin32rootlesswindow.c b/xorg-server/hw/xwin/winwin32rootlesswindow.c new file mode 100644 index 000000000..dedcd7a76 --- /dev/null +++ b/xorg-server/hw/xwin/winwin32rootlesswindow.c @@ -0,0 +1,476 @@ +/* + *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; + + pWin = (WindowPtr) LookupIDByType (id, RT_WINDOW); + hIcon = (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) SetClassLong (pRLWinPriv->hWnd, + GCL_HICON, + (int) hIcon); + + winDestroyIcon(hiconOld); + } + } +} + + +/* + * 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 = WindowTable[pScreen->myNum]; + 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; +} |