diff options
-rw-r--r-- | make/build-nativewindow.xml | 5 | ||||
-rw-r--r-- | make/config/nativewindow/win32-lib.cfg | 7 | ||||
-rw-r--r-- | make/stub_includes/win32/WindowsDWM.h | 91 | ||||
-rw-r--r-- | make/stub_includes/win32/gluegen/windows.h (renamed from make/stub_includes/win32/windows.h) | 13 | ||||
-rw-r--r-- | make/stub_includes/win32/gluegen/wingdi.h (renamed from make/stub_includes/win32/wingdi.h) | 8 | ||||
-rw-r--r-- | make/stub_includes/win32/gluegen/wingdi_types.h (renamed from make/stub_includes/win32/wingdi_types.h) | 8 | ||||
-rw-r--r-- | make/stub_includes/win32/gluegen/winwgl.h (renamed from make/stub_includes/win32/winwgl.h) | 8 | ||||
-rw-r--r-- | src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java | 19 | ||||
-rw-r--r-- | src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java | 79 | ||||
-rw-r--r-- | src/nativewindow/native/win32/WindowsDWM.c | 115 | ||||
-rw-r--r-- | src/nativewindow/native/win32/WindowsDWM.h | 34 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java | 14 | ||||
-rw-r--r-- | src/newt/native/WindowsWindow.c | 128 |
13 files changed, 391 insertions, 138 deletions
diff --git a/make/build-nativewindow.xml b/make/build-nativewindow.xml index b3a02b9b9..216ae461f 100644 --- a/make/build-nativewindow.xml +++ b/make/build-nativewindow.xml @@ -227,7 +227,7 @@ outputRootDir="${build.nativewindow}" config="${windowlib.os.cfg}" includeRefid="stub.includes.fileset.platform" - literalInclude="${stub.includes.gluegen.gg}, ${src.c}/${window.os.system}" + literalInclude="${stub.includes.gluegen.gg}, ${stub.includes}/${window.os.system}/gluegen, ${src.c}/${window.os.system}" emitter="com.jogamp.gluegen.JavaEmitter" debug="false" dumpCPP="false"> @@ -246,7 +246,7 @@ outputRootDir="${build.nativewindow}" config="${jawt.cfg}" includeRefid="stub.includes.fileset.platform" - literalInclude="${stub.includes.gluegen.gg}, ${stub.includes.gluegen}/jni, ${stub.includes.gluegen}/jni/${jni.platform.sub}" + literalInclude="${stub.includes.gluegen.gg}, ${stub.includes.gluegen}/jni, ${stub.includes.gluegen}/jni/${jni.platform.sub}, ${stub.includes}/${window.os.system}/gluegen" emitter="com.jogamp.gluegen.JavaEmitter" debug="false" dumpCPP="false"> @@ -710,6 +710,7 @@ <includepath path="${src.generated.c}" /> <includepath path="${src.generated.c}/X11" if="isX11"/> <includepath path="${src.generated.c}/MacOSX" if="isOSX"/> + <includepath path="stub_includes/win32" if="isWindows"/> <includepath path="${src.generated.c}/Windows" if="isWindows"/> <includepath path="${src.c}/x11" if="isX11"/> <includepath path="${src.c}/macosx" if="isOSX"/> diff --git a/make/config/nativewindow/win32-lib.cfg b/make/config/nativewindow/win32-lib.cfg index 3a8fdd66a..da91f6944 100644 --- a/make/config/nativewindow/win32-lib.cfg +++ b/make/config/nativewindow/win32-lib.cfg @@ -13,6 +13,13 @@ Opaque long HANDLE Opaque long PROC Opaque long void ** +NIODirectOnly DwmEnableBlurBehindWindow +NIODirectOnly DwmExtendFrameIntoClientArea +NIODirectOnly DwmGetWindowAttribute +NIODirectOnly DwmSetWindowAttribute +NIODirectOnly GetWindowCompositionAccentPolicy +NIODirectOnly SetWindowCompositionAccentPolicy + Import com.jogamp.nativewindow.util.Point Import com.jogamp.nativewindow.NativeWindowException Import jogamp.nativewindow.NWJNILibLoader diff --git a/make/stub_includes/win32/WindowsDWM.h b/make/stub_includes/win32/WindowsDWM.h index 2115a5908..247464afd 100644 --- a/make/stub_includes/win32/WindowsDWM.h +++ b/make/stub_includes/win32/WindowsDWM.h @@ -1,3 +1,6 @@ +#include <windows.h> +#include <stdint.h> + #ifndef WGL_DWM_VERSION_1_X #define DWM_BB_ENABLE 0x00000001 @@ -6,19 +9,44 @@ #define DWM_EC_DISABLECOMPOSITION 0 #define DWM_EC_ENABLECOMPOSITION 1 +typedef enum _DWMWINDOWATTRIBUTE { + DWMWA_NCRENDERING_ENABLED = 1, + DWMWA_NCRENDERING_POLICY, + DWMWA_TRANSITIONS_FORCEDISABLED, + DWMWA_ALLOW_NCPAINT, + DWMWA_CAPTION_BUTTON_BOUNDS, + DWMWA_NONCLIENT_RTL_LAYOUT, + DWMWA_FORCE_ICONIC_REPRESENTATION, + DWMWA_FLIP3D_POLICY, + DWMWA_EXTENDED_FRAME_BOUNDS, + DWMWA_HAS_ICONIC_BITMAP, + DWMWA_DISALLOW_PEEK, + DWMWA_EXCLUDED_FROM_PEEK, + DWMWA_CLOAK, + DWMWA_CLOAKED, + DWMWA_FREEZE_REPRESENTATION, + DWMWA_LAST +} DWMWINDOWATTRIBUTE; + +typedef enum _DWMNCRENDERINGPOLICY { + DWMNCRP_USEWINDOWSTYLE = 0, + DWMNCRP_DISABLED, + DWMNCRP_ENABLED, + DWMNCRP_LAST +} DWMNCRENDERINGPOLICY; typedef struct tagDWM_BLURBEHIND { DWORD dwFlags; - int fEnable; /* BOOL */ + int32_t fEnable; /* BOOL */ HRGN hRgnBlur; - int fTransitionOnMaximized; /* BOOL */ + int32_t fTransitionOnMaximized; /* BOOL */ } DWM_BLURBEHIND, *PDWM_BLURBEHIND; typedef struct tagMARGINS { - int cxLeftWidth; - int cxRightWidth; - int cyTopHeight; - int cyBottomHeight; + int32_t cxLeftWidth; + int32_t cxRightWidth; + int32_t cyTopHeight; + int32_t cyBottomHeight; } MARGINS, *PMARGINS; #endif /* WGL_DWM_VERSION_1_X */ @@ -31,6 +59,57 @@ BOOL DwmIsCompositionEnabled(); BOOL DwmEnableComposition( UINT uCompositionAction ); BOOL DwmEnableBlurBehindWindow(HWND, CONST DWM_BLURBEHIND *); BOOL DwmExtendFrameIntoClientArea(HWND, CONST MARGINS *); +HRESULT DwmGetWindowAttribute(HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute); +HRESULT DwmSetWindowAttribute(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); #endif /* WGL_DWM_VERSION_1_X */ +#ifndef WGL_WINCOMP_VERSION_0_X + +typedef enum _AccentState { + ACCENT_DISABLED = 0, + ACCENT_ENABLE_GRADIENT = 1, + ACCENT_ENABLE_TRANSPARENTGRADIENT = 2, + ACCENT_ENABLE_BLURBEHIND = 3, + ACCENT_INVALID_STATE = 4 +} AccentState; + +typedef struct _AccentPolicy { + AccentState AccentState; + int32_t AccentFlags; + int32_t GradientColor; + int32_t AnimationId; +} AccentPolicy; + + +#ifndef __GLUEGEN__ + +typedef enum _WindowCompositionAttribute { + WCA_ACCENT_POLICY = 19 +} WindowCompositionAttribute; + +typedef struct _WINCOMPATTRDATA { + /** The attribute to query */ + WindowCompositionAttribute attribute; + /** result storage */ + PVOID pData; + /** size of the result storage */ + ULONG dataSize; +} WINCOMPATTRDATA; + +#endif + +#endif /* WGL_WINCOMP_VERSION_0_X */ + +#ifndef WGL_WINCOMP_VERSION_0_X +#define WGL_WINCOMP_VERSION_0_X + +BOOL IsWindowCompositionExtensionAvailable(); +BOOL GetWindowCompositionAccentPolicy(HWND hwnd, AccentPolicy* pAccentPolicy); +BOOL SetWindowCompositionAccentPolicy(HWND hwnd, const AccentPolicy* pAccentPolicy); +#if 0 + BOOL GetWindowCompositionAttribute(HWND hwnd, WINCOMPATTRDATA* pAttrData); + BOOL SetWindowCompositionAttribute(HWND hwnd, WINCOMPATTRDATA* pAttrData); +#endif + +#endif /* WGL_WINCOMP_VERSION_0_X */ diff --git a/make/stub_includes/win32/windows.h b/make/stub_includes/win32/gluegen/windows.h index 9958e6d3a..46a560767 100644 --- a/make/stub_includes/win32/windows.h +++ b/make/stub_includes/win32/gluegen/windows.h @@ -1,6 +1,14 @@ /* Windows #defines and typedefs required for processing of extracts from WINGDI.H and jawt_md.h */ +/** + * These are standard include replacement files + * for gluegen processing only! + */ +#ifndef __GLUEGEN__ + #error "This file is intended to be used for GlueGen code generation, not native compilation. +#endif + #ifndef _WINDOWS_ #define _WINDOWS_ @@ -30,9 +38,12 @@ typedef HANDLE HINSTANCE; typedef HANDLE HPALETTE; typedef HANDLE HWND; typedef HANDLE HRGN; -typedef __int32 LONG; typedef const char* LPCSTR; +typedef void* PVOID; typedef void* LPVOID; +typedef const void* LPCVOID; +typedef __int32 LONG; +typedef unsigned __int32 ULONG; typedef unsigned __int64 ULONG_PTR; typedef struct _proc* PROC; typedef unsigned int* PUINT; diff --git a/make/stub_includes/win32/wingdi.h b/make/stub_includes/win32/gluegen/wingdi.h index 0fb042eb1..5914c708c 100644 --- a/make/stub_includes/win32/wingdi.h +++ b/make/stub_includes/win32/gluegen/wingdi.h @@ -9,6 +9,14 @@ * Editions / Removals and a split (wingdi.h -> wingdi.h + wingdi_types.h + winwgl.h) were made by the JogAmp Community, 2010, 2012 */ +/** + * These are standard include replacement files + * for gluegen processing only! + */ +#ifndef __GLUEGEN__ + #error "This file is intended to be used for GlueGen code generation, not native compilation. +#endif + #ifndef GDI_VERSION_1_X #define GDI_VERSION_1_X diff --git a/make/stub_includes/win32/wingdi_types.h b/make/stub_includes/win32/gluegen/wingdi_types.h index 14210bf2f..659b39e8b 100644 --- a/make/stub_includes/win32/wingdi_types.h +++ b/make/stub_includes/win32/gluegen/wingdi_types.h @@ -9,6 +9,14 @@ * Editions / Removals and a split (wingdi.h -> wingdi.h + wingdi_types.h + winwgl.h) were made by the JogAmp Community, 2010, 2012 */ +/** + * These are standard include replacement files + * for gluegen processing only! + */ +#ifndef __GLUEGEN__ + #error "This file is intended to be used for GlueGen code generation, not native compilation. +#endif + #ifndef GDI_TYPES_1_X #define GDI_TYPES_1_X diff --git a/make/stub_includes/win32/winwgl.h b/make/stub_includes/win32/gluegen/winwgl.h index cc0589574..ca743c9fe 100644 --- a/make/stub_includes/win32/winwgl.h +++ b/make/stub_includes/win32/gluegen/winwgl.h @@ -9,6 +9,14 @@ * Editions / Removals and a split (wingdi.h -> wingdi.h + wingdi_types.h + winwgl.h) were made by the JogAmp Community, 2010, 2012 */ +/** + * These are standard include replacement files + * for gluegen processing only! + */ +#ifndef __GLUEGEN__ + #error "This file is intended to be used for GlueGen code generation, not native compilation. +#endif + #ifndef WGL_GDI_VERSION_1_X #include "wingdi_types.h" diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java index f88718d1b..4ffe6e7d1 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java @@ -171,24 +171,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio ": error code " + GDI.GetLastError()); } if( !caps.isBackgroundOpaque() ) { - final long hwnd = GDI.WindowFromDC(hdc); - final DWM_BLURBEHIND bb = DWM_BLURBEHIND.create(); - bb.setDwFlags(GDI.DWM_BB_ENABLE| GDI.DWM_BB_TRANSITIONONMAXIMIZED); - bb.setFEnable( 1 ); - boolean ok = GDI.DwmEnableBlurBehindWindow(hwnd, bb); - if( ok ) { - final MARGINS m = MARGINS.create(); - m.setCxLeftWidth(-1); - m.setCxRightWidth(-1); - m.setCyBottomHeight(-1); - m.setCyTopHeight(-1); - ok = GDI.DwmExtendFrameIntoClientArea(hwnd, m); - } - if(DEBUG) { - final boolean isUndecorated = GDIUtil.IsUndecorated(hwnd); - final boolean isChild = GDIUtil.IsChild(hwnd); - System.err.println("translucency enabled on wnd: 0x"+Long.toHexString(hwnd)+" - isUndecorated "+isUndecorated+", isChild "+isChild+", ok: "+ok); - } + GDIUtil.DwmSetupTranslucency(GDI.WindowFromDC(hdc), true); } if (DEBUG) { System.err.println("setPixelFormat: hdc "+toHexString(hdc) +", "+caps); diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java index 7c01d7b2e..c0f277f09 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java @@ -128,7 +128,13 @@ public class GDIUtil implements ToolkitProperties { * Windows >= 8, even if not manifested * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832%28v=vs.85%29.aspx */ - private static final VersionNumber Win8Version = new VersionNumber(6, 2, 0); + public static final VersionNumber Win8Version = new VersionNumber(6, 2, 0); + + /** + * Windows >= 10, manifested + * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832%28v=vs.85%29.aspx + */ + public static final VersionNumber Win10Version = new VersionNumber(10, 0, 0); /** * Wrapper for {@link GDI#DwmIsCompositionEnabled()} @@ -148,6 +154,77 @@ public class GDIUtil implements ToolkitProperties { } } + public static boolean DwmSetupTranslucency(final long hwnd, final boolean enable) { + if( !GDI.DwmIsExtensionAvailable() ) { + if(DEBUG) { + System.err.println("GDIUtil.DwmSetupTranslucency on wnd 0x"+Long.toHexString(hwnd)+": enable "+enable+" -> failed, extension not available"); + } + return !enable; + } + final VersionNumber winVer = Platform.getOSVersionNumber(); + final boolean isWin8 = winVer.compareTo(Win8Version) >= 0; + if( !isWin8 && !GDI.DwmIsCompositionEnabled() ) { + if(DEBUG) { + System.err.println("GDIUtil.DwmSetupTranslucency on wnd 0x"+Long.toHexString(hwnd)+": enable "+enable+" -> failed, composition disabled"); + } + return !enable; + } + final boolean hasWinCompEXT = GDI.IsWindowCompositionExtensionAvailable(); + final boolean useWinCompEXT = isWin8 && hasWinCompEXT; + final boolean isUndecorated = IsUndecorated(hwnd); + boolean ok; + if( useWinCompEXT && !isUndecorated ) { + final AccentPolicy accentPolicy = AccentPolicy.create(); + if( enable ) { + // For undecorated windows, this would also enable the Glass effect! + accentPolicy.setAccentState(GDI.ACCENT_ENABLE_BLURBEHIND); + } else { + accentPolicy.setAccentState(GDI.ACCENT_DISABLED); + } + ok = GDI.SetWindowCompositionAccentPolicy(hwnd, accentPolicy); + } else { + // Works even for >= Win8, if undecorated + final DWM_BLURBEHIND bb = DWM_BLURBEHIND.create(); + final int dwFlags = enable ? GDI.DWM_BB_ENABLE | GDI.DWM_BB_BLURREGION | GDI.DWM_BB_TRANSITIONONMAXIMIZED : GDI.DWM_BB_ENABLE; + // final int dwFlags = GDI.DWM_BB_ENABLE; + bb.setDwFlags( dwFlags ); + bb.setFEnable( enable ? 1 : 0 ); + bb.setHRgnBlur(0); + bb.setFTransitionOnMaximized(1); + ok = GDI.DwmEnableBlurBehindWindow(hwnd, bb); + if( ok ) { + final MARGINS m = MARGINS.create(); + m.setCxLeftWidth(-1); + m.setCxRightWidth(-1); + m.setCyBottomHeight(-1); + m.setCyTopHeight(-1); + ok = GDI.DwmExtendFrameIntoClientArea(hwnd, m); + } + } + /*** + * Not required .. + * + if( ok && isWin8 && !isUndecorated ) { + final IntBuffer pvAttribute = Buffers.newDirectIntBuffer(1); + if( enable ) { + // Glass Effect even if undecorated, hence not truly 100% translucent! + pvAttribute.put(0, GDI.DWMNCRP_ENABLED); + } else { + pvAttribute.put(0, GDI.DWMNCRP_DISABLED); + } + final int err = GDI.DwmSetWindowAttribute(hwnd, GDI.DWMWA_NCRENDERING_POLICY, + pvAttribute, + Buffers.sizeOfBufferElem(pvAttribute)*pvAttribute.capacity()); + ok = 0 == err; // S_OK + } */ + if(DEBUG) { + final boolean isChild = IsChild(hwnd); + System.err.println("GDIUtil.DwmSetupTranslucency on wnd 0x"+Long.toHexString(hwnd)+": enable "+enable+", isUndecorated "+isUndecorated+", isChild "+isChild+ + ", version "+winVer+", isWin8 "+isWin8+", hasWinCompEXT "+hasWinCompEXT+", useWinCompEXT "+useWinCompEXT+" -> ok: "+ok); + } + return ok; + } + public static boolean IsUndecorated(final long win) { return IsUndecorated0(win); } diff --git a/src/nativewindow/native/win32/WindowsDWM.c b/src/nativewindow/native/win32/WindowsDWM.c index cc9ed6d8c..925ddd1d1 100644 --- a/src/nativewindow/native/win32/WindowsDWM.c +++ b/src/nativewindow/native/win32/WindowsDWM.c @@ -1,4 +1,5 @@ +#include <windows.h> #include "WindowsDWM.h" #include <stdlib.h> @@ -21,39 +22,68 @@ typedef HRESULT (WINAPI *DwmEnableCompositionPROCADDR)(UINT uCompositionAction); typedef HRESULT (WINAPI *DwmIsCompositionEnabledPROCADDR)(BOOL * pfEnabled); typedef HRESULT (WINAPI *DwmEnableBlurBehindWindowPROCADDR)(HWND hWnd, const DWM_BLURBEHIND* pBlurBehind); typedef HRESULT (WINAPI *DwmExtendFrameIntoClientAreaPROCADDR)(HWND hwnd, const MARGINS *pMarInset); +typedef HRESULT (WINAPI *DwmGetWindowAttributePROCADDR)(HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute); +typedef HRESULT (WINAPI *DwmSetWindowAttributePROCADDR)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); +typedef BOOL (WINAPI *GetWindowCompositionAttributePROCADDR)(HWND hwnd, WINCOMPATTRDATA* pAttrData); +typedef BOOL (WINAPI *SetWindowCompositionAttributePROCADDR)(HWND hwnd, WINCOMPATTRDATA* pAttrData); -static int _init = 0; // 1: init, 2: has DWM extension +#define INIT_CALLED_MASK 1 << 0 +#define INIT_HAS_DWM_EXT_MASK 1 << 1 +#define INIT_HAS_WINCOMP_EXT_MASK 1 << 2 + +#define HAS_INIT(a) ( 0 != ( INIT_CALLED_MASK & (a) ) ) +#define HAS_DWM_EXT(a) ( 0 != ( INIT_HAS_DWM_EXT_MASK & (a) ) ) +#define HAS_WINCOMP_EXT(a) ( 0 != ( INIT_HAS_WINCOMP_EXT_MASK & (a) ) ) + +static int _init = 0; // INIT_ bits, see above static DwmEnableCompositionPROCADDR _DwmEnableComposition = NULL; static DwmIsCompositionEnabledPROCADDR _DwmIsCompositionEnabled = NULL; static DwmEnableBlurBehindWindowPROCADDR _DwmEnableBlurBehindWindow = NULL; static DwmExtendFrameIntoClientAreaPROCADDR _DwmExtendFrameIntoClientArea = NULL; +static DwmGetWindowAttributePROCADDR _DwmGetWindowAttribute = NULL; +static DwmSetWindowAttributePROCADDR _DwmSetWindowAttribute = NULL; +static GetWindowCompositionAttributePROCADDR _GetWindowCompositionAttribute = NULL; +static SetWindowCompositionAttributePROCADDR _SetWindowCompositionAttribute = NULL; static int initWindowsDWM() { - if(0 == _init) { - _init = 1; - HANDLE shell = LoadLibrary(TEXT("dwmapi.dll")); - if (shell) { - _DwmEnableComposition = (DwmEnableCompositionPROCADDR) GetProcAddressA (shell, "DwmEnableComposition"); - _DwmIsCompositionEnabled = (DwmIsCompositionEnabledPROCADDR) GetProcAddressA (shell, "DwmIsCompositionEnabled"); - _DwmEnableBlurBehindWindow = (DwmEnableBlurBehindWindowPROCADDR) GetProcAddressA (shell, "DwmEnableBlurBehindWindow"); - _DwmExtendFrameIntoClientArea = (DwmExtendFrameIntoClientAreaPROCADDR) GetProcAddressA (shell, "DwmExtendFrameIntoClientArea"); + if( !HAS_INIT(_init) ) { + _init |= INIT_CALLED_MASK; + HANDLE hDwmAPI = LoadLibrary(TEXT("dwmapi.dll")); + if (hDwmAPI) { + _DwmEnableComposition = (DwmEnableCompositionPROCADDR) GetProcAddressA (hDwmAPI, "DwmEnableComposition"); + _DwmIsCompositionEnabled = (DwmIsCompositionEnabledPROCADDR) GetProcAddressA (hDwmAPI, "DwmIsCompositionEnabled"); + _DwmEnableBlurBehindWindow = (DwmEnableBlurBehindWindowPROCADDR) GetProcAddressA (hDwmAPI, "DwmEnableBlurBehindWindow"); + _DwmExtendFrameIntoClientArea = (DwmExtendFrameIntoClientAreaPROCADDR) GetProcAddressA (hDwmAPI, "DwmExtendFrameIntoClientArea"); + _DwmGetWindowAttribute = (DwmGetWindowAttributePROCADDR) GetProcAddressA (hDwmAPI, "DwmGetWindowAttribute"); + _DwmSetWindowAttribute = (DwmSetWindowAttributePROCADDR) GetProcAddressA (hDwmAPI, "DwmSetWindowAttribute"); if(NULL != _DwmEnableComposition && NULL != _DwmIsCompositionEnabled && - NULL != _DwmEnableBlurBehindWindow && NULL != _DwmExtendFrameIntoClientArea) { - _init = 2; + NULL != _DwmEnableBlurBehindWindow && NULL != _DwmExtendFrameIntoClientArea && + NULL != _DwmGetWindowAttribute && NULL != _DwmSetWindowAttribute) { + _init |= INIT_HAS_DWM_EXT_MASK; + } + } + // FreeLibrary (hDwmAPI); + HANDLE hUser32 = LoadLibrary(TEXT("user32.dll")); + if (hUser32) { + _GetWindowCompositionAttribute = (GetWindowCompositionAttributePROCADDR) GetProcAddressA (hUser32, "GetWindowCompositionAttribute"); + _SetWindowCompositionAttribute = (SetWindowCompositionAttributePROCADDR) GetProcAddressA (hUser32, "SetWindowCompositionAttribute"); + if( NULL != _GetWindowCompositionAttribute && + NULL != _SetWindowCompositionAttribute ) { + _init |= INIT_HAS_WINCOMP_EXT_MASK; } } - // FreeLibrary (shell); - DBG_PRINT("DWM - initWindowsDWM: %d - s %p, e %p, c %p\n", _init, shell, _DwmEnableBlurBehindWindow, _DwmExtendFrameIntoClientArea); + // FreeLibrary (hUser32); + DBG_PRINT("DWM - initWindowsDWM: hasDWM %d, hasWinComp %d\n", HAS_DWM_EXT(_init), HAS_WINCOMP_EXT(_init)); } return _init; } BOOL DwmIsExtensionAvailable() { - return (2 == initWindowsDWM()) ? TRUE : FALSE; + return HAS_DWM_EXT( initWindowsDWM() ) ? TRUE : FALSE; } BOOL DwmIsCompositionEnabled( ) { - if(2 == initWindowsDWM()) { + if( HAS_DWM_EXT( initWindowsDWM() ) ) { BOOL fEnabled = FALSE; if( 0 == _DwmIsCompositionEnabled(&fEnabled) ) { DBG_PRINT("DWM - DwmIsCompositionEnabled: %d\n", fEnabled); @@ -65,14 +95,14 @@ BOOL DwmIsCompositionEnabled( ) { } BOOL DwmEnableComposition( UINT uCompositionAction ) { - if(2 == initWindowsDWM()) { + if( HAS_DWM_EXT( initWindowsDWM() ) ) { return 0 == _DwmEnableComposition(uCompositionAction) ? TRUE : FALSE; } return FALSE; } BOOL DwmEnableBlurBehindWindow(HWND hwnd, const DWM_BLURBEHIND* pBlurBehind) { - if(2 == initWindowsDWM()) { + if( HAS_DWM_EXT( initWindowsDWM() ) ) { _DwmEnableBlurBehindWindow(hwnd, pBlurBehind); DBG_PRINT("DWM - DwmEnableBlurBehindWindow: hwnd %p, f %d, on %d, %p\n", (void *)hwnd, @@ -86,10 +116,59 @@ BOOL DwmEnableBlurBehindWindow(HWND hwnd, const DWM_BLURBEHIND* pBlurBehind) { } BOOL DwmExtendFrameIntoClientArea(HWND hwnd, const MARGINS *pMarInset) { - if(2 == initWindowsDWM()) { + if( HAS_DWM_EXT( initWindowsDWM() ) ) { _DwmExtendFrameIntoClientArea(hwnd, pMarInset); return TRUE; } return FALSE; } +HRESULT DwmGetWindowAttribute(HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute) { + if( HAS_DWM_EXT( initWindowsDWM() ) ) { + return _DwmGetWindowAttribute(hwnd, dwAttribute, pvAttribute, cbAttribute); + } + return E_NOINTERFACE; +} + +HRESULT DwmSetWindowAttribute(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute) { + if( HAS_DWM_EXT( initWindowsDWM() ) ) { + return _DwmSetWindowAttribute(hwnd, dwAttribute, pvAttribute, cbAttribute); + } + return E_NOINTERFACE; +} + +BOOL IsWindowCompositionExtensionAvailable() { + return HAS_WINCOMP_EXT( initWindowsDWM() ) ? TRUE : FALSE; +} + +BOOL GetWindowCompositionAccentPolicy(HWND hwnd, AccentPolicy* pAccentPolicy) { + if( HAS_WINCOMP_EXT( initWindowsDWM() ) ) { + WINCOMPATTRDATA attrData = { WCA_ACCENT_POLICY, pAccentPolicy, sizeof(AccentPolicy) }; + return _GetWindowCompositionAttribute(hwnd, &attrData); + } + return FALSE; +} +BOOL SetWindowCompositionAccentPolicy(HWND hwnd, const AccentPolicy* pAccentPolicy) { + if( HAS_WINCOMP_EXT( initWindowsDWM() ) ) { + WINCOMPATTRDATA attrData = { WCA_ACCENT_POLICY, (AccentPolicy*)pAccentPolicy, sizeof(AccentPolicy) }; + return _SetWindowCompositionAttribute(hwnd, &attrData); + } + return FALSE; +} + +#if 0 +BOOL GetWindowCompositionAttribute(HWND hwnd, WINCOMPATTRDATA* pAttrData) { + if( HAS_WINCOMP_EXT( initWindowsDWM() ) ) { + return _GetWindowCompositionAttribute(hwnd, pAttrData); + } + return FALSE; +} + +BOOL SetWindowCompositionAttribute(HWND hwnd, WINCOMPATTRDATA* pAttrData) { + if( HAS_WINCOMP_EXT( initWindowsDWM() ) ) { + return _SetWindowCompositionAttribute(hwnd, pAttrData); + } + return FALSE; +} +#endif + diff --git a/src/nativewindow/native/win32/WindowsDWM.h b/src/nativewindow/native/win32/WindowsDWM.h deleted file mode 100644 index 6e5160fa4..000000000 --- a/src/nativewindow/native/win32/WindowsDWM.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef _WINDOWS_DWM_H_ -#define _WINDOWS_DWM_H_ - - #include <windows.h> - - #define DWM_BB_ENABLE 0x00000001 // fEnable has been specified - #define DWM_BB_BLURREGION 0x00000002 - #define DWM_BB_TRANSITIONONMAXIMIZED 0x00000004 - #define DWM_EC_DISABLECOMPOSITION 0 - #define DWM_EC_ENABLECOMPOSITION 1 - - typedef struct _DWM_BLURBEHIND - { - DWORD dwFlags; - BOOL fEnable; - HRGN hRgnBlur; - BOOL fTransitionOnMaximized; - } DWM_BLURBEHIND, *PDWM_BLURBEHIND; - - typedef struct _MARGINS - { - int cxLeftWidth; // width of left border that retains its size - int cxRightWidth; // width of right border that retains its size - int cyTopHeight; // height of top border that retains its size - int cyBottomHeight; // height of bottom border that retains its size - } MARGINS, *PMARGINS; - - BOOL DwmIsExtensionAvailable(); - BOOL DwmIsCompositionEnabled(); - BOOL DwmEnableComposition( UINT uCompositionAction ); - BOOL DwmEnableBlurBehindWindow(HWND hwnd, const DWM_BLURBEHIND* pBlurBehind); - BOOL DwmExtendFrameIntoClientArea(HWND hwnd, const MARGINS *pMarInset); - -#endif /* _WINDOWS_DWM_H_ */ diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java index c1aa4cb90..af5dad3ac 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java @@ -157,6 +157,10 @@ public class WindowDriver extends WindowImpl { if ( 0 == _windowHandle ) { throw new NativeWindowException("Error creating window"); } + if( !cfg.getChosenCapabilities().isBackgroundOpaque() ) { + GDIUtil.DwmSetupTranslucency(_windowHandle, true); + } + InitWindow0(_windowHandle, flags); setWindowHandle(_windowHandle); windowHandleClose = _windowHandle; @@ -235,7 +239,16 @@ public class WindowDriver extends WindowImpl { width = posSize[2]; height = posSize[3]; } + + final boolean changeDecoration = 0 != ( CHANGE_MASK_DECORATION & flags); + final boolean isTranslucent = !getChosenCapabilities().isBackgroundOpaque(); + if( changeDecoration && isTranslucent ) { + GDIUtil.DwmSetupTranslucency(getWindowHandle(), false); + } reconfigureWindow0( getParentWindowHandle(), getWindowHandle(), x, y, width, height, flags); + if( changeDecoration && isTranslucent ) { + GDIUtil.DwmSetupTranslucency(getWindowHandle(), true); + } if( 0 != ( CHANGE_MASK_VISIBILITY & flags) ) { visibleChanged(false, 0 != ( STATE_MASK_VISIBLE & flags)); @@ -396,6 +409,7 @@ public class WindowDriver extends WindowImpl { private native long CreateWindow0(long hInstance, String wndClassName, String wndName, int winMajor, int winMinor, long parentWindowHandle, int x, int y, int width, int height, int flags); + private native void InitWindow0(long windowHandle, int flags); private native long MonitorFromWindow0(long windowHandle); private native void reconfigureWindow0(long parentWindowHandle, long windowHandle, int x, int y, int width, int height, int flags); diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index 097eb5e11..c004f48a1 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -2236,16 +2236,15 @@ static void NewtWindow_setVisiblePosSize(WindowUserData *wud, HWND hwnd, int jfl JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindow0 (JNIEnv *env, jobject obj, jlong hInstance, jstring jWndClassName, jstring jWndName, jint winMajor, jint winMinor, - jlong parent, jint jx, jint jy, jint defaultWidth, jint defaultHeight, jint flags) + jlong parent, jint jxpos, jint jypos, jint defaultWidth, jint defaultHeight, jint flags) { HWND parentWindow = (HWND) (intptr_t) parent; const TCHAR* wndClassName = NULL; const TCHAR* wndName = NULL; DWORD windowStyle = WS_DEFAULT_STYLES; - int x=(int)jx, y=(int)jy; + int xpos=(int)jxpos, ypos=(int)jypos; int width=(int)defaultWidth, height=(int)defaultHeight; - HWND window = NULL; - int _x = x, _y = y; // pos for CreateWindow, might be tweaked + HWND hwnd = NULL; #ifdef UNICODE wndClassName = NewtCommon_GetNullTerminatedStringChars(env, jWndClassName); @@ -2261,10 +2260,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo return 0; } windowStyle |= WS_CHILD ; - } else if ( TST_FLAG_IS_UNDECORATED(flags) ) { - windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX; } else { - if ( TST_FLAG_IS_RESIZABLE(flags) ) { + if ( TST_FLAG_IS_UNDECORATED(flags) ) { + windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX; + } else if ( TST_FLAG_IS_RESIZABLE(flags) ) { // WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX); windowStyle |= WS_OVERLAPPEDWINDOW; } else { @@ -2272,31 +2271,28 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo } if( TST_FLAG_IS_AUTOPOSITION(flags) ) { // user didn't requested specific position, use WM default - _x = CW_USEDEFAULT; - _y = 0; + xpos = CW_USEDEFAULT; + ypos = 0; } } - window = CreateWindow(wndClassName, wndName, windowStyle, - _x, _y, width, height, - parentWindow, NULL, - (HINSTANCE) (intptr_t) hInstance, - NULL); + hwnd = CreateWindow(wndClassName, wndName, windowStyle, + xpos, ypos, width, height, + parentWindow, NULL, (HINSTANCE) (intptr_t) hInstance, NULL); - DBG_PRINT("*** WindowsWindow: CreateWindow thread 0x%X, win %d.%d parent %p, window %p, %d/%d %dx%d, undeco %d, alwaysOnTop %d, autoPosition %d\n", - (int)GetCurrentThreadId(), winMajor, winMinor, parentWindow, window, x, y, width, height, + DBG_PRINT("*** WindowsWindow: CreateWindow thread 0x%X, win %d.%d parent %p, window %p, %d/%d -> %d/%d %dx%d, undeco %d, alwaysOnTop %d, autoPosition %d\n", + (int)GetCurrentThreadId(), winMajor, winMinor, parentWindow, hwnd, jxpos, jypos, xpos, ypos, width, height, TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags), TST_FLAG_IS_AUTOPOSITION(flags)); - if (NULL == window) { + if (NULL == hwnd) { int lastError = (int) GetLastError(); DBG_PRINT("*** WindowsWindow: CreateWindow failure: 0x%X %d\n", lastError, lastError); - return 0; } else { WindowUserData * wud = (WindowUserData *) malloc(sizeof(WindowUserData)); wud->jinstance = (*env)->NewGlobalRef(env, obj); wud->jenv = env; - wud->xpos = x; - wud->ypos = y; + wud->xpos = xpos; + wud->ypos = ypos; wud->width = width; wud->height = height; wud->visible = TRUE; @@ -2330,51 +2326,26 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo DBG_PRINT("*** WindowsWindow: CreateWindow winTouchFuncAvail %d, supportsMTouch %d\n", WinTouch_func_avail, wud->supportsMTouch); #if !defined(__MINGW64__) && ( defined(UNDER_CE) || _MSC_VER <= 1200 ) - SetWindowLong(window, GWL_USERDATA, (intptr_t) wud); + SetWindowLong(hwnd, GWL_USERDATA, (intptr_t) wud); #else - SetWindowLongPtr(window, GWLP_USERDATA, (intptr_t) wud); + SetWindowLongPtr(hwnd, GWLP_USERDATA, (intptr_t) wud); #endif - // Not required (reducing redundant pain/update/size calls): - // ShowWindow(window, SW_SHOW); - // InvalidateRect(window, NULL, FALSE); - // UpdateWindow(window); // Issue WM_PAINT to clear window! - // send insets before visibility, allowing java code a proper sync point! - UpdateInsets(env, wud, window); + UpdateInsets(env, wud, hwnd); if( TST_FLAG_IS_AUTOPOSITION(flags) ) { RECT rc; - GetWindowRect(window, &rc); - x = rc.left + wud->insets.left; // client coords - y = rc.top + wud->insets.top; // client coords - wud->xpos = x; - wud->ypos = y; - } - DBG_PRINT("*** WindowsWindow: CreateWindow client: %d/%d %dx%d (autoPosition %d)\n", - x, y, width, height, TST_FLAG_IS_AUTOPOSITION(flags)); - - NewtWindow_setVisiblePosSize(wud, window, flags, TRUE, x, y, width, height); - - DBG_PRINT("*** WindowsWindow: CreateWindow pos/size set: %d/%d %dx%d, focused %d, visible %d\n", - wud->xpos, wud->ypos, wud->width, wud->height, wud->focused, wud->visible); - wud->isInCreation = FALSE; - - if( wud->isMaximized ) { - (*env)->CallVoidMethod(env, wud->jinstance, maximizedChangedID, JNI_TRUE, JNI_TRUE); - } - (*env)->CallVoidMethod(env, wud->jinstance, sizePosInsetsFocusVisibleChangedID, JNI_FALSE, - (jint)wud->xpos, (jint)wud->ypos, - (jint)wud->width, (jint)wud->height, - (jint)wud->insets.left, (jint)wud->insets.right, (jint)wud->insets.top, (jint)wud->insets.bottom, - (jboolean)wud->focused, - (jboolean)wud->visible, - JNI_FALSE); - DBG_PRINT("*** WindowsWindow: CreateWindow JNI callbacks done\n"); - - if( wud->supportsMTouch ) { - WinTouch_RegisterTouchWindow(window, 0); + GetWindowRect(hwnd, &rc); + xpos = rc.left + wud->insets.left; // client coords + ypos = rc.top + wud->insets.top; // client coords + wud->xpos = xpos; + wud->ypos = ypos; } + DBG_PRINT("*** WindowsWindow: CreateWindow client: %d/%d %dx%d -> %d/%d %dx%d (autoPosition %d)\n", + xpos, ypos, width, height, + wud->xpos, wud->ypos, wud->width, wud->height, + TST_FLAG_IS_AUTOPOSITION(flags)); } #ifdef UNICODE @@ -2390,9 +2361,50 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo hookMP = SetWindowsHookEx(WH_MOUSE_LL, &HookMouseProc, (HINSTANCE) (intptr_t) hInstance, 0); DBG_PRINT("**** LLMP Hook %p, MP Hook %p\n", hookLLMP, hookMP); #endif + DBG_PRINT("*** WindowsWindow: CreateWindow done\n"); + return (jlong) (intptr_t) hwnd; +} + +/* + * Class: jogamp_newt_driver_windows_WindowDriver + * Method: InitWindow + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_InitWindow0 + (JNIEnv *env, jobject obj, jlong window, jint flags) +{ + HWND hwnd = (HWND) (intptr_t) window; + WindowUserData * wud; +#if !defined(__MINGW64__) && ( defined(UNDER_CE) || _MSC_VER <= 1200 ) + wud = (WindowUserData *) GetWindowLong(hwnd, GWL_USERDATA); +#else + wud = (WindowUserData *) GetWindowLongPtr(hwnd, GWLP_USERDATA); +#endif + + DBG_PRINT("*** WindowsWindow: InitWindow start %d/%d %dx%d, focused %d, visible %d\n", + wud->xpos, wud->ypos, wud->width, wud->height, wud->focused, wud->visible); + + NewtWindow_setVisiblePosSize(wud, hwnd, flags, TRUE, wud->xpos, wud->ypos, wud->width, wud->height); + wud->isInCreation = FALSE; + + DBG_PRINT("*** WindowsWindow: InitWindow pos/size set: %d/%d %dx%d, focused %d, visible %d\n", + wud->xpos, wud->ypos, wud->width, wud->height, wud->focused, wud->visible); - return (jlong) (intptr_t) window; + if( wud->isMaximized ) { + (*env)->CallVoidMethod(env, wud->jinstance, maximizedChangedID, JNI_TRUE, JNI_TRUE); + } + (*env)->CallVoidMethod(env, wud->jinstance, sizePosInsetsFocusVisibleChangedID, JNI_FALSE, + (jint)wud->xpos, (jint)wud->ypos, + (jint)wud->width, (jint)wud->height, + (jint)wud->insets.left, (jint)wud->insets.right, (jint)wud->insets.top, (jint)wud->insets.bottom, + (jboolean)wud->focused, + (jboolean)wud->visible, + JNI_FALSE); + DBG_PRINT("*** WindowsWindow: InitWindow JNI callbacks done\n"); + + if( wud->supportsMTouch ) { + WinTouch_RegisterTouchWindow(hwnd, 0); + } } /* |