From 19e764eee0c8b74d877fb2b1d6aedc933976660e Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Wed, 21 Jul 2010 18:11:13 +0100 Subject: [PATCH 1/7] Cygwin/X: Internal WM workaround for Java AWT bug Java applications using AWT on JRE 1.6.0 break with non-reparenting WMs AWT doesn't explicitly know about (See sun bug #6434227) XDecoratedPeer.handleConfigureNotifyEvent() only processes non-synthetic ConfigureNotify events to update window location if it's identified the WM as a non-reparenting WM it knows about (compiz or lookingglass) Rather than tell all sorts of lies to get XWM to recognize us as one of those, simply send a synthetic ConfigureNotify for every non-synthetic one Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/winmultiwindowwm.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c index c9b1584f8..ef0c7cf0b 100644 --- a/hw/xwin/winmultiwindowwm.c +++ b/hw/xwin/winmultiwindowwm.c @@ -1114,6 +1114,30 @@ winMultiWindowXMsgProc (void *pArg) } } } + else if (event.type == ConfigureNotify) + { + if (!event.xconfigure.send_event) + { + /* + Java applications using AWT on JRE 1.6.0 break with non-reparenting WMs AWT + doesn't explicitly know about (See sun bug #6434227) + + XDecoratedPeer.handleConfigureNotifyEvent() only processes non-synthetic + ConfigureNotify events to update window location if it's identified the + WM as a non-reparenting WM it knows about (compiz or lookingglass) + + Rather than tell all sorts of lies to get XWM to recognize us as one of + those, simply send a synthetic ConfigureNotify for every non-synthetic one + */ + XEvent event_send = event; + event_send.xconfigure.send_event = TRUE; + event_send.xconfigure.event = event.xconfigure.window; + XSendEvent(event.xconfigure.display, + event.xconfigure.window, + True, StructureNotifyMask, + &event_send); + } + } else if (event.type == PropertyNotify && event.xproperty.atom == atmWmName) { From bd288c3458bc1ba2cbb4c8416e5b2dfd849581e6 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Thu, 22 Jul 2010 18:36:51 +0100 Subject: [PATCH 2/7] Cygwin/X: Fix a GDI bitmap resource leak of window icons Ensure any icon created specially for a window is destroyed when the window is destroyed Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/winmultiwindowicons.c | 3 ++- hw/xwin/winmultiwindowwindow.c | 13 ++++++++++++- hw/xwin/winwin32rootless.c | 22 +++++++++++----------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/hw/xwin/winmultiwindowicons.c b/hw/xwin/winmultiwindowicons.c index 1ca3f9141..44956e389 100644 --- a/hw/xwin/winmultiwindowicons.c +++ b/hw/xwin/winmultiwindowicons.c @@ -624,6 +624,7 @@ void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon) *pIcon = hIcon; else winDestroyIcon(hIcon); + if (pSmallIcon) *pSmallIcon = hSmallIcon; else @@ -632,7 +633,7 @@ void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon) void winDestroyIcon(HICON hIcon) { - /* Delete the icon if its not the default */ + /* Delete the icon if its not one of the application defaults or an override */ if (hIcon && hIcon != g_hIconX && hIcon != g_hSmallIconX && diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c index 7efc360a4..61305e19d 100644 --- a/hw/xwin/winmultiwindowwindow.c +++ b/hw/xwin/winmultiwindowwindow.c @@ -592,7 +592,9 @@ winDestroyWindowsWindow (WindowPtr pWin) MSG msg; winWindowPriv(pWin); BOOL oldstate = winInDestroyWindowsWindow; - + HICON hIcon; + HICON hIconSm; + #if CYGMULTIWINDOW_DEBUG ErrorF ("winDestroyWindowsWindow\n"); #endif @@ -603,13 +605,22 @@ winDestroyWindowsWindow (WindowPtr pWin) winInDestroyWindowsWindow = TRUE; + /* Store the info we need to destroy after this window is gone */ + hIcon = (HICON)SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_BIG, 0); + hIconSm = (HICON)SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_SMALL, 0); + SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, NULL); + /* Destroy the Windows window */ DestroyWindow (pWinPriv->hWnd); /* Null our handle to the Window so referencing it will cause an error */ pWinPriv->hWnd = NULL; + /* Destroy any icons we created for this window */ + winDestroyIcon(hIcon); + winDestroyIcon(hIconSm); + /* Process all messages on our queue */ while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c index 75142f15b..8f9917a7b 100644 --- a/hw/xwin/winwin32rootless.c +++ b/hw/xwin/winwin32rootless.c @@ -366,8 +366,8 @@ void winMWExtWMDestroyFrame (RootlessFrameID wid) { win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; - HICON hiconClass; - HICON hiconSmClass; + HICON hIcon; + HICON hIconSm; HMODULE hInstance; int iReturn; char pszClass[CLASS_NAME_LENGTH]; @@ -398,8 +398,8 @@ winMWExtWMDestroyFrame (RootlessFrameID wid) /* Store the info we need to destroy after this window is gone */ hInstance = (HINSTANCE) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HMODULE); - hiconClass = (HICON) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HICON); - hiconSmClass = (HICON) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HICONSM); + hIcon = (HICON)SendMessage(pRLWinPriv->hWnd, WM_GETICON, ICON_BIG, 0); + hIconSm = (HICON)SendMessage(pRLWinPriv->hWnd, WM_GETICON, ICON_SMALL, 0); iReturn = GetClassName (pRLWinPriv->hWnd, pszClass, CLASS_NAME_LENGTH); pRLWinPriv->fClose = TRUE; @@ -415,15 +415,15 @@ winMWExtWMDestroyFrame (RootlessFrameID wid) winDebug ("winMWExtWMDestroyFrame - Unregistering %s: ", pszClass); #endif iReturn = UnregisterClass (pszClass, hInstance); - -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMDestroyFramew - %d Deleting Icon: ", iReturn); -#endif - - winDestroyIcon(hiconClass); - winDestroyIcon(hiconSmClass); } +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMDestroyFramew - Deleting Icon\n"); +#endif + + winDestroyIcon(hIcon); + winDestroyIcon(hIconSm); + #if CYGMULTIWINDOW_DEBUG winDebug ("winMWExtWMDestroyFrame - done\n"); #endif From 38a1f5c613a48ef9fd6ba043bc3028f487750d3a Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 12 Oct 2010 17:12:02 +0100 Subject: [PATCH 3/7] Cygwin/X: Don't make InputOnly windows visible Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/winmultiwindowwindow.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c index 61305e19d..21b818b89 100644 --- a/hw/xwin/winmultiwindowwindow.c +++ b/hw/xwin/winmultiwindowwindow.c @@ -506,12 +506,16 @@ winCreateWindowsWindow (WindowPtr pWin) iWidth = pWin->drawable.width; iHeight = pWin->drawable.height; - /* ensure window actually ends up somewhere visible */ - if (iX > GetSystemMetrics (SM_CXVIRTUALSCREEN)) - iX = CW_USEDEFAULT; + /* If it's an InputOutput window, and so is going to end up being made visible, + make sure the window actually ends up somewhere where it will be visible */ + if (pWin->drawable.class != InputOnly) + { + if ((iX < GetSystemMetrics (SM_XVIRTUALSCREEN)) || (iX > GetSystemMetrics (SM_CXVIRTUALSCREEN))) + iX = CW_USEDEFAULT; - if (iY > GetSystemMetrics (SM_CYVIRTUALSCREEN)) - iY = CW_USEDEFAULT; + if ((iY < GetSystemMetrics (SM_YVIRTUALSCREEN)) || (iY > GetSystemMetrics (SM_CYVIRTUALSCREEN))) + iY = CW_USEDEFAULT; + } if (winMultiWindowGetTransientFor (pWin, &pDaddy)) { @@ -666,7 +670,8 @@ winUpdateWindowsWindow (WindowPtr pWin) } /* Display the window without activating it */ - ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE); + if (pWin->drawable.class != InputOnly) + ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE); /* Send first paint message */ UpdateWindow (pWinPriv->hWnd); From 71550a8665d861384332d81239ca0c1586a17137 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Fri, 28 Jan 2011 20:17:22 +0000 Subject: [PATCH 4/7] Cygwin/X: Decorate function pointers retrieved via GetProcAddress with WINAPI Decorate function pointers retrieved via GetProcAddress which are currently missing it with WINAPI, to ensure stdcall convention is used when calling them. This fixes a crash currently seen when compiled -O2 and the -screen option uses a size and monitor number e.g. -screen 0 1280x1000@2 Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/InitOutput.c | 2 +- hw/xwin/winmonitors.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c index 7faed0170..22ef8da76 100644 --- a/hw/xwin/InitOutput.c +++ b/hw/xwin/InitOutput.c @@ -49,7 +49,7 @@ from The Open Group. #endif #ifdef RELOCATE_PROJECTROOT #include -typedef HRESULT (*SHGETFOLDERPATHPROC)( +typedef WINAPI HRESULT (*SHGETFOLDERPATHPROC)( HWND hwndOwner, int nFolder, HANDLE hToken, diff --git a/hw/xwin/winmonitors.c b/hw/xwin/winmonitors.c index 63af803d0..a9d46f90e 100644 --- a/hw/xwin/winmonitors.c +++ b/hw/xwin/winmonitors.c @@ -53,7 +53,7 @@ wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _d return TRUE; } -typedef wBOOL (*ENUMDISPLAYMONITORSPROC)(HDC,LPCRECT,MONITORENUMPROC,LPARAM); +typedef WINAPI wBOOL (*ENUMDISPLAYMONITORSPROC)(HDC,LPCRECT,MONITORENUMPROC,LPARAM); ENUMDISPLAYMONITORSPROC _EnumDisplayMonitors; wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data); From 0c603509eb7f9c83baf4e00b4558dce78f897ebf Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Fri, 11 Feb 2011 13:15:40 +0000 Subject: [PATCH 5/7] Cygwin/X: Cosmetic fixes to logging of result from X*TextPropertyToTextList() Report XLocaleNotSupported result from X*TextPropertyToTextList() Fix formatting for unknown results reported for X*TextPropertyToTextList() Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/winclipboardxevents.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/xwin/winclipboardxevents.c b/hw/xwin/winclipboardxevents.c index 8b502b117..b0006a01f 100644 --- a/hw/xwin/winclipboardxevents.c +++ b/hw/xwin/winclipboardxevents.c @@ -636,11 +636,14 @@ winClipboardFlushXEvents (HWND hwnd, case XNoMemory: ErrorF ("XNoMemory\n"); break; + case XLocaleNotSupported: + ErrorF ("XLocaleNotSupported\n"); + break; case XConverterNotFound: ErrorF ("XConverterNotFound\n"); break; default: - ErrorF ("%d", iReturn); + ErrorF ("%d\n", iReturn); break; } pszReturnData = malloc (1); From ce6136f8c553bbc6d3e3affa0faa2afbf8054f44 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 23 Mar 2010 20:06:33 +0000 Subject: [PATCH 6/7] Cygwin/X: Make winOverrrideStyle() thread-safe Make winOverrrideStyle() thread-safe winOverrideStyle() is called from the internal WM client thread. Accessing server-internal data structures to get window name and class is not safe, as there is no lock to ensure we do not collide with these data structures being updated in the server thread. Rewrite so the internal client thread uses X client calls to obtain this data safely Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/winmultiwindowwm.c | 22 ++++++++++++++++++++-- hw/xwin/winprefs.c | 26 +++----------------------- hw/xwin/winprefs.h | 2 +- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c index ef0c7cf0b..67a58a076 100644 --- a/hw/xwin/winmultiwindowwm.c +++ b/hw/xwin/winmultiwindowwm.c @@ -1576,7 +1576,6 @@ winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle) Atom type, *pAtom = NULL; int format; unsigned long hint = 0, maxmin = 0, style, nitems = 0 , left = 0; - WindowPtr pWin = GetProp (hWnd, WIN_WINDOW_PROP); MwmHints *mwm_hint = NULL; if (!hWnd) return; @@ -1669,7 +1668,26 @@ winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle) } /* Override hint settings from above with settings from config file */ - style = winOverrideStyle((unsigned long)pWin); + { + XClassHint class_hint = {0,0}; + char *window_name = 0; + + if (XGetClassHint(pDisplay, iWindow, &class_hint)) + { + XFetchName(pDisplay, iWindow, &window_name); + + style = winOverrideStyle(class_hint.res_name, class_hint.res_class, window_name); + + if (class_hint.res_name) XFree(class_hint.res_name); + if (class_hint.res_class) XFree(class_hint.res_class); + if (window_name) XFree(window_name); + } + else + { + style = STYLE_NONE; + } + } + if (style & STYLE_TOPMOST) *zstyle = HWND_TOPMOST; else if (style & STYLE_MAXIMIZE) maxmin = (hint & ~HINT_MIN) | HINT_MAX; else if (style & STYLE_MINIMIZE) maxmin = (hint & ~HINT_MAX) | HINT_MIN; diff --git a/hw/xwin/winprefs.c b/hw/xwin/winprefs.c index 4ccb4ffc2..d941c5169 100644 --- a/hw/xwin/winprefs.c +++ b/hw/xwin/winprefs.c @@ -813,40 +813,20 @@ LoadPreferences (void) * STYLES{} section in the prefs file, and return the style type */ unsigned long -winOverrideStyle (unsigned long longpWin) +winOverrideStyle (char *res_name, char *res_class, char *wmName) { - WindowPtr pWin = (WindowPtr) longpWin; - char *res_name, *res_class; int i; - char *wmName; - - if (pWin==NULL) - return STYLE_NONE; - - /* If we can't find the class, we can't override from default! */ - if (!winMultiWindowGetClassHint (pWin, &res_name, &res_class)) - return STYLE_NONE; - - winMultiWindowGetWMName (pWin, &wmName); for (i=0; i Date: Sat, 5 Mar 2011 17:34:42 +0000 Subject: [PATCH 7/7] Cygwin/X: Handle failure during winScreenInit() Handle failure during winScreenInit() a bit more cleanly, rather than crashing This avoids a crash with 'XWin -fullscreen -screen 0 @2 -screen 1 @1' Also document that fullscreen may only be applied to one screen. Signed-off-by: Jon TURNEY Reviewed-by: Colin Harrison Tested-by: Colin Harrison --- hw/xwin/man/XWin.man | 3 ++- hw/xwin/winpfbdd.c | 3 ++- hw/xwin/winscrinit.c | 4 ++++ hw/xwin/winshaddd.c | 3 ++- hw/xwin/winshadddnl.c | 3 ++- hw/xwin/winshadgdi.c | 3 ++- 6 files changed, 14 insertions(+), 5 deletions(-) diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man index e7933c9c8..aad29cf25 100644 --- a/hw/xwin/man/XWin.man +++ b/hw/xwin/man/XWin.man @@ -67,7 +67,7 @@ The default behaviour is to create a single screen 0 that is roughly the size of useful area of the primary monitor (allowing for any window decorations and the task-bar). -Screen specific parameters, such as \fB\-fullscreen\fP, can be applied as a +Screen specific parameters can be applied as a default to all screens by placing those screen specific parameters before any \fB\-screen\fP parameter. Screen specific parameters placed after the first \fB\-screen\fP parameter will apply only to the immediately @@ -108,6 +108,7 @@ in \fB-multiwindow\fP or \fB-rootless\fP mode. .B "\-fullscreen" The X server window takes the full screen, covering completely the \fIWindows\fP desktop. +Currently \fB\-fullscreen\fP may only be applied to one X screen. .TP 8 .B \-nodecoration Do not give the Cygwin/X window a \fIWindows\fP window border, title bar, diff --git a/hw/xwin/winpfbdd.c b/hw/xwin/winpfbdd.c index c0bca71e3..a3990208d 100644 --- a/hw/xwin/winpfbdd.c +++ b/hw/xwin/winpfbdd.c @@ -294,7 +294,8 @@ winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen) /* Call the wrapped CloseScreen procedure */ WIN_UNWRAP(CloseScreen); - fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + if (pScreen->CloseScreen) + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); /* Delete the window property */ RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c index 691237e6f..983ff5730 100644 --- a/hw/xwin/winscrinit.c +++ b/hw/xwin/winscrinit.c @@ -220,6 +220,10 @@ winScreenInit (int index, if (!((*pScreenPriv->pwinFinishScreenInit) (index, pScreen, argc, argv))) { ErrorF ("winScreenInit - winFinishScreenInit () failed\n"); + + /* call the engine dependent screen close procedure to clean up from a failure */ + pScreenPriv->pwinCloseScreen(index, pScreen); + return FALSE; } diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c index 00d7a379f..6dad2782f 100644 --- a/hw/xwin/winshaddd.c +++ b/hw/xwin/winshaddd.c @@ -728,7 +728,8 @@ winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen) /* Call the wrapped CloseScreen procedure */ WIN_UNWRAP(CloseScreen); - fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + if (pScreen->CloseScreen) + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); winFreeFBShadowDD(pScreen); diff --git a/hw/xwin/winshadddnl.c b/hw/xwin/winshadddnl.c index 0a0b4ae13..63d48adb6 100644 --- a/hw/xwin/winshadddnl.c +++ b/hw/xwin/winshadddnl.c @@ -802,7 +802,8 @@ winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen) /* Call the wrapped CloseScreen procedure */ WIN_UNWRAP(CloseScreen); - fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + if (pScreen->CloseScreen) + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); winFreeFBShadowDDNL(pScreen); diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c index 499037656..1e7cb006c 100644 --- a/hw/xwin/winshadgdi.c +++ b/hw/xwin/winshadgdi.c @@ -636,7 +636,8 @@ winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen) /* Call the wrapped CloseScreen procedure */ WIN_UNWRAP(CloseScreen); - fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + if (pScreen->CloseScreen) + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); /* Delete the window property */ RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);