summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-01-31 07:35:58 +0100
committerSven Gothel <[email protected]>2023-01-31 07:35:58 +0100
commit97b79ad351e48e7d3c6f9c95bacdf4f9d5d158ef (patch)
tree0945989bcd6ffbe87f295f422002b3055a1e082d
parent6eb13066996e94b2fe40bf64e74ea43d8f4e9171 (diff)
NEWT Soft-PixelScale (p6): Implement Soft-PixelScale for X11 and Windows ... (working state)
Both: - Using Soft-PixelScale mode, i.e. converting all given window-units to pixel-units for native GDI/X11 ops - Using scaled pixel-sized surface - Adjusting NEWT's Monitor's window-unit viewport value to pixel-scale For X11: - Using global scale factor from environment variable, either: "GDK_SCALE", "QT_SCALE_FACTOR" or "SOFT_SCALE". The latter is for testing only. See https://wiki.archlinux.org/title/HiDPI For Windows: - Using actual monitor's pixel-scale via native SHC API (Shellscaling API, shcore.dll) Misc: - SurfaceScaleUtils.getGlobalPixelScaleEnv() reads a float value from given env names, first come, first serve - MonitorModeProps.streamInMonitorDevice(..): Add `invscale_wuviewport` argument to scale wuvieport for soft-pixel-scale - TestGearsNEWT: Enhance GL2 demo to be suitable for manual tests, this since my Windows KVM machine doesn't support ES2 - TestGLContextDrawableSwitch10NEWT: Add a few more test constraints .. working Tested: - Manually on a Windows virtual machine (KVM) using - 2 virtualized 'Video QXL' cards and - and 'remote-viewer' to see the 2 monitors since `Virtual Machine Manager` build-in doesn't support - remote-viewer spice://localhost:5917 - Manually on a Linux machine w/ SOFT_SCALE - Both, X11 and Windows - Place window on each monitor - Move window across monitors w/ pixel-scale change (or not) - TODO: Test and fix utilization with AWT, i.e. NewtCanvasAWT
-rwxr-xr-xmake/scripts/tests-win.bat4
-rwxr-xr-xmake/scripts/tests-x64-dbg.bat4
-rw-r--r--make/scripts/tests.sh10
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java46
-rw-r--r--src/newt/classes/jogamp/newt/MonitorModeProps.java18
-rw-r--r--src/newt/classes/jogamp/newt/ScreenImpl.java6
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java5
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/ios/ScreenDriver.java3
-rw-r--r--src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java3
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java123
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java26
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java101
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch10NEWT.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java65
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java2
23 files changed, 373 insertions, 65 deletions
diff --git a/make/scripts/tests-win.bat b/make/scripts/tests-win.bat
index a03c40cc5..7e37a1e94 100755
--- a/make/scripts/tests-win.bat
+++ b/make/scripts/tests-win.bat
@@ -5,7 +5,7 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestMainVersion
REM scripts\java-win.bat com.jogamp.oculusvr.OVRVersion %*
REM
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper %*
-REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT -time 30000
+scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 4000 -x 10 -y 10 -width 100 -height 100 -screen 0
@@ -188,7 +188,7 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02aN
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02bNEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.ManualScreenMode03sNEWT %*
-scripts\java-win.bat com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT
+REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.TestCloseNewtAWT
REM scripts\java-win.bat testawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES1AWT %*
diff --git a/make/scripts/tests-x64-dbg.bat b/make/scripts/tests-x64-dbg.bat
index 4e19bddd8..827453871 100755
--- a/make/scripts/tests-x64-dbg.bat
+++ b/make/scripts/tests-x64-dbg.bat
@@ -72,7 +72,7 @@ REM set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.GLJPanel"
REM set D_ARGS="-Djogl.gljpanel.noverticalflip"
REM set D_ARGS="-Dnewt.debug=all"
REM set D_ARGS="-Dnewt.debug.Window"
-set D_ARGS="-Dnativewindow.debug.SWT" "-Dnewt.debug.Window" "-Djogl.debug.GLCanvas"
+REM set D_ARGS="-Dnativewindow.debug.SWT" "-Dnewt.debug.Window" "-Djogl.debug.GLCanvas"
REM set D_ARGS="-Dnativewindow.debug.JFX" "-Dnewt.debug.Window"
REM set D_ARGS="-Dnewt.debug.Window.KeyEvent"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Window.KeyEvent" "-Dnewt.debug.EDT"
@@ -88,7 +88,7 @@ REM set D_ARGS="-Dnewt.debug.Display" "-Dnewt.debug.EDT" "-Dnewt.debug.Window"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display" "-Dnewt.debug.EDT" "-Djogl.debug.GLContext"
REM set D_ARGS="-Dnewt.debug.Screen" "-Dnewt.debug.EDT" "-Dnativewindow.debug=all"
REM set D_ARGS="-Dnewt.debug.Screen"
-REM set D_ARGS="-Dnewt.debug.Screen" "-Dnewt.debug.Window"
+set D_ARGS="-Dnewt.debug.Screen" "-Dnewt.debug.Window"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display" "-Dnewt.test.Window.reparent.incompatible=true"
REM set D_ARGS="-Djogamp.debug.ReflectionUtil" "-Djogamp.debug.ReflectionUtil.forNameStats"
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index d5f7a5a66..dfa9bbec2 100644
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -70,7 +70,7 @@ fi
#export LIBGL_DEBUG=verbose
#export MESA_DEBUG=true
-#export LIBGL_ALWAYS_SOFTWARE=true
+export LIBGL_ALWAYS_SOFTWARE=true
#export INTEL_DEBUG="buf bat"
#export INTEL_STRICT_CONFORMANCE=1
@@ -242,7 +242,7 @@ function jrun() {
#D_ARGS="-Djogl.1thread=true -Djogl.debug.Threading"
#D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL -Djogl.debug.GLContext.TraceSwitch -Djogl.debug=all"
#D_ARGS="-Djogl.debug.GLArrayData"
- #D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.Window"
+ D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.Window"
#D_ARGS="-Dnewt.debug.Window"
#D_ARGS="-Dnewt.debug.Screen"
#D_ARGS="-Dnewt.window.icons=null,null"
@@ -981,7 +981,11 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01 $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelAWT $*
-testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT
+#testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT2 $*
+testnoawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch10NEWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch11NewtAWT $*
# Linux DRM/GBM
#
diff --git a/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java b/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java
index f5804cd12..c732151e5 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java
@@ -28,6 +28,10 @@
*/
package jogamp.nativewindow;
+import java.security.PrivilegedAction;
+import java.util.Map;
+
+import com.jogamp.common.util.SecurityUtil;
import com.jogamp.nativewindow.ScalableSurface;
/**
@@ -222,4 +226,46 @@ public class SurfaceScaleUtils {
result[1] = resultY;
return changed;
}
+
+ /**
+ * Get global pixel-scale values from environment variables, e.g.:
+ * - QT_SCALE_FACTOR
+ * - GDK_SCALE
+ * See https://wiki.archlinux.org/title/HiDPI
+ * @param env_var_names array of potential environment variable names, treated as float.
+ * @param pixel_scale_xy store for resulting scale factors
+ * @return index of first found variable name within env_var_names, otherwise -1
+ */
+ public static int getGlobalPixelScaleEnv(final String[] env_var_names, final float[] pixel_scale_xy) {
+ final Map<String, String> env = SecurityUtil.doPrivileged(new PrivilegedAction<Map<String, String>>() {
+ @Override
+ public Map<String, String> run() {
+ return System.getenv();
+ }
+ });
+ float value = -1.0f;
+ boolean done = false;
+ int var_idx = 0;
+ while( var_idx < env_var_names.length && !done ) {
+ final String env_var_name = env_var_names[var_idx];
+ final String s_value = env.get(env_var_name);
+ if( null != s_value ) {
+ try {
+ value = Float.valueOf(s_value);
+ done = true;
+ } catch(final NumberFormatException nfe) {
+ ++var_idx;
+ }
+ } else {
+ ++var_idx;
+ }
+ }
+ if( done ) {
+ pixel_scale_xy[0] = value;
+ pixel_scale_xy[1] = value;
+ return var_idx;
+ } else {
+ return -1;
+ }
+ }
}
diff --git a/src/newt/classes/jogamp/newt/MonitorModeProps.java b/src/newt/classes/jogamp/newt/MonitorModeProps.java
index 873ee3ed6..292551559 100644
--- a/src/newt/classes/jogamp/newt/MonitorModeProps.java
+++ b/src/newt/classes/jogamp/newt/MonitorModeProps.java
@@ -273,6 +273,7 @@ public class MonitorModeProps {
* @param screen the associated {@link ScreenImpl}
* @param monitor_handle unique monitor long handle, implementation specific
* @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}.
+ * @param invscale_wuviewport if true, the viewport in window-units will be scaled by 1/pixelScale for soft-pixel-scale
* @param monitorProperties the input data inclusive supported modes.
* @param offset the offset to the input data
* @param monitor_idx if not null, returns the index of resulting {@link MonitorDevice} within {@link Cache#monitorDevices}.
@@ -281,8 +282,8 @@ public class MonitorModeProps {
*/
public static MonitorDevice streamInMonitorDevice(final Cache cache, final ScreenImpl screen,
final long monitor_handle,
- final float[] pixelScale, final int[] monitorProperties,
- int offset, final int[] monitor_idx) {
+ final float[] pixelScale, final boolean invscale_wuviewport,
+ final int[] monitorProperties, int offset, final int[] monitor_idx) {
// min 11: count, id, ScreenSizeMM[width, height], Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+
final int count = monitorProperties[offset];
if(MIN_MONITOR_DEVICE_PROPERTIES > count) {
@@ -303,6 +304,9 @@ public class MonitorModeProps {
final DimensionImmutable sizeMM = streamInResolution(monitorProperties, offset); offset+=NUM_RESOLUTION_PROPERTIES;
final Rectangle viewportPU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]);
final Rectangle viewportWU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]);
+ if( invscale_wuviewport && null != pixelScale ) {
+ viewportWU.scaleInv(pixelScale[0], pixelScale[1]);
+ }
final MonitorMode currentMode;
{
final int modeId = monitorProperties[offset++];
@@ -360,6 +364,7 @@ public class MonitorModeProps {
* @param monitor_handle unique monitor long handle, implementation specific
* @param currentMode pre-fetched current {@link MonitorMode}s from cache.
* @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}.
+ * @param invscale_wuviewport if true, the viewport in window-units will be scaled by 1/pixelScale for soft-pixel-scale
* @param supportedModes pre-assembled list of supported {@link MonitorMode}s from cache.
* @param monitorProperties the input data minus supported modes!
* @param offset the offset to the input data
@@ -371,9 +376,9 @@ public class MonitorModeProps {
final long monitor_handle,
final MonitorMode currentMode,
final float[] pixelScale,
- final ArrayHashSet<MonitorMode> supportedModes,
- final int[] monitorProperties, int offset,
- final int[] monitor_idx) {
+ final boolean invscale_wuviewport,
+ final ArrayHashSet<MonitorMode> supportedModes, final int[] monitorProperties,
+ int offset, final int[] monitor_idx) {
// min 11: count, id, ScreenSizeMM[width, height], Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+
final int count = monitorProperties[offset];
if(MIN_MONITOR_DEVICE_PROPERTIES - 1 - NUM_MONITOR_MODE_PROPERTIES != count) {
@@ -392,6 +397,9 @@ public class MonitorModeProps {
final DimensionImmutable sizeMM = streamInResolution(monitorProperties, offset); offset+=NUM_RESOLUTION_PROPERTIES;
final Rectangle viewportPU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]);
final Rectangle viewportWU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]);
+ if( invscale_wuviewport && null != pixelScale ) {
+ viewportWU.scaleInv(pixelScale[0], pixelScale[1]);
+ }
MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, monitor_handle, monitor_id, isClone, isPrimary,
sizeMM, currentMode, pixelScale,
viewportPU, viewportWU, supportedModes);
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
index 1dba31d4f..d90ee73bb 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -360,8 +360,8 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
* <li>{@link MonitorModeProps#MIN_MONITOR_DEVICE_PROPERTIES}</li>
* </ul>, i.e.
* <ul>
- * <li>{@link MonitorModeProps#streamInMonitorDevice(jogamp.newt.MonitorModeProps.Cache, ScreenImpl, long, double[], int[], int, int[])}</li>
- * <li>{@link MonitorModeProps#streamInMonitorDevice(int[], jogamp.newt.MonitorModeProps.Cache, long, ArrayHashSet, int[], int, ScreenImpl)}</li>
+ * <li>{@link MonitorModeProps#streamInMonitorDevice(jogamp.newt.MonitorModeProps.Cache, ScreenImpl, long, double[], boolean, int[], int, int[])}</li>
+ * <li>{@link MonitorModeProps#streamInMonitorDevice(int[], jogamp.newt.MonitorModeProps.Cache, long, ArrayHashSet, boolean, int[], int, ScreenImpl)}</li>
* <li>{@link MonitorModeProps#streamInMonitorMode(int[], jogamp.newt.MonitorModeProps.Cache, int[], int)}</li>
* </ul>
* @param cache memory pool caching the result
@@ -520,7 +520,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
if( MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES != i ) {
throw new InternalError("XX");
}
- return MonitorModeProps.streamInMonitorDevice(cache, this, monitorId, null, props, 0, null);
+ return MonitorModeProps.streamInMonitorDevice(cache, this, monitorId, null, false /* invscale_wuviewport */, props, 0, null);
}
/**
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index ef8c4916d..ae63c4539 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -2966,12 +2966,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
boolean res = false;
if( DEBUG_IMPLEMENTATION ) {
System.err.println("Window.SoftPixelScale.0a: req "+reqPixelScale[0]+", has "+hasPixelScale[0]+", new "+newPixelScale[0]+" - "+getThreadName());
- Thread.dumpStack();
+ // Thread.dumpStack();
}
synchronized( scaleLock ) {
- if( DEBUG_IMPLEMENTATION ) {
- System.err.println("Window.SoftPixelScale.0b: req "+reqPixelScale[0]+", has "+hasPixelScale[0]+", new "+newPixelScale[0]+" - "+getThreadName());
- }
try {
res = applySoftPixelScaleImpl(move_diff, sendEvent, defer, newPixelScale);
} finally {
diff --git a/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java
index 3c0b1aef4..8d73592b5 100644
--- a/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java
@@ -116,7 +116,7 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl {
props[i++] = 0; // rotated viewport y window-units
props[i++] = outMetrics.widthPixels; // rotated viewport width window-units
props[i++] = outMetrics.heightPixels; // rotated viewport height window-units
- MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, cache.monitorModes, props, 0, null);
+ MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, false, cache.monitorModes, props, 0, null);
}
@Override
diff --git a/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java
index d577ed501..fc4bf03a4 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java
@@ -122,7 +122,7 @@ public class ScreenDriver extends ScreenImpl {
props[i++] = 0; // rotated viewport y window-units
props[i++] = currentMode.getRotatedWidth(); // rotated viewport width window-units
props[i++] = currentMode.getRotatedHeight(); // rotated viewport height window-units
- MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, cache.monitorModes, props, 0, null);
+ MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, false, cache.monitorModes, props, 0, null);
}
@Override
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java
index 62dbd0c72..3cdb368f2 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java
@@ -97,7 +97,7 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl {
props[i++] = 0; // rotated viewport y window-units
props[i++] = fixedWidth; // FIXME rotated viewport width window-units
props[i++] = fixedHeight; // FIXME rotated viewport height window-units
- MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, cache.monitorModes, props, 0, null);
+ MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, false, cache.monitorModes, props, 0, null);
}
@Override
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java
index 9e05e1002..1b3807a94 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java
@@ -90,7 +90,7 @@ public class ScreenDriver extends ScreenImpl {
props[i++] = 0; // rotated viewport y window-units
props[i++] = cachedWidth; // rotated viewport width window-units
props[i++] = cachedHeight; // rotated viewport height window-units
- MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, cache.monitorModes, props, 0, null);
+ MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, false, cache.monitorModes, props, 0, null);
}
@Override
diff --git a/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java
index 5281f0ddc..a08b5a445 100644
--- a/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java
@@ -129,7 +129,7 @@ public class ScreenDriver extends ScreenImpl {
props[i++] = 0; // rotated viewport y window-units
props[i++] = mode[scridx].getHdisplay(); // rotated viewport width window-units
props[i++] = mode[scridx].getVdisplay(); // rotated viewport height window-units
- MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, cache.monitorModes, props, 0, null);
+ MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, false, cache.monitorModes, props, 0, null);
crtc_ids = new int[] { encoder[scridx].getCrtc_id() };
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java
index ceb2c4cc6..7eb6eea92 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java
@@ -99,7 +99,7 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl {
props[i++] = 0; // rotated viewport y window-units
props[i++] = cachedWidth; // rotated viewport width window-units
props[i++] = cachedWidth; // rotated viewport height window-units
- MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, cache.monitorModes, props, 0, null);
+ MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, false, cache.monitorModes, props, 0, null);
}
@Override
diff --git a/src/newt/classes/jogamp/newt/driver/ios/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/ios/ScreenDriver.java
index de5cdd239..4cf459699 100644
--- a/src/newt/classes/jogamp/newt/driver/ios/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/ios/ScreenDriver.java
@@ -177,7 +177,8 @@ public class ScreenDriver extends ScreenImpl {
// merge monitor-props + supported modes
final float pixelScale = crtProps.pixelScaleArray[crtIdx];
MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode,
- new float[] { pixelScale, pixelScale }, supportedModes, crtProps.propsFixedArray[crtIdx], 0, null);
+ new float[] { pixelScale, pixelScale }, false /* invscale_wuviewport */,
+ supportedModes, crtProps.propsFixedArray[crtIdx], 0, null);
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
index 3112aa88f..ba28e161d 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
@@ -95,7 +95,7 @@ public class ScreenDriver extends ScreenImpl {
props[i++] = 0; // rotated viewport y window-units
props[i++] = cachedWidth; // rotated viewport width window-units
props[i++] = cachedWidth; // rotated viewport height window-units
- MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, cache.monitorModes, props, 0, null);
+ MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, false, cache.monitorModes, props, 0, null);
}
@Override
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java
index a4823034f..635fffc0b 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java
@@ -183,7 +183,8 @@ public class ScreenDriver extends ScreenImpl {
// merge monitor-props + supported modes
final float pixelScale = crtProps.pixelScaleArray[crtIdx];
MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode,
- new float[] { pixelScale, pixelScale }, supportedModes, crtProps.propsFixedArray[crtIdx], 0, null);
+ new float[] { pixelScale, pixelScale }, false /* invscale_wuviewport */,
+ supportedModes, crtProps.propsFixedArray[crtIdx], 0, null);
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
index 002836e0c..c3aa94648 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
@@ -143,7 +143,8 @@ public class ScreenDriver extends ScreenImpl {
monitor_handle = monitor_id;
}
// merge monitor-props + supported modes
- MonitorModeProps.streamInMonitorDevice(cache, this, monitor_handle, currentMode, pixel_scale, supportedModes, monitorProps, 0, null);
+ MonitorModeProps.streamInMonitorDevice(cache, this, monitor_handle, currentMode, pixel_scale, true /* invscale_wuviewport */,
+ supportedModes, monitorProps, 0, null);
// next monitor, 1st mode
supportedModes = new ArrayHashSet<MonitorMode>(false, ArrayHashSet.DEFAULT_INITIAL_CAPACITY, ArrayHashSet.DEFAULT_LOAD_FACTOR);
@@ -168,6 +169,7 @@ public class ScreenDriver extends ScreenImpl {
int offset = MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT;
viewportPU.set(monitorProps[offset++], monitorProps[offset++], monitorProps[offset++], monitorProps[offset++]);
viewportWU.set(monitorProps[offset++], monitorProps[offset++], monitorProps[offset++], monitorProps[offset++]);
+ viewportWU.scaleInv(pixelScale[0], pixelScale[1]);
return true;
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
index fb20265ce..1605d4126 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
@@ -36,6 +36,7 @@ package jogamp.newt.driver.windows;
import java.nio.ByteBuffer;
+import jogamp.nativewindow.SurfaceScaleUtils;
import jogamp.nativewindow.windows.GDI;
import jogamp.nativewindow.windows.GDIUtil;
import jogamp.newt.PointerIconImpl;
@@ -47,11 +48,12 @@ import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.nativewindow.VisualIDHolder;
import com.jogamp.nativewindow.util.InsetsImmutable;
import com.jogamp.nativewindow.util.Point;
-
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.VersionNumber;
+import com.jogamp.newt.MonitorDevice;
import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.MonitorEvent;
import com.jogamp.newt.event.MouseEvent;
import com.jogamp.newt.event.MouseEvent.PointerType;
@@ -61,7 +63,7 @@ public class WindowDriver extends WindowImpl {
DisplayDriver.initSingleton();
}
- private long hmon;
+ private volatile long hmon;
private long hdc;
private long hdc_old;
private long windowHandleClose;
@@ -69,6 +71,20 @@ public class WindowDriver extends WindowImpl {
public WindowDriver() {
}
+ /**
+ * Essentially updates {@code hasPixelScale}
+ */
+ private boolean updatePixelScaleByMonitor(final long crt_handle, final int[] move_diff, final boolean sendEvent, final boolean defer) {
+ boolean res = false;
+ if( 0 != crt_handle ) {
+ final float newPixelScaleRaw[] = { 0, 0 };
+ if( GDIUtil.GetMonitorPixelScale(crt_handle, newPixelScaleRaw) ) {
+ res = applySoftPixelScale(move_diff, sendEvent, defer, newPixelScaleRaw);
+ }
+ }
+ return res;
+ }
+
@Override
protected int lockSurfaceImpl() {
if (0 != hdc) {
@@ -81,7 +97,14 @@ public class WindowDriver extends WindowImpl {
if( 0 == hdc ) {
return LOCK_SURFACE_NOT_READY;
}
- hmon = MonitorFromWindow0(hWnd);
+ if(DEBUG_IMPLEMENTATION) {
+ final long _hmon = GDIUtil.GetMonitorFromWindow(hWnd);
+ if (hmon != _hmon) {
+ System.err.println("Info: Window Device Changed (L) "+getThreadName()+
+ ", HMON "+toHexString(hmon)+" -> "+toHexString(_hmon));
+ // Thread.dumpStack();
+ }
+ }
// Let's not trigger on HDC change, GLDrawableImpl.'s destroy/create is a nop here anyways.
// FIXME: Validate against EGL surface creation: ANGLE uses HWND -> fine!
@@ -113,20 +136,27 @@ public class WindowDriver extends WindowImpl {
}
@Override
- public boolean hasDeviceChanged() {
- if(0!=getWindowHandle()) {
- final long _hmon = MonitorFromWindow0(getWindowHandle());
- if (hmon != _hmon) {
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Info: Window Device Changed "+Thread.currentThread().getName()+
- ", HMON "+toHexString(hmon)+" -> "+toHexString(_hmon));
- // Thread.dumpStack();
- }
- hmon = _hmon;
- return true;
- }
+ protected void monitorModeChanged(final MonitorEvent me, final boolean success) {
+ if( hmon == me.getMonitor().getHandle() ) {
+ updatePixelScaleByMonitor(me.getMonitor().getHandle(), null, false /* sendEvent*/, false /* defer */); // send reshape event itself
}
- return false;
+ }
+
+ @Override
+ public final boolean setSurfaceScale(final float[] pixelScale) {
+ super.setSurfaceScale(pixelScale); // pixelScale -> reqPixelScale
+
+ boolean changed = false;
+ if( isNativeValid() ) {
+ changed = applySoftPixelScale(null, true /* sendEvent */, false /* defer */, reqPixelScale);
+ }
+ if( DEBUG_IMPLEMENTATION ) {
+ System.err.println("WindowDriver.setPixelScale: min["+minPixelScale[0]+", "+minPixelScale[1]+"], max["+
+ maxPixelScale[0]+", "+maxPixelScale[1]+"], req["+
+ reqPixelScale[0]+", "+reqPixelScale[1]+"] -> result["+
+ hasPixelScale[0]+", "+hasPixelScale[1]+"] - changed "+changed+", realized "+isNativeValid());
+ }
+ return changed;
}
@Override
@@ -150,10 +180,14 @@ public class WindowDriver extends WindowImpl {
flags |= CHANGE_MASK_MAXIMIZED_VERT;
maxCount++;
}
+ final int[] xy_pix = getPixelPosI();
+ final int[] sz_pix = getPixelSizeI();
+
+ // this.convertToWindowUnits(null)
final long _windowHandle = CreateWindow0(DisplayDriver.getHInstance(), display.getWindowClassName(), display.getWindowClassName(),
winVer.getMajor(), winVer.getMinor(),
getParentWindowHandle(),
- getX(), getY(), getWidth(), getHeight(), flags);
+ xy_pix[0], xy_pix[1], sz_pix[0], sz_pix[1], flags);
if ( 0 == _windowHandle ) {
throw new NativeWindowException("Error creating window");
}
@@ -164,10 +198,17 @@ public class WindowDriver extends WindowImpl {
setWindowHandle(_windowHandle);
windowHandleClose = _windowHandle;
- if( 0 == ( STATE_MASK_CHILDWIN & flags ) && 1 == maxCount ) {
- reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), flags);
+ if( 0 == ( STATE_MASK_CHILDWIN & flags ) && 1 <= maxCount ) {
+ reconfigureWindowImpl(xy_pix[0], xy_pix[1], sz_pix[0], sz_pix[1], flags);
}
+ hmon = GDIUtil.GetMonitorFromWindow(_windowHandle);
+ boolean changedPixelScale = applySoftPixelScale(null, true /* sendEvent */, false /* defer */, reqPixelScale);
+ if( !changedPixelScale ) {
+ changedPixelScale = updatePixelScaleByMonitor(hmon, null, true /* sendEvent */, false /* defer */);
+ }
+ positionModified[0] = changedPixelScale;
+
if(DEBUG_IMPLEMENTATION) {
final Exception e = new Exception("Info: Window new window handle "+Thread.currentThread().getName()+
" (Parent HWND "+toHexString(getParentWindowHandle())+
@@ -201,6 +242,7 @@ public class WindowDriver extends WindowImpl {
windowHandleClose = 0;
hdc = 0;
hdc_old = 0;
+ hmon = 0;
}
@Override
@@ -244,7 +286,11 @@ public class WindowDriver extends WindowImpl {
if( changeDecoration && isTranslucent ) {
GDIUtil.DwmSetupTranslucency(getWindowHandle(), false);
}
- reconfigureWindow0( getParentWindowHandle(), getWindowHandle(), x, y, width, height, flags);
+ final int xy_pix[] = SurfaceScaleUtils.scale(new int[2], x, y, hasPixelScale);
+ final int sz_pix[] = SurfaceScaleUtils.scale(new int[2], width, height, hasPixelScale);
+ reconfigureWindow0( getParentWindowHandle(), getWindowHandle(),
+ xy_pix[0], xy_pix[1], sz_pix[0], sz_pix[1], flags);
+
if( changeDecoration && isTranslucent ) {
GDIUtil.DwmSetupTranslucency(getWindowHandle(), true);
}
@@ -259,6 +305,37 @@ public class WindowDriver extends WindowImpl {
}
@Override
+ protected boolean positionChanged(final boolean defer, final boolean windowUnits, final int newX, final int newY) {
+ final boolean res = super.positionChanged(defer, windowUnits, newX, newY);
+
+ if ( res ) {
+ final long hWnd = getWindowHandle();
+ if( 0 != hWnd ) {
+ final long _hmon = GDIUtil.GetMonitorFromWindow(hWnd);
+ if( hmon != _hmon ) {
+ final int[] move_diff = new int[] { 0, 0 };
+ MonitorDevice.Orientation orientation = MonitorDevice.Orientation.clone;
+ // Move from md0 -> md1
+ final MonitorDevice md0 = getScreen().getMonitorByHandle(hmon);
+ final MonitorDevice md1 = getScreen().getMonitorByHandle(_hmon);
+ if( null != md0 && null != md1 ) {
+ orientation = md1.getOrientationTo(md0, move_diff);
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Info: Window Device Changed (P: "+newX+"/"+newY+
+ ", crt_move[orient "+orientation+", diff "+move_diff[0]+"/"+move_diff[1]+") "+
+ ", HMON "+toHexString(hmon)+" -> "+toHexString(_hmon)+
+ " - "+Thread.currentThread().getName());
+ }
+ hmon = _hmon;
+ updatePixelScaleByMonitor(_hmon, move_diff, true /* sendEvent */, defer);
+ }
+ }
+ }
+ return res;
+ }
+
+ @Override
protected void requestFocusImpl(final boolean force) {
requestFocus0(getWindowHandle(), force);
}
@@ -307,7 +384,8 @@ public class WindowDriver extends WindowImpl {
this.runOnEDTIfAvail(true, new Runnable() {
@Override
public void run() {
- final Point sPos = convertToPixelUnits( getLocationOnScreenImpl(x, y) );
+ // shortcut from getLocationOnScreenImpl(..) while maintaining pixel-units
+ final Point sPos = GDIUtil.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y );
warpPointer0(getWindowHandle(), sPos.getX(), sPos.getY());
}
});
@@ -316,7 +394,8 @@ public class WindowDriver extends WindowImpl {
@Override
protected Point getLocationOnScreenImpl(final int x, final int y) {
- return GDIUtil.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y);
+ final int xy_pix[] = SurfaceScaleUtils.scale(new int[2], x, y, hasPixelScale);
+ return convertToWindowUnits( GDIUtil.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, xy_pix[0], xy_pix[1]) );
}
//
diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
index 7fb70cc32..c6b91cbf6 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
@@ -37,9 +37,11 @@ import java.util.ArrayList;
import java.util.List;
import com.jogamp.nativewindow.AbstractGraphicsDevice;
+import com.jogamp.nativewindow.ScalableSurface;
import com.jogamp.nativewindow.util.Rectangle;
import com.jogamp.nativewindow.util.RectangleImmutable;
+import jogamp.nativewindow.SurfaceScaleUtils;
import jogamp.nativewindow.x11.X11Util;
import jogamp.newt.Debug;
import jogamp.newt.DisplayImpl;
@@ -57,11 +59,27 @@ import com.jogamp.newt.MonitorMode;
public class ScreenDriver extends ScreenImpl {
protected static final boolean DEBUG_TEST_RANDR13_DISABLED;
+ protected static final float[] global_pixel_scale = new float[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE };
+ protected static final boolean global_pixel_scale_set;
static {
Debug.initSingleton();
DEBUG_TEST_RANDR13_DISABLED = PropertyAccess.isPropertyDefined("newt.test.Screen.disableRandR13", true);
+ final String[] env_var_names = new String[] { "GDK_SCALE", "QT_SCALE_FACTOR", "SOFT_SCALE" };
+ int var_name_idx = -1;
+ try {
+ var_name_idx = SurfaceScaleUtils.getGlobalPixelScaleEnv(env_var_names, global_pixel_scale);
+ } catch (final Throwable t) { t.printStackTrace(); }
+ if( 0 <= var_name_idx && var_name_idx < env_var_names.length ) {
+ global_pixel_scale_set = true;
+ if( DEBUG ) {
+ System.err.println("X11Screen: Global PixelScale Set: "+env_var_names[var_name_idx]+": "+global_pixel_scale[0]+"/"+global_pixel_scale[1]);
+ }
+ } else {
+ global_pixel_scale_set = false;
+ }
+
DisplayDriver.initSingleton();
}
@@ -120,6 +138,10 @@ public class ScreenDriver extends ScreenImpl {
try {
if( rAndR.beginInitialQuery(device.getHandle(), this) ) {
try {
+ final float pixel_scale[] = { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE };
+ if( global_pixel_scale_set ) {
+ System.arraycopy(global_pixel_scale, 0, pixel_scale, 0, 2);
+ }
final int[] crt_ids = rAndR.getMonitorDeviceIds(device.getHandle(), this);
final int crtCount = null != crt_ids ? crt_ids.length : 0;
@@ -155,7 +177,8 @@ public class ScreenDriver extends ScreenImpl {
if( null != monitorProps &&
MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES <= monitorProps[0] && // Enabled ? I.e. contains active modes ?
MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES <= monitorProps.length ) {
- MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, null, monitorProps, 0, null);
+ MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, pixel_scale, true /* invscale_wuviewport */,
+ monitorProps, 0, null);
}
}
}
@@ -177,6 +200,7 @@ public class ScreenDriver extends ScreenImpl {
if( null != viewportProps ) {
viewportPU.set(viewportProps[0], viewportProps[1], viewportProps[2], viewportProps[3]);
viewportWU.set(viewportProps[0], viewportProps[1], viewportProps[2], viewportProps[3]); // equal window-units and pixel-units
+ viewportWU.scaleInv(pixelScale[0], pixelScale[1]);
return true;
} else {
return false;
diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
index c1a24797b..38c463e7c 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
@@ -36,6 +36,8 @@ package jogamp.newt.driver.x11;
import java.nio.Buffer;
+import jogamp.nativewindow.SurfaceScaleUtils;
+import jogamp.nativewindow.windows.GDIUtil;
import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
import jogamp.newt.DisplayImpl;
@@ -53,9 +55,11 @@ import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.nio.Buffers;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
+import com.jogamp.newt.MonitorDevice;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.MonitorEvent;
import com.jogamp.newt.event.MouseEvent;
public class WindowDriver extends WindowImpl {
@@ -68,6 +72,8 @@ public class WindowDriver extends WindowImpl {
private static final int defaultIconDataSize;
private static final Buffer defaultIconData;
+ private volatile MonitorDevice last_monitor;
+
static {
ScreenDriver.initSingleton();
@@ -94,8 +100,45 @@ public class WindowDriver extends WindowImpl {
public WindowDriver() {
}
+ /**
+ * Essentially updates {@code hasPixelScale}
+ */
+ private boolean updatePixelScaleByMonitor(final MonitorDevice md, final int[] move_diff, final boolean sendEvent, final boolean defer) {
+ boolean res = false;
+ if( null != md ) {
+ final float newPixelScale[] = { 0, 0 };
+ md.getPixelScale(newPixelScale);
+ res = applySoftPixelScale(move_diff, sendEvent, defer, newPixelScale);
+ }
+ return res;
+ }
+
+ @Override
+ protected void monitorModeChanged(final MonitorEvent me, final boolean success) {
+ if( last_monitor == me.getMonitor() ) {
+ updatePixelScaleByMonitor(me.getMonitor(), null, false /* sendEvent*/, false /* defer */); // send reshape event itself
+ }
+ }
+
@Override
- protected void createNativeImpl(boolean[] positionModified) {
+ public final boolean setSurfaceScale(final float[] pixelScale) {
+ super.setSurfaceScale(pixelScale); // pixelScale -> reqPixelScale
+
+ boolean changed = false;
+ if( isNativeValid() ) {
+ changed = applySoftPixelScale(null, true /* sendEvent */, false /* defer */, reqPixelScale);
+ }
+ if( DEBUG_IMPLEMENTATION ) {
+ System.err.println("WindowDriver.setPixelScale: min["+minPixelScale[0]+", "+minPixelScale[1]+"], max["+
+ maxPixelScale[0]+", "+maxPixelScale[1]+"], req["+
+ reqPixelScale[0]+", "+reqPixelScale[1]+"] -> result["+
+ hasPixelScale[0]+", "+hasPixelScale[1]+"] - changed "+changed+", realized "+isNativeValid());
+ }
+ return changed;
+ }
+
+ @Override
+ protected void createNativeImpl(final boolean[] positionModified) {
final ScreenDriver screen = (ScreenDriver) getScreen();
final DisplayDriver display = (DisplayDriver) screen.getDisplay();
final AbstractGraphicsDevice edtDevice = display.getGraphicsDevice();
@@ -124,11 +167,14 @@ public class WindowDriver extends WindowImpl {
setGraphicsConfiguration(cfg);
final int flags = getReconfigureMask(0, true) & STATE_MASK_CREATENATIVE;
edtDevice.lock();
+
+ final int[] xy_pix = getPixelPosI();
+ final int[] sz_pix = getPixelSizeI();
try {
final long[] handles = CreateWindow(getParentWindowHandle(),
edtDevice.getHandle(), screen.getIndex(), visualID,
display.getJavaObjectAtom(), display.getWindowDeleteAtom(), display.getXiOpcode(),
- getX(), getY(), getWidth(), getHeight(), flags,
+ xy_pix[0], xy_pix[1], sz_pix[0], sz_pix[1], flags,
defaultIconDataSize, defaultIconData, DEBUG_IMPLEMENTATION);
if (null == handles || 2 != handles.length || 0 == handles[0] || 0 == handles[1] ) {
throw new NativeWindowException("Error creating window");
@@ -138,6 +184,14 @@ public class WindowDriver extends WindowImpl {
}
setWindowHandle(handles[0]);
javaWindowHandle = handles[1];
+
+ last_monitor = getMainMonitor();
+ boolean changedPixelScale = applySoftPixelScale(null, true /* sendEvent */, false /* defer */, reqPixelScale);
+ if( !changedPixelScale ) {
+ changedPixelScale = updatePixelScaleByMonitor(last_monitor, null, true /* sendEvent */, false /* defer */);
+ }
+ positionModified[0] = changedPixelScale;
+
} finally {
edtDevice.unlock();
}
@@ -160,6 +214,7 @@ public class WindowDriver extends WindowImpl {
} finally {
edtDevice.unlock();
javaWindowHandle = 0;
+ last_monitor = null;
}
}
if(null != renderDevice) {
@@ -200,9 +255,13 @@ public class WindowDriver extends WindowImpl {
_x = x;
_y = y;
}
+ final int xy_pix[] = SurfaceScaleUtils.scale(new int[2], _x, _y, hasPixelScale);
+ final int sz_pix[] = SurfaceScaleUtils.scale(new int[2], width, height, hasPixelScale);
+
if(DEBUG_IMPLEMENTATION) {
- System.err.println("X11Window reconfig.0: "+x+"/"+y+" -> "+_x+"/"+_y+" "+width+"x"+height+", insets "+_insets+
- ", "+getReconfigStateMaskString(flags));
+ System.err.println("X11Window reconfig.0: "+x+"/"+y+" -> "+_x+"/"+_y+" "+width+"x"+height+
+ " -> pixel["+xy_pix[0]+"/"+xy_pix[1]+" "+sz_pix[0]+"x"+sz_pix[1]+
+ "], insets "+_insets+", "+getReconfigStateMaskString(flags));
}
if( 0 != ( CHANGE_MASK_FULLSCREEN & flags ) ) {
if( 0 != ( STATE_MASK_FULLSCREEN & flags) &&
@@ -222,7 +281,7 @@ public class WindowDriver extends WindowImpl {
@Override
public Object run(final long dpy) {
reconfigureWindow0( dpy, getScreenIndex(),
- getParentWindowHandle(), javaWindowHandle, _x, _y, width, height, fflags);
+ getParentWindowHandle(), javaWindowHandle, xy_pix[0], xy_pix[1], sz_pix[0], sz_pix[1], fflags);
return null;
}
});
@@ -259,6 +318,32 @@ public class WindowDriver extends WindowImpl {
super.focusChanged(defer, focusGained);
}
+ @Override
+ protected boolean positionChanged(final boolean defer, final boolean windowUnits, final int newX, final int newY) {
+ final boolean res = super.positionChanged(defer, windowUnits, newX, newY);
+
+ if ( res ) {
+ if( isNativeValid() ) {
+ final MonitorDevice new_monitor = getMainMonitor();
+ if( null != last_monitor && !new_monitor.equals(last_monitor) ) {
+ final int[] move_diff = new int[] { 0, 0 };
+ MonitorDevice.Orientation orientation = MonitorDevice.Orientation.clone;
+ // Move from last_monitor -> new_monitor
+ orientation = new_monitor.getOrientationTo(last_monitor, move_diff);
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Info: Window Device Changed (P: "+newX+"/"+newY+
+ ", crt_move[orient "+orientation+", diff "+move_diff[0]+"/"+move_diff[1]+") "+
+ ", monitor "+last_monitor.getId()+" -> "+new_monitor.getId()+
+ " - "+Thread.currentThread().getName());
+ }
+ last_monitor = new_monitor;
+ updatePixelScaleByMonitor(new_monitor, move_diff, true /* sendEvent */, defer);
+ }
+ }
+ }
+ return res;
+ }
+
protected void reparentNotify(final long newParentWindowHandle) {
if(DEBUG_IMPLEMENTATION) {
final long p0 = getParentWindowHandle();
@@ -344,12 +429,14 @@ public class WindowDriver extends WindowImpl {
@Override
protected Point getLocationOnScreenImpl(final int x, final int y) {
- return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Point>() {
+ final int xy_pix[] = SurfaceScaleUtils.scale(new int[2], x, y, hasPixelScale);
+ final Point res_pix = runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Point>() {
@Override
public Point run(final long dpy) {
- return X11Lib.GetRelativeLocation(dpy, getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ return X11Lib.GetRelativeLocation(dpy, getScreenIndex(), getWindowHandle(), 0 /*root win*/, xy_pix[0], xy_pix[1]);
}
} );
+ return convertToWindowUnits( res_pix );
}
@Override
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch10NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch10NEWT.java
index cd9defd83..df712ee4e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch10NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch10NEWT.java
@@ -106,6 +106,7 @@ public class TestGLContextDrawableSwitch10NEWT extends UITestCase {
window.setVisible(true);
Assert.assertTrue(NewtTestUtil.waitForVisible(window, true, null));
Assert.assertTrue(NewtTestUtil.waitForRealized(window, true, null));
+ Assert.assertTrue(NewtTestUtil.waitForSize(window, width, height, null));
final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
final GLDrawable drawable = factory.createGLDrawable(window);
@@ -113,6 +114,8 @@ public class TestGLContextDrawableSwitch10NEWT extends UITestCase {
drawable.setRealized(true);
Assert.assertTrue(drawable.isRealized());
+ Assert.assertEquals(drawable.getSurfaceWidth(), window.getSurfaceWidth());
+ Assert.assertEquals(drawable.getSurfaceHeight(), window.getSurfaceHeight());
final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, null, window, false, null) {
@Override
@@ -123,6 +126,7 @@ public class TestGLContextDrawableSwitch10NEWT extends UITestCase {
};
window.setWindowDestroyNotifyAction( new Runnable() {
+ @Override
public void run() {
glad.windowDestroyNotifyOp();
} } );
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java
index 0ab9308c2..9b44da691 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java
@@ -28,15 +28,20 @@
package com.jogamp.opengl.test.junit.jogl.demos.gl2.newt;
+import com.jogamp.nativewindow.ScalableSurface;
+import com.jogamp.nativewindow.util.Dimension;
+import com.jogamp.nativewindow.util.DimensionImmutable;
+import com.jogamp.nativewindow.util.Point;
+import com.jogamp.nativewindow.util.PointImmutable;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.newt.opengl.util.NEWTDemoListener;
import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
import com.jogamp.opengl.test.junit.util.QuitAdapter;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
-import com.jogamp.opengl.test.junit.newt.parenting.NewtReparentingKeyAdapter;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLProfile;
@@ -58,15 +63,18 @@ import org.junit.runners.MethodSorters;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestGearsNEWT extends UITestCase {
static GLProfile glp;
- static int width, height;
+ static PointImmutable wpos;
+ static DimensionImmutable wsize;
+ static float[] reqSurfacePixelScale = new float[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE };
@BeforeClass
public static void initClass() {
if(GLProfile.isAvailable(GLProfile.GL2)) {
glp = GLProfile.get(GLProfile.GL2);
Assert.assertNotNull(glp);
- width = 640;
- height = 480;
+ if(null == wsize) {
+ wsize = new Dimension(640, 480);
+ }
} else {
setTestSupported(false);
}
@@ -95,11 +103,30 @@ public class TestGearsNEWT extends UITestCase {
glWindow.addKeyListener(newtDemoListener);
glWindow.addMouseListener(newtDemoListener);
- glWindow.setSize(width, height);
+ glWindow.setSize(wsize.getWidth(), wsize.getHeight());
+ if(null != wpos) {
+ glWindow.setPosition(wpos.getX(), wpos.getY());
+ }
+ glWindow.setSurfaceScale(reqSurfacePixelScale);
+ final float[] valReqSurfacePixelScale = glWindow.getRequestedSurfaceScale(new float[2]);
+
glWindow.setVisible(true);
animator.setUpdateFPSFrames(1, null);
animator.start();
+ System.err.println("Window Current State : "+glWindow.getStateMaskString());
+ System.err.println("Window Supported States: "+glWindow.getSupportedStateMaskString());
+ System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities());
+ System.err.println("GL chosen: "+glWindow.getChosenCapabilities());
+ System.err.println("window insets: "+glWindow.getInsets());
+ System.err.println("window bounds (window): "+glWindow.getBounds());
+ System.err.println("window bounds (pixels): "+glWindow.getSurfaceBounds());
+
+ final float[] hasSurfacePixelScale1 = glWindow.getCurrentSurfaceScale(new float[2]);
+ System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+
+ valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+
+ hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
+
while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
Thread.sleep(100);
}
@@ -117,14 +144,42 @@ public class TestGearsNEWT extends UITestCase {
static long duration = 500; // ms
public static void main(final String args[]) {
+ int x=0, y=0, w=640, h=480;
+ boolean usePos = false;
+
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
i++;
try {
duration = Integer.parseInt(args[i]);
} catch (final Exception ex) { ex.printStackTrace(); }
+ } else if(args[i].equals("-width")) {
+ i++;
+ w = MiscUtils.atoi(args[i], w);
+ } else if(args[i].equals("-height")) {
+ i++;
+ h = MiscUtils.atoi(args[i], h);
+ } else if(args[i].equals("-x")) {
+ i++;
+ x = MiscUtils.atoi(args[i], x);
+ usePos = true;
+ } else if(args[i].equals("-y")) {
+ i++;
+ y = MiscUtils.atoi(args[i], y);
+ usePos = true;
+ } else if(args[i].equals("-pixelScale")) {
+ i++;
+ final float pS = MiscUtils.atof(args[i], reqSurfacePixelScale[0]);
+ reqSurfacePixelScale[0] = pS;
+ reqSurfacePixelScale[1] = pS;
}
}
+ wsize = new Dimension(w, h);
+ if(usePos) {
+ wpos = new Point(x, y);
+ }
+ System.err.println("position "+wpos);
+ System.err.println("size "+wsize);
org.junit.runner.JUnitCore.main(TestGearsNEWT.class.getName());
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java
index fbca2e614..78f59931a 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java
@@ -119,7 +119,7 @@ public class TestScreenMode00aNEWT extends UITestCase {
cache.monitorDevices.add(monOut);
{
final int[] props = MonitorModeProps.streamOutMonitorDevice(monOut);
- final MonitorDevice monIn = MonitorModeProps.streamInMonitorDevice(cache, null, monitor_handle, null, props, 0, null);
+ final MonitorDevice monIn = MonitorModeProps.streamInMonitorDevice(cache, null, monitor_handle, null, false /* invscale_wuviewport */, props, 0, null);
System.err.println("01 in : "+monIn);
Assert.assertEquals(monOut.getHandle(), monIn.getHandle());