aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2015-10-01 23:36:54 +0200
committerSven Gothel <[email protected]>2015-10-01 23:36:54 +0200
commita9b3f6d13b45284e81b91a1e1e31b35c31dd3670 (patch)
tree1a2550bc440cb27476d9d9a328600dc4b5fb296b
parent4b0be44f54a7d89192c03725a16e396eba98a712 (diff)
Bug 1232 - NEWT Translucent Decorated Windows Not Working On Windows >= 8 (Lack of Aero / Blur )
Adopting new undocumented user32.dll Windows >= 8 API: - SetWindowCompositionAttribute / AccentState See: - <https://github.com/riverar/sample-win10-aeroglass/blob/master/MainWindow.xaml.cs> - <http://withinrafael.com/adding-the-aero-glass-blur-to-your-windows-10-apps/> - <http://undoc.airesoft.co.uk/user32.dll/SetWindowCompositionAttribute.php> - <http://undoc.airesoft.co.uk/user32.dll/GetWindowCompositionAttribute.php> +++ Cleaning up WindowsDWM.h, use on header file (in stub_includes) for GlueGen and implementation. +++ Merge java implementation within GDIUtil.DwmSetupTranslucency(..), to be utilized by NEWT and JOGL. NEWT issues GDIUtil.DwmSetupTranslucency(..) at creation and when toggling decoration. Toggling decoration on Win >= 8 leads to lost of translucency when returning to decorated window. On Win 7, this may work .. but is also buggy. +++ Followup patch is needed for NEWT to _not_ clear the background!
-rw-r--r--make/build-nativewindow.xml5
-rw-r--r--make/config/nativewindow/win32-lib.cfg7
-rw-r--r--make/stub_includes/win32/WindowsDWM.h91
-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.java19
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java79
-rw-r--r--src/nativewindow/native/win32/WindowsDWM.c115
-rw-r--r--src/nativewindow/native/win32/WindowsDWM.h34
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java14
-rw-r--r--src/newt/native/WindowsWindow.c128
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);
+ }
}
/*