diff options
Diffstat (limited to 'hw/xwin/winmultiwindowwindow.c')
-rw-r--r-- | hw/xwin/winmultiwindowwindow.c | 1272 |
1 files changed, 280 insertions, 992 deletions
diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c index 57d209e2a..15e508659 100644 --- a/hw/xwin/winmultiwindowwindow.c +++ b/hw/xwin/winmultiwindowwindow.c @@ -26,11 +26,22 @@ *from the XFree86 Project. * * Authors: Kensuke Matsuzaki + * Earle F. Philhower, III + * Harold L Hunt II */ -/* $XFree86: xc/programs/Xserver/hw/xwin/winmultiwindowwindow.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winmultiwindowwindow.c,v 1.3 2003/10/02 13:30:10 eich Exp $ */ #include "win.h" #include "dixevents.h" +#include "winmultiwindowclass.h" +#include "winprefs.h" + + +/* + * External global variables + */ + +extern HICON g_hiconX; /* @@ -46,31 +57,12 @@ winDestroyWindowsWindow (WindowPtr pWin); static void winUpdateWindowsWindow (WindowPtr pWin); -static XID -winGetWindowID (WindowPtr pWin); - static void -SendConfigureNotify (WindowPtr pWin); - -static -void -winUpdateRgn (WindowPtr pWindow); - -#ifdef SHAPE -static -void -winReshape (WindowPtr pWin); -#endif - - -/* - * Local globals - */ - -static UINT s_nIDPollingMouse = 2; +winFindWindow (pointer value, XID id, pointer cdata); #if 0 -static BOOL s_fMoveByX = FALSE; +static void +winRestackXWindow (WindowPtr pWin, int smode); #endif @@ -78,9 +70,8 @@ static BOOL s_fMoveByX = FALSE; * Constant defines */ +#define MOUSE_POLLING_INTERVAL 500 -#define MOUSE_POLLING_INTERVAL 500 -#define WIN_MULTIWINDOW_SHAPE YES /* * Macros @@ -118,6 +109,7 @@ winCreateWindowMultiWindow (WindowPtr pWin) pWinPriv->hWnd = NULL; pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen); pWinPriv->fXKilled = FALSE; + pWinPriv->fNeedRestore = FALSE; return fResult; } @@ -191,8 +183,8 @@ winPositionWindowMultiWindow (WindowPtr pWin, int x, int y) iBorder = wBorderWidth (pWin); /* Get the X and Y location of the X window */ - iX = pWin->drawable.x; - iY = pWin->drawable.y; + iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); /* Get the height and width of the X window */ iWidth = pWin->drawable.width; @@ -336,9 +328,10 @@ winMapWindowMultiWindow (WindowPtr pWin) /* Refresh/redisplay the Windows window associated with this X window */ winUpdateWindowsWindow (pWin); -#if WIN_MULTIWINDOW_SHAPE - winReshape (pWin); - winUpdateRgn (pWin); +#ifdef SHAPE + /* Update the Windows window's shape */ + winReshapeMultiWindow (pWin); + winUpdateRgnMultiWindow (pWin); #endif return fResult; @@ -376,6 +369,7 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) WindowPtr pPrevWin; UINT uFlags; HWND hInsertAfter; + HWND hWnd = NULL; winWindowPriv(pWin); #if CYGMULTIWINDOW_DEBUG @@ -387,6 +381,9 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) winGetScreenPriv(pWin->drawable.pScreen)->RestackWindow (pWin, pOldNextSib); + if (winGetScreenPriv(pWin->drawable.pScreen)->fRestacking) + return; + /* Bail out if no window privates or window handle is invalid */ if (!pWinPriv || !pWinPriv->hWnd) return; @@ -409,6 +406,22 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) /* Valid sibling - get handle to insert window after */ hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd; uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE; + + hWnd = GetNextWindow (pWinPriv->hWnd, GW_HWNDPREV); + + do + { + if (GetProp (hWnd, WIN_WINDOW_PROP)) + { + if (hWnd == winGetWindowPriv(pPrevWin)->hWnd) + { + uFlags |= SWP_NOZORDER; + } + break; + } + hWnd = GetNextWindow (hWnd, GW_HWNDPREV); + } + while (hWnd); } else { @@ -427,966 +440,111 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) /* - * SetShape - See Porting Layer Definition - p. 42 - */ - -#ifdef SHAPE -void -winSetShapeMultiWindow (WindowPtr pWin) -{ -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winSetShapeMultiWindow - pWin: %08x\n", pWin); -#endif - - /* Call any wrapped SetShape function */ - if (winGetScreenPriv(pWin->drawable.pScreen)->SetShape) - winGetScreenPriv(pWin->drawable.pScreen)->SetShape (pWin); - - /* - * NOTE: We do not currently do anything here. - */ - -#if WIN_MULTIWINDOW_SHAPE - winReshape (pWin); - winUpdateRgn (pWin); -#endif - - return; -} -#endif - - -/* - * winUpdateRgn - Local function to update a Windows window region - */ - -static -void -winUpdateRgn (WindowPtr pWin) -{ -#if 1 - SetWindowRgn (winGetWindowPriv(pWin)->hWnd, - winGetWindowPriv(pWin)->hRgn, TRUE); -#endif -} - - -/* - * winReshape - Computes the composite clipping region for a window + * winCreateWindowsWindow - Create a Windows window associated with an X window */ -#ifdef SHAPE -static -void -winReshape (WindowPtr pWin) +static void +winCreateWindowsWindow (WindowPtr pWin) { - int nRects; - ScreenPtr pScreen = pWin->drawable.pScreen; - RegionRec rrNewShape; - BoxPtr pShape, pRects, pEnd; - HRGN hRgn, hRgnRect; + int iX, iY; + int iWidth; + int iHeight; + int iBorder; + HWND hWnd; + WNDCLASS wc; winWindowPriv(pWin); + HICON hIcon; +#define CLASS_NAME_LENGTH 512 + char pszClass[CLASS_NAME_LENGTH], pszWindowID[12]; + char *res_name, *res_class, *res_role; + static int s_iWindowID = 0; -#if CYGDEBUG - ErrorF ("winReshape ()\n"); +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin); #endif - - /* Bail if the window is the root window */ - if (pWin->parent == NULL) - return; - /* Bail if the window is not top level */ - if (pWin->parent->parent != NULL) - return; - - /* Bail if Windows window handle is invalid */ - if (pWinPriv->hWnd == NULL) - return; + iBorder = wBorderWidth (pWin); - /* Free any existing window region stored in the window privates */ - if (pWinPriv->hRgn != NULL) - { - DeleteObject (pWinPriv->hRgn); - pWinPriv->hRgn = NULL; - } + iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); - /* Bail if the window has no bounding region defined */ - if (!wBoundingShape (pWin)) - return; + iWidth = pWin->drawable.width; + iHeight = pWin->drawable.height; - REGION_INIT(pScreen, &rrNewShape, NullBox, 0); - REGION_COPY(pScreen, &rrNewShape, wBoundingShape(pWin)); - REGION_TRANSLATE(pScreen, - &rrNewShape, - pWin->borderWidth, - pWin->borderWidth); - - nRects = REGION_NUM_RECTS(&rrNewShape); - pShape = REGION_RECTS(&rrNewShape); + /* Load default X icon in case it's not ready yet */ + if (!g_hiconX) + g_hiconX = (HICON)winOverrideDefaultIcon(); - /* Don't do anything if there are no rectangles in the region */ - if (nRects > 0) - { - RECT rcClient; - RECT rcWindow; - int iOffsetX, iOffsetY; - - /* Get client rectangle */ - if (!GetClientRect (pWinPriv->hWnd, &rcClient)) - { - ErrorF ("winReshape - GetClientRect failed, bailing: %d\n", - GetLastError ()); - return; - } - - /* Translate client rectangle coords to screen coords */ - /* NOTE: Only transforms top and left members */ - ClientToScreen (pWinPriv->hWnd, (LPPOINT) &rcClient); - - /* Get window rectangle */ - if (!GetWindowRect (pWinPriv->hWnd, &rcWindow)) - { - ErrorF ("winReshape - GetWindowRect failed, bailing: %d\n", - GetLastError ()); - return; - } - - /* Calculate offset from window upper-left to client upper-left */ - iOffsetX = rcClient.left - rcWindow.left; - iOffsetY = rcClient.top - rcWindow.top; - - /* Create initial Windows region for title bar */ - /* FIXME: Mean, nasty, ugly hack!!! */ - hRgn = CreateRectRgn (0, 0, rcWindow.right, iOffsetY); - if (hRgn == NULL) - { - ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " - "failed: %d\n", - 0, 0, rcWindow.right, iOffsetY, GetLastError ()); - } - - /* Loop through all rectangles in the X region */ - for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) - { - /* Create a Windows region for the X rectangle */ - hRgnRect = CreateRectRgn (pRects->x1 + iOffsetX - 1, - pRects->y1 + iOffsetY - 1, - pRects->x2 + iOffsetX - 1, - pRects->y2 + iOffsetY - 1); - if (hRgnRect == NULL) - { - ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) " - "failed: %d\n" - "\tx1: %d x2: %d xOff: %d y1: %d y2: %d yOff: %d\n", - pRects->x1 + iOffsetX - 1, - pRects->y1 + iOffsetY - 1, - pRects->x2 + iOffsetX - 1, - pRects->y2 + iOffsetY - 1, - GetLastError (), - pRects->x1, pRects->x2, iOffsetX, - pRects->y1, pRects->y2, iOffsetY); - } - - /* Merge the Windows region with the accumulated region */ - if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) - { - ErrorF ("winReshape - CombineRgn () failed: %d\n", - GetLastError ()); - } - - /* Delete the temporary Windows region */ - DeleteObject (hRgnRect); - } - - /* Save a handle to the composite region in the window privates */ - pWinPriv->hRgn = hRgn; - } - - REGION_UNINIT(pScreen, &rrNewShape); + if (!g_hiconX) + g_hiconX = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)); - return; -} -#endif - - -/* - * winTopLevelWindowProc - Window procedure for all top-level Windows windows. - */ - -LRESULT CALLBACK -winTopLevelWindowProc (HWND hwnd, UINT message, - WPARAM wParam, LPARAM lParam) -{ - POINT ptMouse; - HDC hdcUpdate; - PAINTSTRUCT ps; - WindowPtr pWin = NULL; - winPrivWinPtr pWinPriv = NULL; - ScreenPtr s_pScreen = NULL; - winPrivScreenPtr s_pScreenPriv = NULL; - winScreenInfo *s_pScreenInfo = NULL; - HWND hwndScreen = NULL; - DrawablePtr pDraw = NULL; - int iX, iY, iWidth, iHeight, iBorder; - winWMMessageRec wmMsg; - static Bool s_fTracking = FALSE; - static Bool s_fCursor = TRUE; + /* Try and get the icon from WM_HINTS */ + hIcon = winXIconToHICON (pWin); - /* Check if the Windows window property for our X window pointer is valid */ - if ((pWin = GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) - { - /* Our X window pointer is valid */ - - /* Get pointers to the drawable and the screen */ - pDraw = &pWin->drawable; - s_pScreen = pWin->drawable.pScreen; - - /* Get a pointer to our window privates */ - pWinPriv = winGetWindowPriv(pWin); - - /* Get pointers to our screen privates and screen info */ - s_pScreenPriv = pWinPriv->pScreenPriv; - s_pScreenInfo = s_pScreenPriv->pScreenInfo; - - /* Get the handle for our screen-sized window */ - /* NOTE: This will be going away at some point, right? Harold Hunt - 2003/01/15 */ - hwndScreen = s_pScreenPriv->hwndScreen; - - /* */ - wmMsg.msg = 0; - wmMsg.hwndWindow = hwnd; - wmMsg.iWindow = (Window)GetProp (hwnd, WIN_WID_PROP); - -#if 1 - wmMsg.iX = pWinPriv->iX; - wmMsg.iY = pWinPriv->iY; - wmMsg.iWidth = pWinPriv->iWidth; - wmMsg.iHeight = pWinPriv->iHeight; -#else - wmMsg.iX = pDraw.x; - wmMsg.iY = pDraw.y; - wmMsg.iWidth = pDraw.width; - wmMsg.iHeight = pDraw.height; -#endif - - -#if 0 - /* - * Print some debugging information - */ - - ErrorF ("hWnd %08X\n", hwnd); - ErrorF ("pWin %08X\n", pWin); - ErrorF ("pDraw %08X\n", pDraw); - ErrorF ("\ttype %08X\n", pWin->drawable.type); - ErrorF ("\tclass %08X\n", pWin->drawable.class); - ErrorF ("\tdepth %08X\n", pWin->drawable.depth); - ErrorF ("\tbitsPerPixel %08X\n", pWin->drawable.bitsPerPixel); - ErrorF ("\tid %08X\n", pWin->drawable.id); - ErrorF ("\tx %08X\n", pWin->drawable.x); - ErrorF ("\ty %08X\n", pWin->drawable.y); - ErrorF ("\twidth %08X\n", pWin->drawable.width); - ErrorF ("\thenght %08X\n", pWin->drawable.height); - ErrorF ("\tpScreen %08X\n", pWin->drawable.pScreen); - ErrorF ("\tserialNumber %08X\n", pWin->drawable.serialNumber); - ErrorF ("g_iWindowPrivateIndex %d\n", g_iWindowPrivateIndex); - ErrorF ("pWinPriv %08X\n", pWinPriv); - ErrorF ("s_pScreenPriv %08X\n", s_pScreenPriv); - ErrorF ("s_pScreenInfo %08X\n", s_pScreenInfo); - ErrorF ("hwndScreen %08X\n", hwndScreen); -#endif - } + /* Use default X icon if no icon loaded from WM_HINTS */ + if (!hIcon) + hIcon = g_hiconX; + /* Set standard class name prefix so we can identify window easily */ + strncpy (pszClass, WINDOW_CLASS_X, strlen (WINDOW_CLASS_X)); - - /* Branch on message type */ - switch (message) + if (winMultiWindowGetClassHint (pWin, &res_name, &res_class)) { - case WM_CREATE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_CREATE\n"); -#endif - - /* */ - SetProp (hwnd, - WIN_WINDOW_PROP, - (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams); - - /* */ - SetProp (hwnd, - WIN_WID_PROP, - (HANDLE)winGetWindowID (((LPCREATESTRUCT) lParam)->lpCreateParams)); - return 0; - - case WM_PAINT: - /* Only paint if our window handle is valid */ - if (hwndScreen == NULL) - break; - - /* BeginPaint gives us an hdc that clips to the invalidated region */ - hdcUpdate = BeginPaint (hwnd, &ps); - -#if 0 - /* NOTE: Doesn't appear to be used - Harold Hunt - 2003/01/15 */ - /* Get the dimensions of the client area */ - GetClientRect (hwnd, &rcClient); -#endif - - /* Get the position and dimensions of the window */ - iBorder = wBorderWidth (pWin); - iX = pWin->drawable.x; - iY = pWin->drawable.y; - iWidth = pWin->drawable.width; - iHeight = pWin->drawable.height; - - /* Try to copy from the shadow buffer */ - if (!BitBlt (hdcUpdate, - 0, 0, - iWidth, iHeight, - s_pScreenPriv->hdcShadow, - iX, iY, - 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), // Default language - (LPTSTR) &lpMsgBuf, - 0, NULL); - - ErrorF ("winTopLevelWindowProc - BitBlt failed: %s\n", - (LPSTR)lpMsgBuf); - LocalFree (lpMsgBuf); - } - - /* EndPaint frees the DC */ - EndPaint (hwndScreen, &ps); - return 0; - - -#if 1 - case WM_MOUSEMOVE: - /* 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); - - /* We can't do anything without privates */ - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - - /* Has the mouse pointer crossed screens? */ - if (s_pScreen != miPointerCurrentScreen ()) - miPointerSetNewScreen (s_pScreenInfo->dwScreen, - ptMouse.x - s_pScreenInfo->dwXOffset, - ptMouse.y - s_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 ("winTopLevelWindowProc - _TrackMouseEvent failed\n"); - - /* Flag that we are tracking now */ - s_fTracking = TRUE; - } - - /* Hide or show the Windows mouse cursor */ - if (s_fCursor) - { - /* Hide Windows cursor */ - s_fCursor = FALSE; - ShowCursor (FALSE); - KillTimer (hwnd, s_nIDPollingMouse); - } - - /* Deliver absolute cursor position to X Server */ - miPointerAbsoluteCursor (ptMouse.x - s_pScreenInfo->dwXOffset, - ptMouse.y - s_pScreenInfo->dwYOffset, - g_c32LastInputEventTime = GetTickCount ()); - return 0; - - case WM_NCMOUSEMOVE: - /* - * 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 (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - - /* Non-client mouse movement, show Windows cursor */ - if (!s_fCursor) - { - s_fCursor = TRUE; - ShowCursor (TRUE); - SetTimer (hwnd, s_nIDPollingMouse, MOUSE_POLLING_INTERVAL, NULL); - } - break; - - case WM_MOUSELEAVE: - /* Mouse has left our client area */ - - /* Flag that we are no longer tracking */ - s_fTracking = FALSE; - - /* Show the mouse cursor, if necessary */ - if (!s_fCursor) - { - s_fCursor = TRUE; - ShowCursor (TRUE); - SetTimer (hwnd, s_nIDPollingMouse, MOUSE_POLLING_INTERVAL, NULL); - } - return 0; - - case WM_LBUTTONDBLCLK: - case WM_LBUTTONDOWN: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam); - - case WM_LBUTTONUP: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam); - - case WM_MBUTTONDBLCLK: - case WM_MBUTTONDOWN: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam); - - case WM_MBUTTONUP: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam); - - case WM_RBUTTONDBLCLK: - case WM_RBUTTONDOWN: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam); - - case WM_RBUTTONUP: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam); - -#else - - case WM_MOUSEMOVE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - 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); - - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, MAKELONG(ptMouse.x, ptMouse.y)); - return 0; - - case WM_NCMOUSEMOVE: - case WM_LBUTTONDBLCLK: - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_MBUTTONDBLCLK: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_RBUTTONDBLCLK: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_MOUSELEAVE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_*BUTTON*\n"); -#endif - - /* Pass the message to the root window */ - SendMessage(hwndScreen, message, wParam, MAKELONG(ptMouse.x, ptMouse.y)); - return 0; -#endif - - case WM_MOUSEWHEEL: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_MOUSEWHEEL\n"); -#endif + strncat (pszClass, "-", 1); + strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass)); + strncat (pszClass, "-", 1); + strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass)); - /* Pass the message to the root window */ - SendMessage(hwndScreen, message, wParam, lParam); - return 0; - - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - case WM_SYSDEADCHAR: - case WM_KEYDOWN: - case WM_KEYUP: - case WM_DEADCHAR: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_*KEY*\n"); -#endif - - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, lParam); - return 0; - - case WM_HOTKEY: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_HOTKEY\n"); -#endif - - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, lParam); - return 0; - - -#if 1 - case WM_ACTIVATE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_ACTIVATE\n"); -#endif - - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, lParam); - - /* Bail if inactivating */ - if (LOWORD(wParam) == WA_INACTIVE) - return 0; - - /* Check if the current window is the active window in Windows */ - if (GetActiveWindow () == hwnd) + /* Check if a window class is provided by the WM_WINDOW_ROLE property, + * if not use the WM_CLASS information. + * For further information see: + * http://tronche.com/gui/x/icccm/sec-5.html + */ + if (winMultiWindowGetWindowRole (pWin, &res_role) ) { - /* Tell our Window Manager thread to raise the window */ - wmMsg.msg = WM_WM_RAISE; - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + strcat (pszClass, "-"); + strcat (pszClass, res_role); + free (res_role); } - - /* Tell our Window Manager thread to activate the window */ - wmMsg.msg = WM_WM_ACTIVATE; - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); - - return 0; - - case WM_ACTIVATEAPP: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_ACTIVATEAPP\n"); -#endif - - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, lParam); - return 0; -#endif - - case WM_CLOSE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_CLOSE\n"); -#endif - /* Branch on if the window was killed in X already */ - if (pWinPriv->fXKilled) - { - /* Window was killed, go ahead and destroy the window */ - DestroyWindow (hwnd); - } - else - { - /* Tell our Window Manager thread to kill the window */ - wmMsg.msg = WM_WM_KILL; - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); - } - return 0; - - case WM_DESTROY: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_DESTROY\n"); -#endif - - /* Branch on if the window was killed in X already */ - if (pWinPriv && !pWinPriv->fXKilled) - { - ErrorF ("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n"); - - /* Tell our Window Manager thread to kill the window */ - wmMsg.msg = WM_WM_KILL; - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); - } - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_DESTROY\n"); -#endif - break; - - case WM_MOVE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_MOVE - %d ms\n", GetTickCount ()); -#endif - - /* Bail if Windows window is not actually moving */ - if (pWinPriv->iX == (short) LOWORD(lParam) - && pWinPriv->iY == (short) HIWORD(lParam)) - break; - - /* Get new position */ - pWinPriv->iX = (short) LOWORD(lParam); - pWinPriv->iY = (short) HIWORD(lParam); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\t(%d, %d)\n", pWinPriv->iX, pWinPriv->iY); -#endif - - /* Notify the X client that its window is moving */ - if (SubStrSend(pWin, pWin->parent)) - SendConfigureNotify (pWin); - - /* Tell X that the window is moving */ - (s_pScreen->MoveWindow) (pWin, - (int)(short) LOWORD(lParam) - wBorderWidth (pWin), - (int)(short) HIWORD(lParam) - wBorderWidth (pWin), - pWin->nextSib, - VTMove); - return 0; - - case WM_SHOWWINDOW: - /* Bail out if the window is being hidden */ - if (!wParam) - return 0; - - /* Tell X to map the window */ - MapWindow (pWin, wClient(pWin)); - - /* */ - if (!pWin->overrideRedirect) - { - DWORD dwExStyle; - DWORD dwStyle; - RECT rcNew; - int iDx, iDy; - - /* Flag that this window needs to be made active when clicked */ - SetProp (hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1); - - /* Get the standard and extended window style information */ - dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE); - dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE); - - /* */ - if (dwExStyle != WS_EX_APPWINDOW) - { - /* Setup a rectangle with the X window position and size */ - SetRect (&rcNew, - pWinPriv->iX, - pWinPriv->iY, - pWinPriv->iX + pWinPriv->iWidth, - pWinPriv->iY + pWinPriv->iHeight); - -#if 0 - ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n", - rcNew.left, rcNew.top, - rcNew.right, rcNew.bottom); -#endif - - /* */ - AdjustWindowRectEx (&rcNew, - WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW, - FALSE, - WS_EX_APPWINDOW); - - /* Calculate position deltas */ - iDx = pWinPriv->iX - rcNew.left; - iDy = pWinPriv->iY - rcNew.top; - - /* Calculate new rectangle */ - rcNew.left += iDx; - rcNew.right += iDx; - rcNew.top += iDy; - rcNew.bottom += iDy; - -#if 0 - ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n", - rcNew.left, rcNew.top, - rcNew.right, rcNew.bottom); -#endif - - /* Set the window extended style flags */ - SetWindowLongPtr (hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW); - - /* Set the window standard style flags */ - SetWindowLongPtr (hwnd, GWL_STYLE, WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW); - - /* Positon the Windows window */ - SetWindowPos (hwnd, HWND_TOP, - rcNew.left, rcNew.top, - rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, - SWP_NOMOVE | SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE); - - /* Bring the Window window to the foreground */ - SetForegroundWindow (hwnd); - } - } - - /* Setup the Window Manager message */ - wmMsg.msg = WM_WM_MAP; - wmMsg.iWidth = pWinPriv->iWidth; - wmMsg.iHeight = pWinPriv->iHeight; - - /* Tell our Window Manager thread to map the window */ - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); - - /* Setup the Window Manager message */ - wmMsg.msg = WM_WM_RAISE; - - /* Tell our Window Manager thread to raise the window */ - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); - return 0; - - case WM_SIZE: - /* see dix/window.c */ - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_SIZE - %d ms\n", GetTickCount ()); -#endif - - switch (wParam) - { - case SIZE_MINIMIZED: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\tSIZE_MINIMIZED\n"); -#endif - - wmMsg.msg = WM_WM_LOWER; - - /* Tell our Window Manager thread to lower the window */ - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); - break; - - case SIZE_RESTORED: - case SIZE_MAXIMIZED: - if (pWinPriv->iWidth == (short) LOWORD(lParam) - && pWinPriv->iHeight == (short) HIWORD(lParam)) - break; - - /* Get the dimensions of the Windows window */ - pWinPriv->iWidth = (short) LOWORD(lParam); - pWinPriv->iHeight = (short) HIWORD(lParam); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\t(%d, %d)\n", pWinPriv->iWidth, pWinPriv->iHeight); -#endif - - /* Check if resize events are redirected */ - if ((pWin->eventMask | wOtherEventMasks (pWin)) & ResizeRedirectMask) - { - xEvent eventT; - - /* Setup the X event structure */ - eventT.u.u.type = ResizeRequest; - eventT.u.resizeRequest.window = pWin->drawable.id; - eventT.u.resizeRequest.width = pWinPriv->iWidth; - eventT.u.resizeRequest.height = pWinPriv->iHeight; - - /* */ - if (MaybeDeliverEventsToClient (pWin, &eventT, 1, - ResizeRedirectMask, - wClient(pWin)) == 1) - break; - } - - /* Notify the X client that its window is being resized */ - if (SubStrSend (pWin, pWin->parent)) - SendConfigureNotify (pWin); - - /* Tell the X server that the window is being resized */ - (s_pScreen->ResizeWindow) (pWin, - pWinPriv->iX - wBorderWidth (pWin), - pWinPriv->iY - wBorderWidth (pWin), - pWinPriv->iWidth, - pWinPriv->iHeight, - pWin->nextSib); - - /* Tell X to redraw the exposed portions of the window */ - { - RegionRec temp; - - /* Get the region describing the X window clip list */ - REGION_INIT(s_pScreen, &temp, NullBox, 0); - REGION_COPY(s_pScreen, &temp, &pWin->clipList); - - /* Expose the clipped region */ - (*s_pScreen->WindowExposures) (pWin, &temp, NullRegion); - - /* Free the region */ - REGION_UNINIT(s_pScreen, &temp); - } - break; - -#if 0 - case SIZE_MAXIMIZED: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\tSIZE_MAXIMIZED\n"); -#endif - - /* Get the dimensions of the window */ - pWinPriv->iWidth = (int)(short) LOWORD(lParam); - pWinPriv->iHeight = (int)(short) HIWORD(lParam); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\t(%d, %d)\n", pWinPriv->iWidth, pWinPriv->iHeight); -#endif - - /* */ - if ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask) - { - xEvent eventT; - - eventT.u.u.type = ResizeRequest; - eventT.u.resizeRequest.window = pWin->drawable.id; - eventT.u.resizeRequest.width = pWinPriv->iWidth; - eventT.u.resizeRequest.height = pWinPriv->iHeight; - if (MaybeDeliverEventsToClient (pWin, &eventT, 1, - ResizeRedirectMask, - wClient(pWin)) == 1); - } - - - (s_pScreen->ResizeWindow) (pWin, - pWinPriv->iX - wBorderWidth (pWin), - pWinPriv->iY - wBorderWidth (pWin), - pWinPriv->iWidth, - pWinPriv->iHeight, - pWin->nextSib); - break; -#endif - - default: - break; - } - return 0; - - case WM_MOUSEACTIVATE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE\n"); -#endif - - /* Check if this window needs to be made active when clicked */ - if (!GetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP)) - { -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE - MA_NOACTIVATE\n"); -#endif - - /* */ - return MA_NOACTIVATE; - } - break; - - case WM_TIMER: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_TIMER - %d ms\n", GetTickCount ()); -#endif - - /* Branch on the type of timer event that fired */ - if (wParam == s_nIDPollingMouse) - { - POINT point; - - /* Get the current position of the mouse cursor */ - GetCursorPos (&point); - - /* Deliver absolute cursor position to X Server */ - miPointerAbsoluteCursor (point.x, point.y, - g_c32LastInputEventTime = GetTickCount ()); - } - else - { - ErrorF ("winTopLevelWindowProc - Unknown WM_TIMER\n"); - } - return 0; - - default: - break; + free (res_name); + free (res_class); } - return DefWindowProc (hwnd, message, wParam, lParam); -} - - -/* - * winCreateWindowsWindow - Create a Windows window associated with an X window - */ - -static void -winCreateWindowsWindow (WindowPtr pWin) -{ - int iX, iY; - int iWidth; - int iHeight; - int iBorder; - HWND hWnd; - WNDCLASS wc; - winWindowPriv(pWin); + /* Add incrementing window ID to make unique class name */ + sprintf (pszWindowID, "-%x", s_iWindowID++); + strcat (pszClass, pszWindowID); #if CYGMULTIWINDOW_DEBUG - ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin); + ErrorF ("winCreateWindowsWindow - Creating class: %s\n", pszClass); #endif - iBorder = wBorderWidth (pWin); - - iX = pWin->drawable.x; - iY = pWin->drawable.y; - - iWidth = pWin->drawable.width; - iHeight = pWin->drawable.height; - /* Setup our window class */ wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = winTopLevelWindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = g_hInstance; - wc.hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)); + wc.hIcon = hIcon; wc.hCursor = 0; wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wc.lpszMenuName = NULL; - wc.lpszClassName = WINDOW_CLASS_X; + wc.lpszClassName = pszClass; RegisterClass (&wc); /* Create the window */ - hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ - WINDOW_CLASS_X, /* Class name */ - WINDOW_TITLE_X, /* Window name */ + hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ + pszClass, /* Class name */ + WINDOW_TITLE_X, /* Window name */ WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, - iX, /* Horizontal position */ - iY, /* Vertical position */ - iWidth, /* Right edge */ - iHeight, /* Bottom edge */ - (HWND) NULL, /* No parent or owner window */ - (HMENU) NULL, /* No menu */ - GetModuleHandle (NULL), /* Instance handle */ - pWin); /* ScreenPrivates */ + iX, /* Horizontal position */ + iY, /* Vertical position */ + iWidth, /* Right edge */ + iHeight, /* Bottom edge */ + (HWND) NULL, /* No parent or owner window */ + (HMENU) NULL, /* No menu */ + GetModuleHandle (NULL), /* Instance handle */ + pWin); /* ScreenPrivates */ if (hWnd == NULL) { ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n", @@ -1395,7 +553,9 @@ winCreateWindowsWindow (WindowPtr pWin) pWinPriv->hWnd = hWnd; - + /* Cause the "Always On Top" to be added in main WNDPROC */ + PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0); + SetProp (pWinPriv->hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin)); /* Flag that this Windows window handles its own activation */ @@ -1404,7 +564,8 @@ winCreateWindowsWindow (WindowPtr pWin) /* - * winDestroyWindowsWindow - Destroy a Windows window associated with an X window + * winDestroyWindowsWindow - Destroy a Windows window associated + * with an X window */ static void @@ -1412,21 +573,30 @@ winDestroyWindowsWindow (WindowPtr pWin) { MSG msg; winWindowPriv(pWin); + HICON hiconClass; + HMODULE hInstance; + int iReturn; + char pszClass[512]; #if CYGMULTIWINDOW_DEBUG ErrorF ("winDestroyWindowsWindow\n"); #endif - /* Bail out if the Windows window handle is invalid */ if (pWinPriv->hWnd == NULL) return; - SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, 0); + + /* Store the info we need to destroy after this window is gone */ + hInstance = (HINSTANCE) GetClassLong (pWinPriv->hWnd, GCL_HMODULE); + hiconClass = (HICON) GetClassLong (pWinPriv->hWnd, GCL_HICON); + iReturn = GetClassName (pWinPriv->hWnd, pszClass, 512); + /* Destroy the Windows window */ DestroyWindow (pWinPriv->hWnd); + /* Null our handle to the Window so referencing it will cause an error */ pWinPriv->hWnd = NULL; /* Process all messages on our queue */ @@ -1437,7 +607,30 @@ winDestroyWindowsWindow (WindowPtr pWin) DispatchMessage (&msg); } } - + + /* Only if we were able to get the name */ + if (iReturn) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowsWindow - Unregistering %s: ", pszClass); +#endif + iReturn = UnregisterClass (pszClass, hInstance); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowsWindow - %d Deleting Icon: ", iReturn); +#endif + + /* Only delete if it's not the default */ + if (hiconClass != g_hiconX && + !winIconIsOverride((unsigned long)hiconClass)) + { + iReturn = DestroyIcon (hiconClass); +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowsWindow - %d\n", iReturn); +#endif + } + } + #if CYGMULTIWINDOW_DEBUG ErrorF ("-winDestroyWindowsWindow\n"); #endif @@ -1445,7 +638,8 @@ winDestroyWindowsWindow (WindowPtr pWin) /* - * winUpdateWindowsWindow - Redisplay/redraw a Windows window associated with an X window + * winUpdateWindowsWindow - Redisplay/redraw a Windows window + * associated with an X window */ static void @@ -1489,19 +683,57 @@ winUpdateWindowsWindow (WindowPtr pWin) } +/* + * winGetWindowID - + */ +XID +winGetWindowID (WindowPtr pWin) +{ + WindowIDPairRec wi = {pWin, 0}; + ClientPtr c = wClient(pWin); + + /* */ + FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi); +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winGetWindowID - Window ID: %d\n", wi.id); +#endif + return wi.id; +} +/* + * winMoveXWindow - + */ -typedef struct { - pointer value; - XID id; -} WindowIDPairRec, *WindowIDPairPtr; +void +winMoveXWindow (WindowPtr pWin, int x, int y) +{ + XID *vlist = malloc(sizeof(long)*2); + (CARD32*)vlist[0] = x; + (CARD32*)vlist[1] = y; + ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin)); + free(vlist); +} +/* + * winResizeXWindow - + */ + +void +winResizeXWindow (WindowPtr pWin, int w, int h) +{ + XID *vlist = malloc(sizeof(long)*2); + + (CARD32*)vlist[0] = w; + (CARD32*)vlist[1] = h; + ConfigureWindow (pWin, CWWidth | CWHeight, vlist, wClient(pWin)); + free(vlist); +} /* @@ -1520,55 +752,111 @@ winFindWindow (pointer value, XID id, pointer cdata) } +#if 0 /* - * winGetWindowID - + * winRestackXWindow - */ -static XID -winGetWindowID (WindowPtr pWin) +static void +winRestackXWindow (WindowPtr pWin, int smode) { - WindowIDPairRec wi = {pWin, 0}; - ClientPtr c = wClient(pWin); - - /* */ - FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi); + XID *vlist = malloc(sizeof(unsigned long)); -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winGetWindowID - Window ID: %d\n", wi.id); -#endif + if (vlist == NULL) + { + ErrorF ("winRestackXWindow - malloc () failed\n"); + return; + } - return wi.id; + if (pWin == NULL) + { + ErrorF ("winRestackXWindow - NULL window\n"); + free(vlist); + return; + } + + *((unsigned long*)vlist) = smode; + ConfigureWindow (pWin, CWStackMode, vlist, wClient(pWin)); + + free(vlist); } +#endif /* - * SendConfigureNotify - + * winReorderWindowsMultiWindow - */ -static void -SendConfigureNotify(WindowPtr pWin) +void +winReorderWindowsMultiWindow (ScreenPtr pScreen) { - xEvent event; - winWindowPriv(pWin); + winScreenPriv(pScreen); + HWND hwnd = NULL; + WindowPtr pWin = NULL; + WindowPtr pWinSib = NULL; - event.u.u.type = ConfigureNotify; - event.u.configureNotify.window = pWin->drawable.id; +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winOrderWindowsMultiWindow\n"); +#endif - if (pWin->nextSib) - event.u.configureNotify.aboveSibling = pWin->nextSib->drawable.id; - else - event.u.configureNotify.aboveSibling = None; + pScreenPriv->fRestacking = TRUE; - event.u.configureNotify.x = pWinPriv->iX - wBorderWidth (pWin); - event.u.configureNotify.y = pWinPriv->iY - wBorderWidth (pWin); + if (pScreenPriv->fWindowOrderChanged) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winOrderWindowsMultiWindow - Need to restack\n"); +#endif + hwnd = GetTopWindow (NULL); - event.u.configureNotify.width = pWinPriv->iWidth; - event.u.configureNotify.height = pWinPriv->iHeight; + while (hwnd) + { + if (GetProp (hwnd, WIN_WINDOW_PROP)) + { + pWinSib = pWin; + pWin = GetProp (hwnd, WIN_WINDOW_PROP); + + if (pWinSib) + { + XID *vlist = malloc (sizeof(long) * 2); + + if (vlist == NULL) + { + ErrorF ("winOrderWindowsMultiWindow - malloc () " + "failed\n"); + return; + } + + ((long*)vlist)[0] = winGetWindowID (pWinSib); + ((long*)vlist)[1] = Below; + + ConfigureWindow (pWin, CWSibling | CWStackMode, + vlist, wClient(pWin)); + + free (vlist); + } + } + hwnd = GetNextWindow (hwnd, GW_HWNDNEXT); + } + } - event.u.configureNotify.borderWidth = wBorderWidth (pWin); + pScreenPriv->fRestacking = FALSE; + pScreenPriv->fWindowOrderChanged = FALSE; +} - event.u.configureNotify.override = pWin->overrideRedirect; - /* */ - DeliverEvents (pWin, &event, 1, NullWindow); +/* + * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE + */ + +void +winMinimizeWindow (Window id) +{ + WindowPtr pWin; + winPrivWinPtr pWinPriv; + + pWin = LookupIDByType (id, RT_WINDOW); + + pWinPriv = winGetWindowPriv (pWin); + + ShowWindow (pWinPriv->hWnd, SW_MINIMIZE); } |