From 4e7ade29ed65adfde234c7d0acea0061843011c2 Mon Sep 17 00:00:00 2001 From: Kensuke Matsuzaki Date: Fri, 5 Dec 2003 03:37:26 +0000 Subject: [PATCH] New rootless mode that use generic rootless code. Add windows rootless window management extension. --- fb/fb.h | 2 +- hw/xwin/win.h | 133 +++++ hw/xwin/winblock.c | 5 + hw/xwin/wincreatewnd.c | 2 +- hw/xwin/winengine.c | 4 +- hw/xwin/winscrinit.c | 80 +-- hw/xwin/winwakeup.c | 9 +- hw/xwin/winwin32rootless.c | 907 +++++++++++++++++++++++++++++ hw/xwin/winwin32rootlesswindow.c | 172 ++++++ hw/xwin/winwin32rootlesswndproc.c | 908 ++++++++++++++++++++++++++++++ hw/xwin/winwindowswm.c | 623 ++++++++++++++++++++ miext/rootless/rootlessConfig.h | 14 + 12 files changed, 2817 insertions(+), 42 deletions(-) create mode 100755 hw/xwin/winwin32rootless.c create mode 100755 hw/xwin/winwin32rootlesswindow.c create mode 100755 hw/xwin/winwin32rootlesswndproc.c create mode 100755 hw/xwin/winwindowswm.c diff --git a/fb/fb.h b/fb/fb.h index c9633d248..043061f53 100644 --- a/fb/fb.h +++ b/fb/fb.h @@ -638,7 +638,7 @@ typedef struct { ((WindowPtr) (pWin))->devPrivates[fbWinPrivateIndex].ptr) #endif -#ifdef __DARWIN__ +#if defined(__DARWIN__)||defined(__CYGWIN__) #define __fbPixOriginX(pPix) ((pPix)->drawable.x) #define __fbPixOriginY(pPix) ((pPix)->drawable.y) #else diff --git a/hw/xwin/win.h b/hw/xwin/win.h index 6ecf5ada0..6ad92a932 100644 --- a/hw/xwin/win.h +++ b/hw/xwin/win.h @@ -172,6 +172,7 @@ #include "shadow.h" #include "fb.h" #include "layer.h" +#include "rootless.h" #ifdef RENDER #include "mipict.h" @@ -498,6 +499,16 @@ typedef struct _winPrivScreenRec /* Privates used by both shadow fb DirectDraw servers */ LPDIRECTDRAWCLIPPER pddcPrimary; + /* Privates used by rootless server */ + RootlessFrameID widTop; + QueryBestSizeProcPtr QueryBestSize; + miPointerSpriteFuncPtr spriteFuncs; + HCURSOR hCursor; + Bool fCursorVisible; + int nCX; + int nCY; + + /* Privates used by multi-window server */ pthread_t ptWMProc; pthread_t ptXMsgProc; @@ -553,6 +564,22 @@ typedef struct _winPrivScreenRec } winPrivScreenRec; + typedef struct { + RootlessWindowPtr pFrame; + HWND hWnd; + int dwWidthBytes; + BITMAPINFOHEADER *pbmihShadow; + HBITMAP hbmpShadow; + HDC hdcShadow; + HDC hdcScreen; + BOOL fResized; + BOOL fRestackingNow; + BOOL fClose; + BOOL fDestroyed;//for debug + char *pfb; +} win32RootlessWindowRec, *win32RootlessWindowPtr; + + typedef struct { pointer value; XID id; @@ -1529,6 +1556,112 @@ winWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); +/* + * winwin32rootless.c + */ + +Bool +winWin32RootlessCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen, + int newX, int newY, RegionPtr pShape); + +void +winWin32RootlessDestroyFrame (RootlessFrameID wid); + +void +winWin32RootlessMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY); + +void +winWin32RootlessResizeFrame (RootlessFrameID wid, ScreenPtr pScreen, + int newX, int newY, unsigned int newW, unsigned int newH, + unsigned int gravity); + +void +winWin32RootlessRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid); + +void +winWin32RootlessReshapeFrame (RootlessFrameID wid, RegionPtr pShape); + +void +winWin32RootlessUnmapFrame (RootlessFrameID wid); + +void +winWin32RootlessStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow); + +void +winWin32RootlessStopDrawing (RootlessFrameID wid, Bool flush); + +void +winWin32RootlessUpdateRegion (RootlessFrameID wid, RegionPtr pDamage); + +void +winWin32RootlessDamageRects (RootlessFrameID wid, int count, const BoxRec *rects, + int shift_x, int shift_y); + +void +winWin32RootlessRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin); + +void +winWin32RootlessCopyBytes (unsigned int width, unsigned int height, + const void *src, unsigned int srcRowBytes, + void *dst, unsigned int dstRowBytes); + +void +winWin32RootlessFillBytes (unsigned int width, unsigned int height, unsigned int value, + void *dst, unsigned int dstRowBytes); + +int +winWin32RootlessCompositePixels (unsigned int width, unsigned int height, unsigned int function, + void *src[2], unsigned int srcRowBytes[2], + void *mask, unsigned int maskRowBytes, + void *dst[2], unsigned int dstRowBytes[2]); + +void +winWin32RootlessCopyWindow (RootlessFrameID wid, int dstNrects, const BoxRec *dstRects, + int dx, int dy); + + +/* + * winwin32rootlesswindow.c + */ + +void +winWin32RootlessReorderWindows (ScreenPtr pScreen); + +void +winWin32RootlessMoveXWindow (WindowPtr pWin, int x, int y); + +void +winWin32RootlessResizeXWindow (WindowPtr pWin, int w, int h); + +void +winWin32RootlessUpdateIcon (Window id); + + +/* + * winwin32rootlesscursor.c + */ + +Bool +winWin32RootlessInitCursor (ScreenPtr pScreen); + + +/* + * winwin32rootlesswndproc.c + */ + +LRESULT CALLBACK +winWin32RootlessWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam); + + +/* + * winwindowswm.c + */ + +void +winWindowsWMExtensionInit (); + + /* * END DDX and DIX Function Prototypes */ diff --git a/hw/xwin/winblock.c b/hw/xwin/winblock.c index cc057eed6..85b8b39d3 100644 --- a/hw/xwin/winblock.c +++ b/hw/xwin/winblock.c @@ -76,5 +76,10 @@ winBlockHandler_ProcessMessages: DispatchMessage (&msg); } } + + if (pScreenPriv->pScreenInfo->fMultiWindow) winReorderWindowsMultiWindow ((ScreenPtr)pBlockData); + + if (pScreenPriv->pScreenInfo->fRootless) + winWin32RootlessReorderWindows ((ScreenPtr)pBlockData); } diff --git a/hw/xwin/wincreatewnd.c b/hw/xwin/wincreatewnd.c index 4b1c76136..5c5cc084c 100644 --- a/hw/xwin/wincreatewnd.c +++ b/hw/xwin/wincreatewnd.c @@ -396,7 +396,7 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen) #endif /* Show the window */ - if (pScreenInfo->fMultiWindow) + if (pScreenInfo->fMultiWindow || pScreenInfo->fRootless) { pScreenPriv->fRootWindowShown = FALSE; ShowWindow (*phwnd, SW_HIDE); diff --git a/hw/xwin/winengine.c b/hw/xwin/winengine.c index ba2f989af..9e0e8feb2 100644 --- a/hw/xwin/winengine.c +++ b/hw/xwin/winengine.c @@ -182,9 +182,9 @@ winSetEngine (ScreenPtr pScreen) } /* ShadowGDI is the only engine that supports Multi Window Mode */ - if (pScreenInfo->fMultiWindow) + if (pScreenInfo->fMultiWindow || pScreenInfo->fRootless) { - ErrorF ("winSetEngine - Multi Window => ShadowGDI\n"); + ErrorF ("winSetEngine - Multi Window or Rootless => ShadowGDI\n"); pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; /* Set engine function pointers */ diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c index 8112a7f9e..d53f334fc 100644 --- a/hw/xwin/winscrinit.c +++ b/hw/xwin/winscrinit.c @@ -34,6 +34,32 @@ /* $XFree86: xc/programs/Xserver/hw/xwin/winscrinit.c,v 1.28 2003/08/07 23:47:58 alanh Exp $ */ #include "win.h" +#include "safeAlpha.h" + + +static RootlessFrameProcsRec winWin32RootlessProcs = { + winWin32RootlessCreateFrame, + winWin32RootlessDestroyFrame, + + winWin32RootlessMoveFrame, + winWin32RootlessResizeFrame, + winWin32RootlessRestackFrame, + winWin32RootlessReshapeFrame, + winWin32RootlessUnmapFrame, + + winWin32RootlessStartDrawing, + winWin32RootlessStopDrawing, + winWin32RootlessUpdateRegion, +#ifndef ROOTLESS_TRACK_DAMAGE + winWin32RootlessDamageRects, +#endif + winWin32RootlessRootlessSwitchWindow, + + NULL,//winWin32RootlessCopyBytes, + NULL,//winWin32RootlessFillBytes, + NULL,//winWin32RootlessCompositePixels, + winWin32RootlessCopyWindow +}; /* @@ -389,9 +415,10 @@ winFinishScreenInitFB (int index, #if !WIN_LAYER_SUPPORT /* Initialize the shadow framebuffer layer */ - if (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI - || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD - || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL) + if ((pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI + || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD + || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL) + &&(!pScreenInfo->fRootless)) { #if CYGDEBUG ErrorF ("winFinishScreenInitFB - Calling shadowInit ()\n"); @@ -410,39 +437,22 @@ winFinishScreenInitFB (int index, /* Handle pseudo-rootless mode */ if (pScreenInfo->fRootless) { - /* Define the WRAP macro temporarily for local use */ -#define WRAP(a) \ - if (pScreen->a) { \ - pScreenPriv->a = pScreen->a; \ - } else { \ - ErrorF("null screen fn " #a "\n"); \ - pScreenPriv->a = NULL; \ - } + ErrorF ("winScreenInit - RootlessInit\n"); + + RootlessInit(pScreen, &winWin32RootlessProcs); + + ErrorF ("winScreenInit - RootlessInit - done\n"); + + rootless_CopyBytes_threshold = 0; + rootless_FillBytes_threshold = 0; + rootless_CompositePixels_threshold = 0; + rootless_CopyWindow_threshold = 1;/* FIXME: How many? Profiling needed? */ - /* Save a pointer to each lower-level window procedure */ - WRAP(CreateWindow); - WRAP(DestroyWindow); - WRAP(RealizeWindow); - WRAP(UnrealizeWindow); - WRAP(PositionWindow); - WRAP(ChangeWindowAttributes); -#ifdef SHAPE - WRAP(SetShape); -#endif - - /* Assign pseudo-rootless window procedures to be top level procedures */ - pScreen->CreateWindow = winCreateWindowPRootless; - pScreen->DestroyWindow = winDestroyWindowPRootless; - pScreen->PositionWindow = winPositionWindowPRootless; - pScreen->ChangeWindowAttributes = winChangeWindowAttributesPRootless; - pScreen->RealizeWindow = winMapWindowPRootless; - pScreen->UnrealizeWindow = winUnmapWindowPRootless; -#ifdef SHAPE - pScreen->SetShape = winSetShapePRootless; -#endif - - /* Undefine the WRAP macro, as it is not needed elsewhere */ -#undef WRAP + if (!winWin32RootlessInitCursor (pScreen)) + { + return FALSE; + } + winWindowsWMExtensionInit (); } /* Handle multi window mode */ else if (pScreenInfo->fMultiWindow) diff --git a/hw/xwin/winwakeup.c b/hw/xwin/winwakeup.c index f311d0dc9..fc79f5e66 100644 --- a/hw/xwin/winwakeup.c +++ b/hw/xwin/winwakeup.c @@ -41,9 +41,7 @@ winWakeupHandler (int nScreen, unsigned long ulResult, pointer pReadmask) { -#if 0 winScreenPriv((ScreenPtr)pWakeupData); -#endif MSG msg; /* Process all messages on our queue */ @@ -57,7 +55,12 @@ winWakeupHandler (int nScreen, DispatchMessage (&msg); } } - winReorderWindowsMultiWindow ((ScreenPtr)pWakeupData); + + if (pScreenPriv->pScreenInfo->fMultiWindow) + winReorderWindowsMultiWindow ((ScreenPtr)pWakeupData); + + if (pScreenPriv->pScreenInfo->fRootless) + winWin32RootlessReorderWindows ((ScreenPtr)pWakeupData); } diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c new file mode 100755 index 000000000..b4d2c2ae2 --- /dev/null +++ b/hw/xwin/winwin32rootless.c @@ -0,0 +1,907 @@ +/* + *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 + */ +/* + * Look at hw/darwin/quartz/xpr/xprFrame.c and hw/darwin/quartz/cr/crFrame.c + */ +#include "win.h" +#include +#define _WINDOWSWM_SERVER_ +#include "windowswmstr.h" +#include "dixevents.h" +#include "winmultiwindowclass.h" +#include "winprefs.h" + + +/* + * Constant defines + */ + +#define MOUSE_POLLING_INTERVAL 500 + +#define ULW_COLORKEY 0x00000001 +#define ULW_ALPHA 0x00000002 +#define ULW_OPAQUE 0x00000004 +#define AC_SRC_ALPHA 0x01 +#define CYGMULTIWINDOW_DEBUG YES + +/* + * Global variables + */ + +Bool g_fNoConfigureWindow = FALSE; + + +/* + * External global variables + */ + +extern HICON g_hiconX; + + +/* + * Internal function to get the DIB format that is compatible with the screen + * Fixme: Share code with winshadgdi.c + */ + +static +Bool +winWin32RootlessQueryDIBFormat (win32RootlessWindowPtr pRLWinPriv, BITMAPINFOHEADER *pbmih) +{ + HBITMAP hbmp; +#if CYGDEBUG + LPDWORD pdw = NULL; +#endif + + /* Create a memory bitmap compatible with the screen */ + hbmp = CreateCompatibleBitmap (pRLWinPriv->hdcScreen, 1, 1); + if (hbmp == NULL) + { + ErrorF ("winWin32RootlessQueryDIBFormat - CreateCompatibleBitmap failed\n"); + return FALSE; + } + + /* Initialize our bitmap info header */ + ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); + pbmih->biSize = sizeof (BITMAPINFOHEADER); + + /* Get the biBitCount */ + if (!GetDIBits (pRLWinPriv->hdcScreen, + hbmp, + 0, 1, + NULL, + (BITMAPINFO*) pbmih, + DIB_RGB_COLORS)) + { + ErrorF ("winWin32RootlessQueryDIBFormat - First call to GetDIBits failed\n"); + DeleteObject (hbmp); + return FALSE; + } + +#if CYGDEBUG + /* Get a pointer to bitfields */ + pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); + + ErrorF ("winWin32RootlessQueryDIBFormat - First call masks: %08x %08x %08x\n", + pdw[0], pdw[1], pdw[2]); +#endif + + /* Get optimal color table, or the optimal bitfields */ + if (!GetDIBits (pRLWinPriv->hdcScreen, + hbmp, + 0, 1, + NULL, + (BITMAPINFO*)pbmih, + DIB_RGB_COLORS)) + { + ErrorF ("winWin32RootlessQueryDIBFormat - Second call to GetDIBits " + "failed\n"); + DeleteObject (hbmp); + return FALSE; + } + + /* Free memory */ + DeleteObject (hbmp); + + return TRUE; +} + +static HRGN +winWin32RootlessCreateRgnFromRegion (RegionPtr pShape) +{ + int nRects; + BoxPtr pRects, pEnd; + HRGN hRgn, hRgnRect; + + if (pShape == NULL) return NULL; + + nRects = REGION_NUM_RECTS(pShape); + pRects = REGION_RECTS(pShape); + + hRgn = CreateRectRgn (0, 0, 0, 0); + if (hRgn == NULL) + { + ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " + "failed: %d\n", + 0, 0, 0, 0, (int) GetLastError ()); + } + + /* Loop through all rectangles in the X region */ + for (pEnd = pRects + nRects; pRects < pEnd; pRects++) + { + /* Create a Windows region for the X rectangle */ + hRgnRect = CreateRectRgn (pRects->x1, + pRects->y1, + pRects->x2, + pRects->y2); + if (hRgnRect == NULL) + { + ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) " + "failed: %d\n", + pRects->x1, + pRects->y1, + pRects->x2, + pRects->y2, + (int) GetLastError ()); + } + + /* Merge the Windows region with the accumulated region */ + if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) + { + ErrorF ("winReshape - CombineRgn () failed: %d\n", + (int) GetLastError ()); + } + + /* Delete the temporary Windows region */ + DeleteObject (hRgnRect); + } + + return hRgn; +} + +static void +InitWin32RootlessEngine (win32RootlessWindowPtr pRLWinPriv) +{ + pRLWinPriv->hdcScreen = GetDC (pRLWinPriv->hWnd); + pRLWinPriv->hdcShadow = CreateCompatibleDC (pRLWinPriv->hdcScreen); + pRLWinPriv->hbmpShadow = NULL; + + /* Allocate bitmap info header */ + pRLWinPriv->pbmihShadow = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) + + 256 * sizeof (RGBQUAD)); + if (pRLWinPriv->pbmihShadow == NULL) + { + ErrorF ("winWin32RootlessCreateFrame - malloc () failed\n"); + return; + } + + /* Query the screen format */ + winWin32RootlessQueryDIBFormat (pRLWinPriv, + pRLWinPriv->pbmihShadow); +} + +Bool +winWin32RootlessCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen, + int newX, int newY, RegionPtr pShape) +{ +#define CLASS_NAME_LENGTH 512 + Bool fResult = TRUE; + win32RootlessWindowPtr pRLWinPriv; + WNDCLASS wc; + char pszClass[CLASS_NAME_LENGTH], pszWindowID[12]; + HICON hIcon; + char *res_name, *res_class, *res_role; + static int s_iWindowID = 0; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessCreateFrame %d %d - %d %d\n", + newX, newY, pFrame->width, pFrame->height); +#endif + + pRLWinPriv = (win32RootlessWindowPtr) malloc (sizeof (win32RootlessWindowRec)); + pRLWinPriv->pFrame = pFrame; + pRLWinPriv->pfb = NULL; + pRLWinPriv->hbmpShadow = NULL; + pRLWinPriv->hdcShadow = NULL; + pRLWinPriv->hdcScreen = NULL; + pRLWinPriv->fResized = TRUE; + pRLWinPriv->fClose = FALSE; + pRLWinPriv->fRestackingNow = FALSE; + pRLWinPriv->fDestroyed = FALSE; + + // Store the implementation private frame ID + pFrame->wid = (RootlessFrameID) pRLWinPriv; + + + /* Load default X icon in case it's not ready yet */ + if (!g_hiconX) + g_hiconX = (HICON)winOverrideDefaultIcon(); + + if (!g_hiconX) + g_hiconX = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)); + + /* Try and get the icon from WM_HINTS */ + hIcon = winXIconToHICON (pFrame->win); + + /* 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)); + + if (winMultiWindowGetClassHint (pFrame->win, &res_name, &res_class)) + { + strncat (pszClass, "-", 1); + strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass)); + strncat (pszClass, "-", 1); + strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass)); + + /* 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 (pFrame->win, &res_role) ) + { + strcat (pszClass, "-"); + strcat (pszClass, res_role); + free (res_role); + } + + free (res_name); + free (res_class); + } + + /* Add incrementing window ID to make unique class name */ + sprintf (pszWindowID, "-%x", s_iWindowID++); + strcat (pszClass, pszWindowID); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winCreateWindowsWindow - Creating class: %s\n", pszClass); +#endif + + /* Setup our window class */ + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = winWin32RootlessWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_hInstance; + wc.hIcon = hIcon; + wc.hCursor = 0; + wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = pszClass; + RegisterClass (&wc); + + /* Create the window */ + g_fNoConfigureWindow = TRUE; + pRLWinPriv->hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ + pszClass, /* Class name */ + WINDOW_TITLE_X, /* Window name */ + WS_POPUP | WS_CLIPCHILDREN, + newX, /* Horizontal position */ + newY, /* Vertical position */ + pFrame->width, /* Right edge */ + pFrame->height, /* Bottom edge */ + (HWND) NULL, /* No parent or owner window */ + (HMENU) NULL, /* No menu */ + GetModuleHandle (NULL), /* Instance handle */ + pRLWinPriv); /* ScreenPrivates */ + if (pRLWinPriv->hWnd == NULL) + { + ErrorF ("winWin32RootlessCreateFrame - CreateWindowExA () failed: %d\n", + (int) GetLastError ()); + fResult = FALSE; + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessCreateFrame - ShowWindow\n"); +#endif + + //ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE); + g_fNoConfigureWindow = FALSE; + + if (pShape != NULL) + { + winWin32RootlessReshapeFrame (pFrame->wid, pShape); + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessCreateFrame - (%08x) %08x\n", + (int) pFrame->wid, (int) pRLWinPriv->hWnd); +#if 0 + { + WindowPtr pWin2 = NULL; + win32RootlessWindowPtr pRLWinPriv2 = NULL; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) + { + pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); + } + ErrorF ("winWin32RootlessCreateFrame2 (%08x) %08x\n", + pRLWinPriv2, pRLWinPriv2->hWnd); + if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) + { + ErrorF ("Error param missmatch\n"); + } + } +#endif +#endif + return fResult; +} + +void +winWin32RootlessDestroyFrame (RootlessFrameID wid) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessDestroyFrame (%08x) %08x\n", + (int) pRLWinPriv, (int) pRLWinPriv->hWnd); +#if 0 + { + WindowPtr pWin2 = NULL; + win32RootlessWindowPtr pRLWinPriv2 = NULL; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) + { + pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); + } + ErrorF ("winWin32RootlessDestroyFrame2 (%08x) %08x\n", + pRLWinPriv2, pRLWinPriv2->hWnd); + if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) + { + ErrorF ("Error param missmatch\n"); + *(int*)0 = 1;//raise exseption + } + } +#endif +#endif + + pRLWinPriv->fClose = TRUE; + pRLWinPriv->fDestroyed = TRUE; + /* Destroy the Windows window */ + DestroyWindow (pRLWinPriv->hWnd); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessDestroyFrame - done\n"); +#endif +} + +void +winWin32RootlessMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int iNewX, int iNewY) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + RECT rcNew; + DWORD dwExStyle; + DWORD dwStyle; + int iX, iY, iWidth, iHeight; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessMoveFrame (%08x) (%d %d)\n", (int) pRLWinPriv, iNewX, iNewY); +#endif + + /* Get the Windows window style and extended style */ + dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); + + /* Get the X and Y location of the X window */ + iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Get the height and width of the X window */ + iWidth = pRLWinPriv->pFrame->width; + iHeight = pRLWinPriv->pFrame->height; + + /* Store the origin, height, and width in a rectangle structure */ + SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight); + + /* + * Calculate the required size of the Windows window rectangle, + * given the size of the Windows window client area. + */ + AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); + + g_fNoConfigureWindow = TRUE; + SetWindowPos (pRLWinPriv->hWnd, NULL, rcNew.left, rcNew.top, 0, 0, + SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); + g_fNoConfigureWindow = FALSE; +} + +void +winWin32RootlessResizeFrame (RootlessFrameID wid, ScreenPtr pScreen, + int iNewX, int iNewY, + unsigned int uiNewWidth, unsigned int uiNewHeight, + unsigned int uiGravity) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + RECT rcNew; + RECT rcOld; + DWORD dwExStyle; + DWORD dwStyle; + int iX, iY; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessResizeFrame (%08x) (%d %d)-(%d %d)\n", + (int) pRLWinPriv, iNewX, iNewY, uiNewWidth, uiNewHeight); +#endif + + pRLWinPriv->fResized = TRUE; + + /* Get the Windows window style and extended style */ + dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); + + /* Get the X and Y location of the X window */ + iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Store the origin, height, and width in a rectangle structure */ + SetRect (&rcNew, iX, iY, iX + uiNewWidth, iY + uiNewHeight); + + /* + * Calculate the required size of the Windows window rectangle, + * given the size of the Windows window client area. + */ + AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); + + /* Get a rectangle describing the old Windows window */ + GetWindowRect (pRLWinPriv->hWnd, &rcOld); + + /* Check if the old rectangle and new rectangle are the same */ + if (!EqualRect (&rcNew, &rcOld)) + { + + g_fNoConfigureWindow = TRUE; + MoveWindow (pRLWinPriv->hWnd, + rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + TRUE); + g_fNoConfigureWindow = FALSE; + } +} + +void +winWin32RootlessRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + win32RootlessWindowPtr pRLNextWinPriv = (win32RootlessWindowPtr) nextWid; + winScreenPriv(pRLWinPriv->pFrame->win->drawable.pScreen); + HWND hWnd; +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessRestackFrame (%08x)\n", (int) pRLWinPriv); +#endif + + if (pScreenPriv->fRestacking) return; + + pRLWinPriv->fRestackingNow = TRUE; + + /* Show window */ + if(!IsWindowVisible (pRLWinPriv->hWnd)) + ShowWindow (pRLWinPriv->hWnd, SW_SHOWNA); + + if (pRLNextWinPriv == NULL) + { + //ErrorF ("Win %08x is top\n", pRLWinPriv); + pScreenPriv->widTop = wid; + SetWindowPos (pRLWinPriv->hWnd, HWND_TOP, + 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + } + else + { + //ErrorF ("Win %08x is not top\n", pRLWinPriv); + hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDPREV); + do + { + if (hWnd == pRLNextWinPriv->hWnd) + { + SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, + 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + break; + } + hWnd = GetNextWindow (hWnd, GW_HWNDPREV); + } + while (hWnd); + } + pRLWinPriv->fRestackingNow = FALSE; +} + +void +winWin32RootlessReshapeFrame (RootlessFrameID wid, RegionPtr pShape) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + HRGN hRgn; +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessReshapeFrame (%08x)\n", (int) pRLWinPriv); +#endif + hRgn = winWin32RootlessCreateRgnFromRegion (pShape); + SetWindowRgn (pRLWinPriv->hWnd, hRgn, TRUE); +} + +void +winWin32RootlessUnmapFrame (RootlessFrameID wid) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessUnmapFrame (%08x)\n", (int) pRLWinPriv); +#endif + + g_fNoConfigureWindow = TRUE; + //ShowWindow (pRLWinPriv->hWnd, SW_MINIMIZE); + ShowWindow (pRLWinPriv->hWnd, SW_HIDE); + g_fNoConfigureWindow = FALSE; +} + +/* + * Fixme: Code sharing with winshadgdi.c and other engine support + */ +void +winWin32RootlessStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + winPrivScreenPtr pScreenPriv = NULL; + winScreenInfo *pScreenInfo = NULL; + ScreenPtr pScreen = NULL; + DIBSECTION dibsection; + Bool fReturn = TRUE; + HDC hdcNew; + HBITMAP hbmpNew; +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessStartDrawing (%08x) %08x\n", (int) pRLWinPriv, pRLWinPriv->fDestroyed); +#endif + + if (!pRLWinPriv->fDestroyed) + { + pScreen = pRLWinPriv->pFrame->win->drawable.pScreen; + if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); + if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("pScreenPriv %08X\n", (int) pScreenPriv); + ErrorF ("pScreenInfo %08X\n", (int) pScreenInfo); +#endif + if (pRLWinPriv->hdcScreen == NULL) + { + InitWin32RootlessEngine (pRLWinPriv); + } + + if (pRLWinPriv->fResized) + { + hdcNew = CreateCompatibleDC (pRLWinPriv->hdcScreen); + /* Describe shadow bitmap to be created */ + pRLWinPriv->pbmihShadow->biWidth = pRLWinPriv->pFrame->width;//pRLWinPriv->dwWidth; + pRLWinPriv->pbmihShadow->biHeight = -pRLWinPriv->pFrame->height;//pRLWinPriv->dwHeight; + + /* Create a DI shadow bitmap with a bit pointer */ + hbmpNew = CreateDIBSection (pRLWinPriv->hdcScreen, + (BITMAPINFO *) pRLWinPriv->pbmihShadow, + DIB_RGB_COLORS, + (VOID**) &pRLWinPriv->pfb, + NULL, + 0); + if (hbmpNew == NULL || pRLWinPriv->pfb == NULL) + { + ErrorF ("winWin32RootlessStartDrawing - CreateDIBSection failed\n"); + //return FALSE; + } + else + { +#if CYGDEBUG + ErrorF ("winWin32RootlessStartDrawing - Shadow buffer allocated\n"); +#endif + } + + /* Get information about the bitmap that was allocated */ + GetObject (hbmpNew, sizeof (dibsection), &dibsection); + +#if CYGDEBUG + /* Print information about bitmap allocated */ + ErrorF ("winWin32RootlessStartDrawing - Dibsection width: %d height: %d " + "depth: %d size image: %d\n", + dibsection.dsBmih.biWidth, dibsection.dsBmih.biHeight, + dibsection.dsBmih.biBitCount, + dibsection.dsBmih.biSizeImage); +#endif + + /* Select the shadow bitmap into the shadow DC */ + SelectObject (hdcNew, hbmpNew); + +#if CYGDEBUG + ErrorF ("winWin32RootlessStartDrawing - Attempting a shadow blit\n"); +#endif + + /* Blit from the old shadow to the new shadow */ + fReturn = BitBlt (hdcNew, + 0, 0, + pRLWinPriv->pFrame->width, pRLWinPriv->pFrame->height, + pRLWinPriv->hdcShadow, + 0, 0, + SRCCOPY); + if (fReturn) + { +#if CYGDEBUG + ErrorF ("winWin32RootlessStartDrawing - Shadow blit success\n"); +#endif + } + else + { + ErrorF ("winWin32RootlessStartDrawing - Shadow blit failure\n"); + } + + /* Look for height weirdness */ + if (dibsection.dsBmih.biHeight < 0) + { + /* FIXME: Figure out why biHeight is sometimes negative */ + ErrorF ("winWin32RootlessStartDrawing - WEIRDNESS - biHeight " + "still negative: %d\n" + "winAllocateFBShadowGDI - WEIRDNESS - Flipping biHeight sign\n", + (int) dibsection.dsBmih.biHeight); + dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight; + } + + pRLWinPriv->dwWidthBytes = dibsection.dsBm.bmWidthBytes; + +#if CYGDEBUG + ErrorF ("winWin32RootlessStartDrawing - bytesPerRow: %d\n", + dibsection.dsBm.bmWidthBytes); +#endif + + /* Free the old shadow bitmap */ + DeleteObject (pRLWinPriv->hdcShadow); + DeleteObject (pRLWinPriv->hbmpShadow); + + pRLWinPriv->hdcShadow = hdcNew; + pRLWinPriv->hbmpShadow = hbmpNew; + + pRLWinPriv->fResized = FALSE; + } + } + else + { + ErrorF ("winWin32RootlessStartDrawing - Already window was destoroyed \n"); + } +#if CYGDEBUG + ErrorF ("winWin32RootlessStartDrawing - 0x%08x %d\n", + pRLWinPriv->pfb, dibsection.dsBm.bmWidthBytes); +#endif + *pixelData = pRLWinPriv->pfb; + *bytesPerRow = pRLWinPriv->dwWidthBytes; +} + +void +winWin32RootlessStopDrawing (RootlessFrameID wid, Bool fFlush) +{ +#if 0 + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + BLENDFUNCTION bfBlend; + SIZE szWin; + POINT ptSrc; +#if CYGMULTIWINDOW_DEBUG || TRUE + ErrorF ("winWin32RootlessStopDrawing (%08x)\n", pRLWinPriv); +#endif + szWin.cx = pRLWinPriv->dwWidth; + szWin.cy = pRLWinPriv->dwHeight; + ptSrc.x = 0; + ptSrc.y = 0; + bfBlend.BlendOp = AC_SRC_OVER; + bfBlend.BlendFlags = 0; + bfBlend.SourceConstantAlpha = 255; + bfBlend.AlphaFormat = AC_SRC_ALPHA; + + if (!UpdateLayeredWindow (pRLWinPriv->hWnd, + NULL, NULL, &szWin, + pRLWinPriv->hdcShadow, &ptSrc, + 0, &bfBlend, ULW_ALPHA)) + { + ErrorF ("winWin32RootlessStopDrawing - UpdateLayeredWindow failed\n"); + } +#endif +} + +void +winWin32RootlessUpdateRegion (RootlessFrameID wid, RegionPtr pDamage) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; +#if 0 + BLENDFUNCTION bfBlend; + SIZE szWin; + POINT ptSrc; +#endif +#if CYGMULTIWINDOW_DEBUG && 0 + ErrorF ("winWin32RootlessUpdateRegion (%08x)\n", pRLWinPriv); +#endif +#if 0 + szWin.cx = pRLWinPriv->dwWidth; + szWin.cy = pRLWinPriv->dwHeight; + ptSrc.x = 0; + ptSrc.y = 0; + bfBlend.BlendOp = AC_SRC_OVER; + bfBlend.BlendFlags = 0; + bfBlend.SourceConstantAlpha = 255; + bfBlend.AlphaFormat = AC_SRC_ALPHA; + + if (!UpdateLayeredWindow (pRLWinPriv->hWnd, + NULL, NULL, &szWin, + pRLWinPriv->hdcShadow, &ptSrc, + 0, &bfBlend, ULW_ALPHA)) + { + 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), + (LPTSTR) &lpMsgBuf, + 0, NULL); + + ErrorF ("winWin32RootlessUpdateRegion - UpdateLayeredWindow failed: %s\n", + (LPSTR)lpMsgBuf); + LocalFree (lpMsgBuf); + } +#endif + if (!g_fNoConfigureWindow) UpdateWindow (pRLWinPriv->hWnd); +} + +void +winWin32RootlessDamageRects (RootlessFrameID wid, int nCount, const BoxRec *pRects, + int shift_x, int shift_y) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + const BoxRec *pEnd; +#if CYGMULTIWINDOW_DEBUG && 0 + ErrorF ("winWin32RootlessDamageRects (%08x, %d, %08x, %d, %d)\n", + pRLWinPriv, nCount, pRects, shift_x, shift_y); +#endif + + for (pEnd = pRects + nCount; pRects < pEnd; pRects++) { + RECT rcDmg; + rcDmg.left = pRects->x1 + shift_x; + rcDmg.top = pRects->y1 + shift_y; + rcDmg.right = pRects->x2 + shift_x; + rcDmg.bottom = pRects->y2 + shift_y; + + InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE); + } +} + +void +winWin32RootlessRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid; +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessRootlessSwitchWindow (%08x) %08x\n", + (int) pRLWinPriv, (int) pRLWinPriv->hWnd); +#endif + pRLWinPriv->pFrame = pFrame; + pRLWinPriv->fResized = TRUE; + +#if CYGMULTIWINDOW_DEBUG +#if 0 + { + WindowPtr pWin2 = NULL; + win32RootlessWindowPtr pRLWinPriv2 = NULL; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) + { + pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); + } + ErrorF ("winWin32RootlessSwitchFrame2 (%08x) %08x\n", + pRLWinPriv2, pRLWinPriv2->hWnd); + if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) + { + ErrorF ("Error param missmatch\n"); + } + } +#endif +#endif +} + +void +winWin32RootlessCopyBytes (unsigned int width, unsigned int height, + const void *src, unsigned int srcRowBytes, + void *dst, unsigned int dstRowBytes) +{ +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessCopyBytes - Not implemented\n"); +#endif +} + +void +winWin32RootlessFillBytes (unsigned int width, unsigned int height, unsigned int value, + void *dst, unsigned int dstRowBytes) +{ +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessFillBytes - Not implemented\n"); +#endif +} + +int +winWin32RootlessCompositePixels (unsigned int width, unsigned int height, unsigned int function, + void *src[2], unsigned int srcRowBytes[2], + void *mask, unsigned int maskRowBytes, + void *dst[2], unsigned int dstRowBytes[2]) +{ +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessCompositePixels - Not implemented\n"); +#endif + return 0; +} + + +void +winWin32RootlessCopyWindow (RootlessFrameID wid, int nDstRects, const BoxRec *pDstRects, + int nDx, int nDy) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + const BoxRec *pEnd; + RECT rcDmg; +#if CYGMULTIWINDOW_DEBUG || TRUE + ErrorF ("winWin32RootlessCopyWindow (%08x, %d, %08x, %d, %d)\n", + (int) pRLWinPriv, nDstRects, (int) pDstRects, nDx, nDy); +#endif + + for (pEnd = pDstRects + nDstRects; pDstRects < pEnd; pDstRects++) + { + ErrorF ("BitBlt (%d, %d, %d, %d) (%d, %d)\n", + pDstRects->x1, pDstRects->y1, + pDstRects->x2 - pDstRects->x1, + pDstRects->y2 - pDstRects->y1, + pDstRects->x1 + nDx, + pDstRects->y1 + nDy); + + if (!BitBlt (pRLWinPriv->hdcShadow, + pDstRects->x1, pDstRects->y1, + pDstRects->x2 - pDstRects->x1, + pDstRects->y2 - pDstRects->y1, + pRLWinPriv->hdcShadow, + pDstRects->x1 + nDx, pDstRects->y1 + nDy, + SRCCOPY)) + { + ErrorF ("winWin32RootlessCopyWindow - BitBlt failed.\n"); + } + + rcDmg.left = pDstRects->x1; + rcDmg.top = pDstRects->y1; + rcDmg.right = pDstRects->x2; + rcDmg.bottom = pDstRects->y2; + + InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE); + } +#if CYGMULTIWINDOW_DEBUG || TRUE + ErrorF ("winWin32RootlessCopyWindow - done\n"); +#endif +} diff --git a/hw/xwin/winwin32rootlesswindow.c b/hw/xwin/winwin32rootlesswindow.c new file mode 100755 index 000000000..9ca04efb2 --- /dev/null +++ b/hw/xwin/winwin32rootlesswindow.c @@ -0,0 +1,172 @@ +/* + *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 + */ + +#include "win.h" +#include "winprefs.h" + + +/* + * External global variables + */ + +extern HICON g_hiconX; + + +/* + * winWin32RootlessReorderWindows + */ + +void +winWin32RootlessReorderWindows (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + HWND hwnd = NULL; + win32RootlessWindowPtr pRLWin = NULL; + win32RootlessWindowPtr pRLWinSib = NULL; + +#if CYGMULTIWINDOW_DEBUG && FALSE + ErrorF ("winWin32RootlessReorderWindows\n"); +#endif + + pScreenPriv->fRestacking = TRUE; + + if (pScreenPriv->fWindowOrderChanged) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessReorderWindows - Need to restack\n"); +#endif + hwnd = GetTopWindow (NULL); + + while (hwnd) + { + if (GetProp (hwnd, WIN_WINDOW_PROP)) + { + pRLWinSib = pRLWin; + pRLWin = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP); + + if (pRLWinSib) + { + XID *vlist = malloc (sizeof(long) * 2); + + if (vlist == NULL) + { + ErrorF ("winWin32RootlessReorderWindows - malloc () " + "failed\n"); + return; + } + + ((long*)vlist)[0] = pRLWinSib->pFrame->win->drawable.id; + ((long*)vlist)[1] = Below; + + ConfigureWindow (pRLWin->pFrame->win, CWSibling | CWStackMode, + vlist, wClient(pRLWin->pFrame->win)); + + free (vlist); + } + } + hwnd = GetNextWindow (hwnd, GW_HWNDNEXT); + } + } + + pScreenPriv->fRestacking = FALSE; + pScreenPriv->fWindowOrderChanged = FALSE; + +} + + +/* + * winWin32RootlessMoveXWindow + */ + +void +winWin32RootlessMoveXWindow (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); +} + + +/* + * winWin32RootlessResizeXWindow + */ + +void +winWin32RootlessResizeXWindow (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); +} + + +/* + * winWin32RootlessUpdateIcon + * Change the Windows window icon + */ + +void +winWin32RootlessUpdateIcon (Window id) +{ + WindowPtr pWin; + HICON hIcon, hiconOld; + + pWin = LookupIDByType (id, RT_WINDOW); + hIcon = (HICON)winOverrideIcon ((unsigned long)pWin); + + if (!hIcon) + hIcon = winXIconToHICON (pWin); + + if (hIcon) + { + win32RootlessWindowPtr pRLWinPriv + = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); + + if (pRLWinPriv->hWnd) + { + hiconOld = (HICON) SetClassLong (pRLWinPriv->hWnd, + GCL_HICON, + (int) hIcon); + + /* Delete the icon if its not the default */ + if (hiconOld != g_hiconX && + !winIconIsOverride((unsigned long)hiconOld)) + DeleteObject (hiconOld); + } + } +} diff --git a/hw/xwin/winwin32rootlesswndproc.c b/hw/xwin/winwin32rootlesswndproc.c new file mode 100755 index 000000000..b52bf7f02 --- /dev/null +++ b/hw/xwin/winwin32rootlesswndproc.c @@ -0,0 +1,908 @@ +/* + *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 + */ +#include "win.h" +#include +#define _WINDOWSWM_SERVER_ +#include "windowswmstr.h" +#include "dixevents.h" +#include "winmultiwindowclass.h" + + +/* + * Constant defines + */ + +#define MOUSE_POLLING_INTERVAL 500 +#define CYGMULTIWINDOW_DEBUG YES + +/* + * Global variables + */ + +extern HICON g_hiconX; +extern Bool g_fNoConfigureWindow; + + +/* + * Local globals + */ + +static UINT_PTR g_uipMousePollingTimerID = 0; + + +/* + * ConstrainSize - Taken from TWM sources - Respects hints for sizing + */ +#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) ) +static void +ConstrainSize (WinXSizeHints hints, int *widthp, int *heightp) +{ + int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta; + int baseWidth, baseHeight; + int dwidth = *widthp, dheight = *heightp; + + if (hints.flags & PMinSize) + { + minWidth = hints.min_width; + minHeight = hints.min_height; + } + else if (hints.flags & PBaseSize) + { + minWidth = hints.base_width; + minHeight = hints.base_height; + } + else + minWidth = minHeight = 1; + + if (hints.flags & PBaseSize) + { + baseWidth = hints.base_width; + baseHeight = hints.base_height; + } + else if (hints.flags & PMinSize) + { + baseWidth = hints.min_width; + baseHeight = hints.min_height; + } + else + baseWidth = baseHeight = 0; + + if (hints.flags & PMaxSize) + { + maxWidth = hints.max_width; + maxHeight = hints.max_height; + } + else + { + maxWidth = MAXINT; + maxHeight = MAXINT; + } + + if (hints.flags & PResizeInc) + { + xinc = hints.width_inc; + yinc = hints.height_inc; + } + else + xinc = yinc = 1; + + /* + * First, clamp to min and max values + */ + if (dwidth < minWidth) + dwidth = minWidth; + if (dheight < minHeight) + dheight = minHeight; + + if (dwidth > maxWidth) + dwidth = maxWidth; + if (dheight > maxHeight) + dheight = maxHeight; + + /* + * Second, fit to base + N * inc + */ + dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth; + dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight; + + /* + * Third, adjust for aspect ratio + */ + + /* + * The math looks like this: + * + * minAspectX dwidth maxAspectX + * ---------- <= ------- <= ---------- + * minAspectY dheight maxAspectY + * + * If that is multiplied out, then the width and height are + * invalid in the following situations: + * + * minAspectX * dheight > minAspectY * dwidth + * maxAspectX * dheight < maxAspectY * dwidth + * + */ + + if (hints.flags & PAspect) + { + if (hints.min_aspect.x * dheight > hints.min_aspect.y * dwidth) + { + delta = makemult(hints.min_aspect.x * dheight / hints.min_aspect.y - dwidth, xinc); + if (dwidth + delta <= maxWidth) + dwidth += delta; + else + { + delta = makemult(dheight - dwidth*hints.min_aspect.y/hints.min_aspect.x, yinc); + if (dheight - delta >= minHeight) + dheight -= delta; + } + } + + if (hints.max_aspect.x * dheight < hints.max_aspect.y * dwidth) + { + delta = makemult(dwidth * hints.max_aspect.y / hints.max_aspect.x - dheight, yinc); + if (dheight + delta <= maxHeight) + dheight += delta; + else + { + delta = makemult(dwidth - hints.max_aspect.x*dheight/hints.max_aspect.y, xinc); + if (dwidth - delta >= minWidth) + dwidth -= delta; + } + } + } + + /* Return computed values */ + *widthp = dwidth; + *heightp = dheight; +} +#undef makemult + + + +/* + * ValidateSizing - Ensures size request respects hints + */ +static int +ValidateSizing (HWND hwnd, WindowPtr pWin, + WPARAM wParam, LPARAM lParam) +{ + WinXSizeHints sizeHints; + RECT *rect; + int iWidth, iHeight, iTopBorder; + POINT pt; + + /* Invalid input checking */ + if (pWin==NULL || lParam==0) + { + ErrorF ("Invalid input checking\n"); + return FALSE; + } + + /* No size hints, no checking */ + if (!winMultiWindowGetWMNormalHints (pWin, &sizeHints)) + { + ErrorF ("No size hints, no checking\n"); + return FALSE; + } + + /* Avoid divide-by-zero */ + if (sizeHints.flags & PResizeInc) + { + if (sizeHints.width_inc == 0) sizeHints.width_inc = 1; + if (sizeHints.height_inc == 0) sizeHints.height_inc = 1; + } + + rect = (RECT*)lParam; + + iWidth = rect->right - rect->left; + iHeight = rect->bottom - rect->top; + + /* Get title bar height, there must be an easier way?! */ + pt.x = pt.y = 0; + ClientToScreen(hwnd, &pt); + iTopBorder = pt.y - rect->top; + + /* Now remove size of any borders */ + iWidth -= 2 * GetSystemMetrics(SM_CXSIZEFRAME); + iHeight -= GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder; + + /* Constrain the size to legal values */ + ConstrainSize (sizeHints, &iWidth, &iHeight); + + /* Add back the borders */ + iWidth += 2 * GetSystemMetrics(SM_CXSIZEFRAME); + iHeight += GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder; + + /* Adjust size according to where we're dragging from */ + switch(wParam) { + case WMSZ_TOP: + case WMSZ_TOPRIGHT: + case WMSZ_BOTTOM: + case WMSZ_BOTTOMRIGHT: + case WMSZ_RIGHT: + rect->right = rect->left + iWidth; + break; + default: + rect->left = rect->right - iWidth; + break; + } + switch(wParam) { + case WMSZ_BOTTOM: + case WMSZ_BOTTOMRIGHT: + case WMSZ_BOTTOMLEFT: + case WMSZ_RIGHT: + case WMSZ_LEFT: + rect->bottom = rect->top + iHeight; + break; + default: + rect->top = rect->bottom - iHeight; + break; + } + return TRUE; +} + + +/* + * winWin32RootlessWindowProc - Window procedure + */ + +LRESULT CALLBACK +winWin32RootlessWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + WindowPtr pWin = NULL; + win32RootlessWindowPtr pRLWinPriv = NULL; + ScreenPtr pScreen = NULL; + winPrivScreenPtr pScreenPriv = NULL; + winScreenInfo *pScreenInfo = NULL; + HWND hwndScreen = NULL; + POINT ptMouse; + static Bool s_fTracking = FALSE; + HDC hdcUpdate; + PAINTSTRUCT ps; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) + { + pWin = pRLWinPriv->pFrame->win; + pScreen = pWin->drawable.pScreen; + if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); + if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; + if (pScreenPriv) hwndScreen = pScreenPriv->hwndScreen; +#if 1 + ErrorF ("hWnd %08X\n", hwnd); + ErrorF ("pScreenPriv %08X\n", pScreenPriv); + ErrorF ("pScreenInfo %08X\n", pScreenInfo); + ErrorF ("hwndScreen %08X\n", hwndScreen); +#endif + ErrorF ("winWin32RootlessWindowProc (%08x) %08x %08x %08x\n", + pRLWinPriv, message, wParam, lParam); + } + /* Branch on message type */ + switch (message) + { + case WM_CREATE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_CREATE\n"); +#endif + /* */ + SetProp (hwnd, + WIN_WINDOW_PROP, + (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams); + return 0; + + case WM_CLOSE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_CLOSE %d\n", pRLWinPriv->fClose); +#endif + /* Tell window-manager to close window */ + if (pRLWinPriv->fClose) + { + DestroyWindow (hwnd); + } + else + { + winWindowsWMSendEvent(WindowsWMControllerNotify, + WindowsWMControllerNotifyMask, + 1, + WindowsWMCloseWindow, + pWin->drawable.id, + 0, 0, 0, 0); + } + return 0; + + case WM_DESTROY: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_DESTROY\n"); +#endif + /* Free the shadow DC; which allows the bitmap to be freed */ + DeleteDC (pRLWinPriv->hdcShadow); + pRLWinPriv->hdcShadow = NULL; + + /* Free the shadow bitmap */ + DeleteObject (pRLWinPriv->hbmpShadow); + pRLWinPriv->hbmpShadow = NULL; + + /* Free the screen DC */ + ReleaseDC (pRLWinPriv->hWnd, pRLWinPriv->hdcScreen); + pRLWinPriv->hdcScreen = NULL; + + pRLWinPriv->fResized = FALSE; + pRLWinPriv->pfb = NULL; + free (pRLWinPriv); + SetProp (hwnd, WIN_WINDOW_PROP, (HANDLE)NULL); + break; + + case WM_MOUSEMOVE: +#if CYGMULTIWINDOW_DEBUG && 0 + ErrorF ("winWin32RootlessWindowProc - 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); + + /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */ + ptMouse.x -= GetSystemMetrics (SM_XVIRTUALSCREEN); + ptMouse.y -= GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* We can't do anything without privates */ + if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + + /* Has the mouse pointer crossed screens? */ + if (pScreen != miPointerCurrentScreen ()) + miPointerSetNewScreen (pScreenInfo->dwScreen, + ptMouse.x - pScreenInfo->dwXOffset, + ptMouse.y - 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 ("winWin32RootlessWindowProc - _TrackMouseEvent failed\n"); + + /* Flag that we are tracking now */ + s_fTracking = TRUE; + } + + /* Kill the timer used to poll mouse events */ + if (g_uipMousePollingTimerID != 0) + { + KillTimer (pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID); + g_uipMousePollingTimerID = 0; + } + + /* Deliver absolute cursor position to X Server */ + miPointerAbsoluteCursor (ptMouse.x - pScreenInfo->dwXOffset, + ptMouse.y - pScreenInfo->dwYOffset, + g_c32LastInputEventTime = GetTickCount ()); + return 0; + + case WM_NCMOUSEMOVE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_NCMOUSEMOVE\n"); +#endif + /* + * 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 (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + + /* + * Timer to poll mouse events. This is needed to make + * programs like xeyes follow the mouse properly. + */ + if (g_uipMousePollingTimerID == 0) + g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen, + WIN_POLLING_MOUSE_TIMER_ID, + MOUSE_POLLING_INTERVAL, + NULL); + break; + + case WM_MOUSELEAVE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_MOUSELEAVE\n"); +#endif + /* Mouse has left our client area */ + + /* Flag that we are no longer tracking */ + s_fTracking = FALSE; + + /* + * Timer to poll mouse events. This is needed to make + * programs like xeyes follow the mouse properly. + */ + if (g_uipMousePollingTimerID == 0) + g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen, + WIN_POLLING_MOUSE_TIMER_ID, + MOUSE_POLLING_INTERVAL, + NULL); + return 0; + + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_LBUTTONDBLCLK\n"); +#endif + if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + SetCapture (hwnd); + return winMouseButtonsHandle (pScreen, ButtonPress, Button1, wParam); + + case WM_LBUTTONUP: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_LBUTTONUP\n"); +#endif + if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + ReleaseCapture (); + return winMouseButtonsHandle (pScreen, ButtonRelease, Button1, wParam); + + case WM_MBUTTONDBLCLK: + case WM_MBUTTONDOWN: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_MBUTTONDBLCLK\n"); +#endif + if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + SetCapture (hwnd); + return winMouseButtonsHandle (pScreen, ButtonPress, Button2, wParam); + + case WM_MBUTTONUP: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_MBUTTONUP\n"); +#endif + if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + ReleaseCapture (); + return winMouseButtonsHandle (pScreen, ButtonRelease, Button2, wParam); + + case WM_RBUTTONDBLCLK: + case WM_RBUTTONDOWN: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_RBUTTONDBLCLK\n"); +#endif + if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + SetCapture (hwnd); + return winMouseButtonsHandle (pScreen, ButtonPress, Button3, wParam); + + case WM_RBUTTONUP: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_RBUTTONUP\n"); +#endif + if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + ReleaseCapture (); + return winMouseButtonsHandle (pScreen, ButtonRelease, Button3, wParam); + + case WM_MOUSEWHEEL: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_MOUSEWHEEL\n"); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_MOUSEACTIVATE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_MOUSEACTIVATE\n"); +#endif +#if 0 + /* Check if this window needs to be made active when clicked */ + if (pWin->overrideRedirect) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_MOUSEACTIVATE - " + "MA_NOACTIVATE\n"); +#endif + + /* */ + return MA_NOACTIVATE; + } +#endif + break; + + case WM_KILLFOCUS: + /* Pop any pressed keys since we are losing keyboard focus */ + winKeybdReleaseKeys (); + return 0; + + case WM_SYSDEADCHAR: + case WM_DEADCHAR: + /* + * NOTE: We do nothing with WM_*CHAR messages, + * nor does the root window, so we can just toss these messages. + */ + return 0; + + case WM_SYSKEYDOWN: + case WM_KEYDOWN: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_*KEYDOWN\n"); +#endif + + /* + * Don't pass Alt-F4 key combo to root window, + * let Windows translate to WM_CLOSE and close this top-level window. + * + * NOTE: We purposely don't check the fUseWinKillKey setting because + * it should only apply to the key handling for the root window, + * not for top-level window-manager windows. + * + * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window + * because that is a key combo that no X app should be expecting to + * receive, since it has historically been used to shutdown the X server. + * Passing Ctrl-Alt-Backspace to the root window preserves that + * behavior, assuming that -unixkill has been passed as a parameter. + */ + if (wParam == VK_F4 && (GetKeyState (VK_MENU) & 0x8000)) + break; + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_SYSKEYUP: + case WM_KEYUP: + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_*KEYUP\n"); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_HOTKEY: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_HOTKEY\n"); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_PAINT: + + /* BeginPaint gives us an hdc that clips to the invalidated region */ + hdcUpdate = BeginPaint (hwnd, &ps); + + /* Try to copy from the shadow buffer */ + if (!BitBlt (hdcUpdate, + ps.rcPaint.left, ps.rcPaint.top, + ps.rcPaint.right - ps.rcPaint.left, + ps.rcPaint.bottom - ps.rcPaint.top, + pRLWinPriv->hdcShadow, + ps.rcPaint.left, ps.rcPaint.top, + 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), + (LPTSTR) &lpMsgBuf, + 0, NULL); + + ErrorF ("winWin32RootlessWindowProc - BitBlt failed: %s\n", + (LPSTR)lpMsgBuf); + LocalFree (lpMsgBuf); + } + + /* EndPaint frees the DC */ + EndPaint (hwnd, &ps); + break; + + case WM_ACTIVATE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_ACTIVATE\n"); +#endif + if (LOWORD(wParam) != WA_INACTIVE) + { + winWindowsWMSendEvent(WindowsWMControllerNotify, + WindowsWMControllerNotifyMask, + 1, + WindowsWMActivateWindow, + pWin->drawable.id, + 0, 0, + 0, 0); + } + return 0; + +#if 0 + case WM_WINDOWPOSCHANGING: + pWinPos = (LPWINDOWPOS)lParam; + /* Window manager does restacking */ + if (!(pWinPos->flags & SWP_NOZORDER)) + { + if (pRLWinPriv->fRestackingNow) + { + ErrorF ("Win %08x is now restacking.\n", pRLWinPriv); + return 0; + } + + //if (pRLWinPriv->fXTop) + if (pScreenPriv->widTop == pRLWinPriv) + { +#if 0 + if ((pWinPos->hwndInsertAfter == HWND_TOP)|| + (pWinPos->hwndInsertAfter == HWND_TOPMOST)|| + (pWinPos->hwndInsertAfter == HWND_NOTOPMOST)) + { + ErrorF ("Win %08x is top and become top/topmost/notopmost.\n", pRLWinPriv); + return 0; + } + + for (hInsWnd = GetNextWindow (hwnd, GW_HWNDPREV); + hInsWnd; hInsWnd = GetNextWindow (hInsWnd, GW_HWNDPREV)) + { + if (hInsWnd == pWinPos->hwndInsertAfter) + { + ErrorF ("Win %08x is top and go above.\n", + pRLWinPriv); + return 0; + } + hInsWnd = GetNextWindow (hInsWnd, GW_HWNDPREV); + } + ErrorF ("Win %08x is top but forbid.\n", pRLWinPriv); +#endif + return 0; + } + ErrorF ("Win %08x forbid to change z order (%08x).\n", + pRLWinPriv, pWinPos->hwndInsertAfter); + pWinPos->flags |= SWP_NOZORDER; + } + break; +#endif + + case WM_MOVE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_MOVE - %d ms\n", GetTickCount ()); +#endif + if (g_fNoConfigureWindow) break; +#if 0 + /* Bail if Windows window is not actually moving */ + if (pRLWinPriv->dwX == (short) LOWORD(lParam) + && pRLWinPriv->dwY == (short) HIWORD(lParam)) + break; + + /* Also bail if we're maximizing, we'll do the whole thing in WM_SIZE */ + { + WINDOWPLACEMENT windPlace; + windPlace.length = sizeof (WINDOWPLACEMENT); + + /* Get current window placement */ + GetWindowPlacement (hwnd, &windPlace); + + /* Bail if maximizing */ + if (windPlace.showCmd == SW_MAXIMIZE + || windPlace.showCmd == SW_SHOWMAXIMIZED) + break; + } +#endif + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\t(%d, %d)\n", (short) LOWORD(lParam), (short) HIWORD(lParam)); +#endif +#if 0 + winWindowsWMSendEvent(WindowsWMControllerNotify, + WindowsWMControllerNotifyMask, + 1, + WindowsWMMoveWindow, + pWin->drawable.id, + (LOWORD(lParam) - wBorderWidth (pWin) - GetSystemMetrics (SM_XVIRTUALSCREEN)), + (HIWORD(lParam) - wBorderWidth (pWin) - GetSystemMetrics (SM_YVIRTUALSCREEN)), + 0, 0); +#else + winWin32RootlessMoveXWindow (pWin, + (LOWORD(lParam) - wBorderWidth (pWin) + - GetSystemMetrics (SM_XVIRTUALSCREEN)), + (HIWORD(lParam) - wBorderWidth (pWin) + - GetSystemMetrics (SM_YVIRTUALSCREEN))); +#endif + return 0; + + case WM_SHOWWINDOW: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_SHOWWINDOW - %d ms\n", GetTickCount ()); +#endif + /* Bail out if the window is being hidden */ + if (!wParam) + return 0; + + /* Tell X to map the window */ + MapWindow (pWin, wClient(pWin)); + + if (pScreenPriv != NULL) + pScreenPriv->fWindowOrderChanged = TRUE; + return 0; + + case WM_SIZING: + /* Need to legalize the size according to WM_NORMAL_HINTS */ + /* for applications like xterm */ + return ValidateSizing (hwnd, pWin, wParam, lParam); + + case WM_WINDOWPOSCHANGED: + { + LPWINDOWPOS pwindPos = (LPWINDOWPOS) lParam; + + /* Bail if window z order was not changed */ + if (pwindPos->flags & SWP_NOZORDER) + break; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - hwndInsertAfter: %p\n", + pwindPos->hwndInsertAfter); +#endif + + if (pScreenPriv != NULL) + pScreenPriv->fWindowOrderChanged = TRUE; + } + return 0; + + case WM_SIZE: + /* see dix/window.c */ + /* FIXME: Maximize/Restore? */ +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWin32RootlessWindowProc - WM_SIZE - %d ms\n", GetTickCount ()); +#endif +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\t(%d, %d) %d\n", (short) LOWORD(lParam), (short) HIWORD(lParam), g_fNoConfigureWindow); +#endif + if (g_fNoConfigureWindow) break; + + if (pScreenPriv != NULL) + pScreenPriv->fWindowOrderChanged = TRUE; + + /* Branch on type of resizing occurring */ + switch (wParam) + { + case SIZE_MINIMIZED: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tSIZE_MINIMIZED\n"); +#endif + winWindowsWMSendEvent(WindowsWMControllerNotify, + WindowsWMControllerNotifyMask, + 1, + WindowsWMMinimizeWindow, + pWin->drawable.id, + 0, 0, + LOWORD(lParam), HIWORD(lParam)); + break; + + case SIZE_RESTORED: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tSIZE_MINIMIZED\n"); +#endif + winWindowsWMSendEvent(WindowsWMControllerNotify, + WindowsWMControllerNotifyMask, + 1, + WindowsWMRestoreWindow, + pWin->drawable.id, + 0, 0, + LOWORD(lParam), HIWORD(lParam)); + break; + + case SIZE_MAXIMIZED: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tSIZE_MAXIMIZED\n"); +#endif + winWindowsWMSendEvent(WindowsWMControllerNotify, + WindowsWMControllerNotifyMask, + 1, + WindowsWMMaximizeWindow, + pWin->drawable.id, + 0, 0, + LOWORD(lParam), HIWORD(lParam)); + break; + } + + /* Perform the resize and notify the X client */ +#if 0 + winWindowsWMSendEvent(WindowsWMControllerNotify, + WindowsWMControllerNotifyMask, + 1, + WindowsWMResizeWindow, + pWin->drawable.id, + 0, 0, + LOWORD(lParam), HIWORD(lParam)); +#else + winWin32RootlessResizeXWindow (pWin, + (short) LOWORD(lParam), + (short) HIWORD(lParam)); +#endif + break; + + case WM_ACTIVATEAPP: + if (wParam) + { + winWindowsWMSendEvent(WindowsWMActivationNotify, + WindowsWMActivationNotifyMask, + 1, + WindowsWMIsActive, + pWin->drawable.id, + 0, 0, + 0, 0); + } + else + { + winWindowsWMSendEvent(WindowsWMActivationNotify, + WindowsWMActivationNotifyMask, + 1, + WindowsWMIsInactive, + pWin->drawable.id, + 0, 0, + 0, 0); + } + break; + + case WM_SETCURSOR: + if (LOWORD(lParam) == HTCLIENT) + { + SetCursor (pScreenPriv->hCursor); + return TRUE; + } + break; + + default: + break; + } + + return DefWindowProc (hwnd, message, wParam, lParam); +} diff --git a/hw/xwin/winwindowswm.c b/hw/xwin/winwindowswm.c new file mode 100755 index 000000000..224a71409 --- /dev/null +++ b/hw/xwin/winwindowswm.c @@ -0,0 +1,623 @@ +/* WindowsWM extension is based on AppleWM extension */ +/************************************************************************** + +Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved. +Copyright (c) 2003 Torrey T. Lyons. 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, sub license, 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 (including the +next paragraph) 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 NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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. + +**************************************************************************/ + +#include "win.h" + +#define NEED_REPLIES +#define NEED_EVENTS +#include "misc.h" +#include "dixstruct.h" +#include "extnsionst.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "scrnintstr.h" +#include "servermd.h" +#include "swaprep.h" +#define _WINDOWSWM_SERVER_ +#include "windowswmstr.h" + +static int WMErrorBase; + +static DISPATCH_PROC(ProcWindowsWMDispatch); +static DISPATCH_PROC(SProcWindowsWMDispatch); + +static void WindowsWMResetProc(ExtensionEntry* extEntry); + +static unsigned char WMReqCode = 0; +static int WMEventBase = 0; + +static RESTYPE ClientType, EventType; /* resource types for event masks */ +static XID eventResource; + +/* Currently selected events */ +static unsigned int eventMask = 0; + +static int WMFreeClient (pointer data, XID id); +static int WMFreeEvents (pointer data, XID id); +static void SNotifyEvent(xWindowsWMNotifyEvent *from, xWindowsWMNotifyEvent *to); + +typedef struct _WMEvent *WMEventPtr; +typedef struct _WMEvent { + WMEventPtr next; + ClientPtr client; + XID clientResource; + unsigned int mask; +} WMEventRec; + +static inline BoxRec +make_box (int x, int y, int w, int h) +{ + BoxRec r; + r.x1 = x; + r.y1 = y; + r.x2 = x + w; + r.y2 = y + h; + return r; +} + +void +winWindowsWMExtensionInit () +{ + ExtensionEntry* extEntry; + + ClientType = CreateNewResourceType(WMFreeClient); + EventType = CreateNewResourceType(WMFreeEvents); + eventResource = FakeClientID(0); + + if (ClientType && EventType && + (extEntry = AddExtension(WINDOWSWMNAME, + WindowsWMNumberEvents, + WindowsWMNumberErrors, + ProcWindowsWMDispatch, + SProcWindowsWMDispatch, + WindowsWMResetProc, + StandardMinorOpcode))) + { + WMReqCode = (unsigned char)extEntry->base; + WMErrorBase = extEntry->errorBase; + WMEventBase = extEntry->eventBase; + EventSwapVector[WMEventBase] = (EventSwapPtr) SNotifyEvent; + } +} + +/*ARGSUSED*/ +static void +WindowsWMResetProc (ExtensionEntry* extEntry) +{ +} + +static int +ProcWindowsWMQueryVersion(register ClientPtr client) +{ + xWindowsWMQueryVersionReply rep; + register int n; + + REQUEST_SIZE_MATCH(xWindowsWMQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = WINDOWS_WM_MAJOR_VERSION; + rep.minorVersion = WINDOWS_WM_MINOR_VERSION; + rep.patchVersion = WINDOWS_WM_PATCH_VERSION; + if (client->swapped) + { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + } + WriteToClient(client, sizeof(xWindowsWMQueryVersionReply), (char *)&rep); + return (client->noClientException); +} + + +/* events */ + +static inline void +updateEventMask (WMEventPtr *pHead) +{ + WMEventPtr pCur; + + eventMask = 0; + for (pCur = *pHead; pCur != NULL; pCur = pCur->next) + eventMask |= pCur->mask; +} + +/*ARGSUSED*/ +static int +WMFreeClient (pointer data, XID id) +{ + WMEventPtr pEvent; + WMEventPtr *pHead, pCur, pPrev; + + pEvent = (WMEventPtr) data; + pHead = (WMEventPtr *) LookupIDByType(eventResource, EventType); + if (pHead) + { + pPrev = 0; + for (pCur = *pHead; pCur && pCur != pEvent; pCur=pCur->next) + pPrev = pCur; + if (pCur) + { + if (pPrev) + pPrev->next = pEvent->next; + else + *pHead = pEvent->next; + } + updateEventMask (pHead); + } + xfree ((pointer) pEvent); + return 1; +} + +/*ARGSUSED*/ +static int +WMFreeEvents (pointer data, XID id) +{ + WMEventPtr *pHead, pCur, pNext; + + pHead = (WMEventPtr *) data; + for (pCur = *pHead; pCur; pCur = pNext) + { + pNext = pCur->next; + FreeResource (pCur->clientResource, ClientType); + xfree ((pointer) pCur); + } + xfree ((pointer) pHead); + eventMask = 0; + return 1; +} + +static int +ProcWindowsWMSelectInput (register ClientPtr client) +{ + REQUEST(xWindowsWMSelectInputReq); + WMEventPtr pEvent, pNewEvent, *pHead; + XID clientResource; + + REQUEST_SIZE_MATCH (xWindowsWMSelectInputReq); + pHead = (WMEventPtr *)SecurityLookupIDByType(client, eventResource, + EventType, SecurityWriteAccess); + if (stuff->mask != 0) + { + if (pHead) + { + /* check for existing entry. */ + for (pEvent = *pHead; pEvent; pEvent = pEvent->next) + { + if (pEvent->client == client) + { + pEvent->mask = stuff->mask; + updateEventMask (pHead); + return Success; + } + } + } + + /* build the entry */ + pNewEvent = (WMEventPtr) xalloc (sizeof (WMEventRec)); + if (!pNewEvent) + return BadAlloc; + pNewEvent->next = 0; + pNewEvent->client = client; + pNewEvent->mask = stuff->mask; + /* + * add a resource that will be deleted when + * the client goes away + */ + clientResource = FakeClientID (client->index); + pNewEvent->clientResource = clientResource; + if (!AddResource (clientResource, ClientType, (pointer)pNewEvent)) + return BadAlloc; + /* + * create a resource to contain a pointer to the list + * of clients selecting input. This must be indirect as + * the list may be arbitrarily rearranged which cannot be + * done through the resource database. + */ + if (!pHead) + { + pHead = (WMEventPtr *) xalloc (sizeof (WMEventPtr)); + if (!pHead || + !AddResource (eventResource, EventType, (pointer)pHead)) + { + FreeResource (clientResource, RT_NONE); + return BadAlloc; + } + *pHead = 0; + } + pNewEvent->next = *pHead; + *pHead = pNewEvent; + updateEventMask (pHead); + } + else if (stuff->mask == 0) + { + /* delete the interest */ + if (pHead) + { + pNewEvent = 0; + for (pEvent = *pHead; pEvent; pEvent = pEvent->next) + { + if (pEvent->client == client) + break; + pNewEvent = pEvent; + } + if (pEvent) + { + FreeResource (pEvent->clientResource, ClientType); + if (pNewEvent) + pNewEvent->next = pEvent->next; + else + *pHead = pEvent->next; + xfree (pEvent); + updateEventMask (pHead); + } + } + } + else + { + client->errorValue = stuff->mask; + return BadValue; + } + return Success; +} + +/* + * deliver the event + */ + +void +winWindowsWMSendEvent (int type, unsigned int mask, int which, int arg, + Window window, int x, int y, int w, int h) +{ + WMEventPtr *pHead, pEvent; + ClientPtr client; + xWindowsWMNotifyEvent se; + + ErrorF ("winWindowsWMSendEvent %d %d %d %d, %d %d - %d %d\n", + type, mask, which, arg, x, y, w, h); + pHead = (WMEventPtr *) LookupIDByType(eventResource, EventType); + if (!pHead) + return; + for (pEvent = *pHead; pEvent; pEvent = pEvent->next) + { + client = pEvent->client; + ErrorF ("winWindowsWMSendEvent - x%08x\n", (int) client); + if ((pEvent->mask & mask) == 0 + || client == serverClient || client->clientGone) + { + continue; + } + ErrorF ("winWindowsWMSendEvent - send\n"); + se.type = type + WMEventBase; + se.kind = which; + se.window = window; + se.arg = arg; + se.x = x; + se.y = y; + se.w = w; + se.h = h; + se.sequenceNumber = client->sequence; + se.time = currentTime.milliseconds; + WriteEventsToClient (client, 1, (xEvent *) &se); + } +} + +/* Safe to call from any thread. */ +unsigned int +WindowsWMSelectedEvents (void) +{ + return eventMask; +} + + +/* general utility functions */ + +static int +ProcWindowsWMDisableUpdate (register ClientPtr client) +{ + REQUEST_SIZE_MATCH(xWindowsWMDisableUpdateReq); + + //winDisableUpdate(); + + return (client->noClientException); +} + +static int +ProcWindowsWMReenableUpdate (register ClientPtr client) +{ + REQUEST_SIZE_MATCH(xWindowsWMReenableUpdateReq); + + //winEnableUpdate(); + + return (client->noClientException); +} + + +/* window functions */ + +static int +ProcWindowsWMSetFrontProcess (register ClientPtr client) +{ + REQUEST_SIZE_MATCH(xWindowsWMSetFrontProcessReq); + + //QuartzMessageMainThread(kWindowsSetFrontProcess, NULL, 0); + + return (client->noClientException); +} + + +/* frame functions */ + +static int +ProcWindowsWMFrameGetRect (register ClientPtr client) +{ + xWindowsWMFrameGetRectReply rep; + BoxRec ir; + RECT rcNew; + REQUEST(xWindowsWMFrameGetRectReq); + + ErrorF ("ProcWindowsWMFrameGetRect %d %d\n", + (sizeof(xWindowsWMFrameGetRectReq) >> 2), (int) client->req_len); + + REQUEST_SIZE_MATCH(xWindowsWMFrameGetRectReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih); + + if (stuff->frame_rect != 0) + { + ErrorF ("ProcWindowsWMFrameGetRect - stuff->frame_rect != 0\n"); + return BadValue; + } + + /* Store the origin, height, and width in a rectangle structure */ + SetRect (&rcNew, stuff->ix, stuff->iy, + stuff->ix + stuff->iw, stuff->iy + stuff->ih); + + ErrorF ("ProcWindowsWMFrameGetRect - %d %d %d %d\n", + stuff->ix, stuff->iy, stuff->ix + stuff->iw, stuff->iy + stuff->ih); + /* + * Calculate the required size of the Windows window rectangle, + * given the size of the Windows window client area. + */ + AdjustWindowRectEx (&rcNew, stuff->frame_style, FALSE, stuff->frame_style_ex); + rep.x = rcNew.left; + rep.y = rcNew.top; + rep.w = rcNew.right - rcNew.left; + rep.h = rcNew.bottom - rcNew.top; + ErrorF ("ProcWindowsWMFrameGetRect - %d %d %d %d\n", + rep.x, rep.y, rep.w, rep.h); + + WriteToClient(client, sizeof(xWindowsWMFrameGetRectReply), (char *)&rep); + return (client->noClientException); +} + + +static int +ProcWindowsWMFrameDraw (register ClientPtr client) +{ + BoxRec ir; + REQUEST(xWindowsWMFrameDrawReq); + WindowPtr pWin; + win32RootlessWindowPtr pRLWinPriv; + RECT rcNew; + WINDOWPLACEMENT wndpl; + + REQUEST_SIZE_MATCH (xWindowsWMFrameDrawReq); + + ErrorF ("ProcWindowsWMFrameDraw\n"); + if (!(pWin = SecurityLookupWindow((Drawable)stuff->window, + client, SecurityReadAccess))) + { + return BadValue; + } + ErrorF ("ProcWindowsWMFrameDraw - Window found\n"); + + ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih); + + pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, TRUE); + if (pRLWinPriv == 0) return BadWindow; + + ErrorF ("ProcWindowsWMFrameDraw - HWND 0x%08x 0x%08x 0x%08x", + (int) pRLWinPriv->hWnd, (int) stuff->frame_style, + (int) stuff->frame_style_ex); + ErrorF ("ProcWindowsWMFrameDraw - %d %d %d %d\n", + stuff->ix, stuff->iy, stuff->iw, stuff->ih); + + GetWindowPlacement (pRLWinPriv->hWnd, &wndpl); + + /* Store the origin, height, and width in a rectangle structure */ + SetRect (&rcNew, stuff->ix, stuff->iy, + stuff->ix + stuff->iw, stuff->iy + stuff->ih); + + /* + * Calculate the required size of the Windows window rectangle, + * given the size of the Windows window client area. + */ + AdjustWindowRectEx (&rcNew, stuff->frame_style, FALSE, stuff->frame_style_ex); + + /* Set the window extended style flags */ + if (!SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, stuff->frame_style_ex)) + { + return BadValue; + } + + /* Set the window standard style flags */ + if (!SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, stuff->frame_style)) + { + return BadValue; + } + + /* Flush the window style */ + if (!SetWindowPos (pRLWinPriv->hWnd, NULL, + 0, 0, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED + /* | SWP_SHOWWINDOW*/ | SWP_NOACTIVATE)) + { + return BadValue; + } + + ShowWindow (pRLWinPriv->hWnd, wndpl.showCmd); + + winWin32RootlessUpdateIcon (pWin->drawable.id); + + ErrorF ("ProcWindowsWMFrameDraw - done\n"); + + return (client->noClientException); +} + +static int +ProcWindowsWMFrameSetTitle( + register ClientPtr client + ) +{ + unsigned int title_length, title_max; + unsigned char *title_bytes; + REQUEST(xWindowsWMFrameSetTitleReq); + WindowPtr pWin; + win32RootlessWindowPtr pRLWinPriv; + + ErrorF ("ProcWindowsWMFrameSetTitle\n"); + + REQUEST_AT_LEAST_SIZE(xWindowsWMFrameSetTitleReq); + + if (!(pWin = SecurityLookupWindow((Drawable)stuff->window, + client, SecurityReadAccess))) + { + return BadValue; + } + ErrorF ("ProcWindowsWMFrameSetTitle - Window found\n"); + + title_length = stuff->title_length; + title_max = (stuff->length << 2) - sizeof(xWindowsWMFrameSetTitleReq); + + if (title_max < title_length) + return BadValue; + + ErrorF ("ProcWindowsWMFrameSetTitle - length is valid\n"); + + title_bytes = malloc (title_length+1); + strncpy (title_bytes, (unsigned char *) &stuff[1], title_length); + title_bytes[title_length] = '\0'; + + pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); + + if (pRLWinPriv == 0) + { + free (title_bytes); + return BadWindow; + } + + /* Flush the window style */ + SetWindowText (pRLWinPriv->hWnd, title_bytes); + + free (title_bytes); + + ErrorF ("ProcWindowsWMFrameSetTitle - done\n"); + + return (client->noClientException); +} + + +/* dispatch */ + +static int +ProcWindowsWMDispatch (register ClientPtr client) +{ + REQUEST(xReq); + + switch (stuff->data) + { + case X_WindowsWMQueryVersion: + return ProcWindowsWMQueryVersion(client); + } + + if (!LocalClient(client)) + return WMErrorBase + WindowsWMClientNotLocal; + + switch (stuff->data) + { + case X_WindowsWMSelectInput: + return ProcWindowsWMSelectInput(client); + case X_WindowsWMDisableUpdate: + return ProcWindowsWMDisableUpdate(client); + case X_WindowsWMReenableUpdate: + return ProcWindowsWMReenableUpdate(client); + case X_WindowsWMSetFrontProcess: + return ProcWindowsWMSetFrontProcess(client); + case X_WindowsWMFrameGetRect: + return ProcWindowsWMFrameGetRect(client); + case X_WindowsWMFrameDraw: + return ProcWindowsWMFrameDraw(client); + case X_WindowsWMFrameSetTitle: + return ProcWindowsWMFrameSetTitle(client); + default: + return BadRequest; + } +} + +static void +SNotifyEvent (xWindowsWMNotifyEvent *from, xWindowsWMNotifyEvent *to) +{ + to->type = from->type; + to->kind = from->kind; + cpswaps (from->sequenceNumber, to->sequenceNumber); + cpswapl (from->window, to->window); + cpswapl (from->time, to->time); + cpswapl (from->arg, to->arg); +} + +static int +SProcWindowsWMQueryVersion (register ClientPtr client) +{ + register int n; + REQUEST(xWindowsWMQueryVersionReq); + swaps(&stuff->length, n); + return ProcWindowsWMQueryVersion(client); +} + +static int +SProcWindowsWMDispatch (register ClientPtr client) +{ + REQUEST(xReq); + + /* It is bound to be non-local when there is byte swapping */ + if (!LocalClient(client)) + return WMErrorBase + WindowsWMClientNotLocal; + + /* only local clients are allowed WM access */ + switch (stuff->data) + { + case X_WindowsWMQueryVersion: + return SProcWindowsWMQueryVersion(client); + default: + return BadRequest; + } +} diff --git a/miext/rootless/rootlessConfig.h b/miext/rootless/rootlessConfig.h index 1a1a48a4a..9743a9a3d 100644 --- a/miext/rootless/rootlessConfig.h +++ b/miext/rootless/rootlessConfig.h @@ -47,4 +47,18 @@ #endif /* __DARWIN__ */ +#ifdef __CYGWIN__ + +# define ROOTLESS_ACCEL YES +# define ROOTLESS_GLOBAL_COORDS TRUE +# define ROOTLESS_PROTECT_ALPHA NO +# define ROOTLESS_REDISPLAY_DELAY 10 +# define ROOTLESS_RESIZE_GRAVITY TRUE +# undef ROOTLESS_TRACK_DAMAGE +/*# define ROOTLESSDEBUG*/ + +# define RootlessAlphaMask(bpp) ((bpp) == 32 ? 0xFF000000 : 0) + +#endif /* __CYGWIN__ */ + #endif /* _ROOTLESSCONFIG_H */