aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--make/build-newt.xml1
-rwxr-xr-xmake/scripts/tests-win.bat4
-rw-r--r--make/scripts/tests.sh6
-rw-r--r--src/jogl/classes/com/jogamp/opengl/JoglVersion.java1
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java5
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java82
-rw-r--r--src/newt/native/WindowsEDID.c419
-rw-r--r--src/newt/native/WindowsEDID.h40
-rw-r--r--src/newt/native/WindowsWindow.c158
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java19
10 files changed, 645 insertions, 90 deletions
diff --git a/make/build-newt.xml b/make/build-newt.xml
index cf8330eb1..37e6b8bff 100644
--- a/make/build-newt.xml
+++ b/make/build-newt.xml
@@ -616,6 +616,7 @@
<include name="${rootrel.src.c}/NewtCommon.c" />
<!-- include name="${rootrel.src.c}/timespec.c" /--> <!-- currently used for X11 and OSX with special PERF DEBUG MODE-->
<include name="${rootrel.src.c}/WindowsWindow.c" if="isWindows"/>
+ <include name="${rootrel.src.c}/WindowsEDID.c" if="isWindows"/>
<include name="${rootrel.src.c}/MacWindow.m" if="isOSX"/>
<include name="${rootrel.src.c}/NewtMacWindow.m" if="isOSX"/>
<include name="${rootrel.src.c}/AndroidWindow.c" if="isAndroid"/>
diff --git a/make/scripts/tests-win.bat b/make/scripts/tests-win.bat
index 8a94a0fa2..bd4a73b14 100755
--- a/make/scripts/tests-win.bat
+++ b/make/scripts/tests-win.bat
@@ -12,7 +12,7 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGe
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 40000 -width 100 -height 100 -screen 0 %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT %*
-scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelAWT %*
+REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelAWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelsAWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.awt.DemoGLJPanelPerf02AWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT %*
@@ -167,7 +167,7 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.TestGLWindows02NEWTAn
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.TestGLWindowInvisiblePointer01NEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.nativewindow.TestRecursiveToolkitLockCORE
-REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00aNEWT %*
+scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00aNEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00bNEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00cNEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01aNEWT %*
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 83d51f971..d8ad7e9da 100644
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -300,7 +300,7 @@ function jrun() {
#X_ARGS="-Xrs"
#X_ARGS="-Dsun.awt.disableMixing=true"
#D_ARGS="-Djogamp.debug.NativeLibrary=true -Djogamp.debug.JNILibLoader=true -Djogl.debug.GLMediaPlayer"
- D_ARGS="-Djogl.debug.GLMediaPlayer"
+ #D_ARGS="-Djogl.debug.GLMediaPlayer"
#D_ARGS="-Djogamp.debug.IOUtil -Djogl.debug.GLSLCode -Djogl.debug.GLMediaPlayer"
#D_ARGS="-Djogl.debug.AudioSink -Djoal.openal.lib=system"
#D_ARGS="-Djogl.debug.AudioSink -Djogl.debug.AudioSink.trace"
@@ -613,7 +613,7 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT
#testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle02NEWT
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
-#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00aNEWT $*
+testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00aNEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00bNEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00cNEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01aNEWT $*
@@ -842,7 +842,7 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.graph.demos.ui.UINewtDemo01 $*
#testnoawt com.jogamp.opengl.test.junit.graph.demos.GPUTextNewtDemo $*
#testnoawt com.jogamp.opengl.test.junit.graph.demos.GPURegionNewtDemo $*
-testnoawt com.jogamp.opengl.test.junit.graph.demos.GPUUISceneNewtDemo $*
+#testnoawt com.jogamp.opengl.test.junit.graph.demos.GPUUISceneNewtDemo $*
#testawt com.jogamp.opengl.test.junit.graph.demos.GPUUISceneNewtCanvasAWTDemo $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube $*
diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
index 5070f3e4e..af16348a8 100644
--- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
+++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
@@ -29,7 +29,6 @@
package com.jogamp.opengl;
import com.jogamp.common.GlueGenVersion;
-import com.jogamp.opengl.*;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.VersionUtil;
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index d638b3ae5..e15f52730 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -1004,6 +1004,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
glWindow.addGLEventListener(new GLEventListener() {
@Override
public void init(final GLAutoDrawable drawable) {
+ final MonitorDevice monitor = glWindow.getMainMonitor();
+ System.err.println("Main Monitor: "+monitor);
+ final float[] pixelPerMM = monitor.getPixelsPerMM(new float[2]);
+ System.err.println(" pp/mm ["+pixelPerMM[0]+", "+pixelPerMM[1]+"]");
+ System.err.println(" pp/in ["+pixelPerMM[0]*25.4f+", "+pixelPerMM[1]*25.4f+"]");
final GL gl = drawable.getGL();
System.err.println(JoglVersion.getGLInfo(gl, null));
System.err.println("Requested: "+drawable.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities());
diff --git a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
index b476ee38a..947ea27f4 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
@@ -65,19 +65,21 @@ public class ScreenDriver extends ScreenImpl {
protected void closeNativeImpl() {
}
- private final String getAdapterName(final int crt_idx) {
- return getAdapterName0(crt_idx);
+ private final String getAdapterName(final int adapter_idx) {
+ return getAdapterName0(adapter_idx);
}
- private final String getActiveMonitorName(final String adapterName, final int monitor_idx) {
- return getActiveMonitorName0(adapterName, monitor_idx);
+ private final String getMonitorName(final String adapterName, final int monitor_idx, final boolean onlyActive) {
+ return getMonitorName0(adapterName, monitor_idx, onlyActive);
+ }
+ private final int getFirstActiveMonitor(final String adapterName) {
+ return getFirstActiveMonitor0(adapterName);
}
- private final MonitorMode getMonitorModeImpl(final MonitorModeProps.Cache cache, final String adapterName, final int crtModeIdx) {
+ private final MonitorMode getMonitorModeImpl(final MonitorModeProps.Cache cache, final String adapterName, final int mode_idx) {
if( null == adapterName ) {
return null;
}
- final String activeMonitorName = getActiveMonitorName(adapterName, 0);
- final int[] modeProps = null != activeMonitorName ? getMonitorMode0(adapterName, crtModeIdx) : null;
+ final int[] modeProps = getMonitorMode0(adapterName, mode_idx);
if ( null == modeProps || 0 >= modeProps.length) {
return null;
}
@@ -86,34 +88,35 @@ public class ScreenDriver extends ScreenImpl {
@Override
protected void collectNativeMonitorModesAndDevicesImpl(final MonitorModeProps.Cache cache) {
- int crtIdx = 0;
ArrayHashSet<MonitorMode> supportedModes = new ArrayHashSet<MonitorMode>();
- String adapterName = getAdapterName(crtIdx);
- while( null != adapterName ) {
- int crtModeIdx = 0;
- MonitorMode mode;
- do {
- mode = getMonitorModeImpl(cache, adapterName, crtModeIdx);
- if( null != mode ) {
- supportedModes.getOrAdd(mode);
- // next mode on same monitor
- crtModeIdx++;
- }
- } while( null != mode);
- if( 0 < crtModeIdx ) {
- // has at least one mode -> add device
- final MonitorMode currentMode = getMonitorModeImpl(cache, adapterName, -1);
- if ( null != currentMode ) { // enabled
- final int[] monitorProps = getMonitorDevice0(adapterName, crtIdx);
- // merge monitor-props + supported modes
- MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, null, supportedModes, monitorProps, 0, null);
-
- // next monitor, 1st mode
- supportedModes= new ArrayHashSet<MonitorMode>();
+ int adapter_idx;
+ String adapterName;
+ for(adapter_idx=0; null != ( adapterName = getAdapterName(adapter_idx) ); adapter_idx++ ) {
+ final int activeMonitorIdx = getFirstActiveMonitor(adapterName);
+ if( 0 <= activeMonitorIdx ) {
+ int mode_idx = 0;
+ MonitorMode mode;
+ do {
+ mode = getMonitorModeImpl(cache, adapterName, mode_idx);
+ if( null != mode ) {
+ supportedModes.getOrAdd(mode);
+ // next mode on same monitor
+ mode_idx++;
+ }
+ } while( null != mode);
+ if( 0 < mode_idx ) {
+ // has at least one mode -> add device
+ final MonitorMode currentMode = getMonitorModeImpl(cache, adapterName, -1);
+ if ( null != currentMode ) { // enabled
+ final int[] monitorProps = getMonitorDevice0(adapterName, adapter_idx);
+ // merge monitor-props + supported modes
+ MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, null, supportedModes, monitorProps, 0, null);
+
+ // next monitor, 1st mode
+ supportedModes = new ArrayHashSet<MonitorMode>();
+ }
}
}
- crtIdx++;
- adapterName = getAdapterName(crtIdx);
}
}
@@ -121,8 +124,8 @@ public class ScreenDriver extends ScreenImpl {
protected boolean updateNativeMonitorDeviceViewportImpl(final MonitorDevice monitor, final float[] pixelScale, final Rectangle viewportPU, final Rectangle viewportWU) {
final String adapterName = getAdapterName(monitor.getId());
if( null != adapterName ) {
- final String activeMonitorName = getActiveMonitorName(adapterName, 0);
- if( null != activeMonitorName ) {
+ final int activeMonitorIdx = getFirstActiveMonitor(adapterName);
+ if( 0 <= activeMonitorIdx ) {
final int[] monitorProps = getMonitorDevice0(adapterName, monitor.getId());
int offset = MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT;
viewportPU.set(monitorProps[offset++], monitorProps[offset++], monitorProps[offset++], monitorProps[offset++]);
@@ -168,9 +171,10 @@ public class ScreenDriver extends ScreenImpl {
private native int getVirtualHeightImpl0();
private static native void dumpMonitorInfo0();
- private native String getAdapterName0(int crt_index);
- private native String getActiveMonitorName0(String adapterName, int crtModeIdx);
- private native int[] getMonitorMode0(String adapterName, int crtModeIdx);
- private native int[] getMonitorDevice0(String adapterName, int monitor_index);
- private native boolean setMonitorMode0(int monitor_index, int x, int y, int width, int height, int bits, int freq, int flags, int rot);
+ private native String getAdapterName0(int adapter_idx);
+ private native String getMonitorName0(String adapterName, int monitor_idx, boolean onlyActive);
+ private native int getFirstActiveMonitor0(String adapterName);
+ private native int[] getMonitorMode0(String adapterName, int mode_idx);
+ private native int[] getMonitorDevice0(String adapterName, int adapter_idx);
+ private native boolean setMonitorMode0(int adapter_idx, int x, int y, int width, int height, int bits, int freq, int flags, int rot);
}
diff --git a/src/newt/native/WindowsEDID.c b/src/newt/native/WindowsEDID.c
new file mode 100644
index 000000000..d84773dc6
--- /dev/null
+++ b/src/newt/native/WindowsEDID.c
@@ -0,0 +1,419 @@
+/**
+ * Copyright 2015 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ *
+ ***
+ *
+ * This code is inspired by Ofek Shilon's code and blog post:
+ * <http://ofekshilon.com/2014/06/19/reading-specific-monitor-dimensions/>
+ * See: function 'NewtEDID_GetMonitorSizeFromEDIDByModelName'
+ *
+ * In contrast to Ofek's code, function 'NewtEDID_GetMonitorSizeFromEDIDByDevice'
+ * uses the proper link from
+ * DISPLAY_DEVICE.DeviceID -> SP_DEVICE_INTERFACE_DETAIL_DATA.DevicePath,
+ * where DISPLAY_DEVICE.DeviceID is the monitor's enumeration via:
+ * EnumDisplayDevices(adapterName, monitor_idx, &ddMon, EDD_GET_DEVICE_INTERFACE_NAME);
+ * Hence the path to the registry-entry is well determined instead of just comparing
+ * the monitor's model name.
+ *
+ */
+
+#include <Windows.h>
+#include <Windowsx.h>
+#include <tchar.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stddef.h>
+
+#include <SetupApi.h>
+#include <cfgmgr32.h> // for MAX_DEVICE_ID_LEN
+
+#include "WindowsEDID.h"
+
+// #define VERBOSE_ON 1
+
+#ifdef VERBOSE_ON
+ #define DBG_PRINT(x, ...) _ftprintf(stderr, __T(x), ##__VA_ARGS__); fflush(stderr)
+#else
+ #define DBG_PRINT(...)
+#endif
+
+#define NAME_SIZE 128
+
+/* GetProcAddress doesn't exist in A/W variants under desktop Windows */
+#ifndef UNDER_CE
+#define GetProcAddressA GetProcAddress
+#endif
+
+#ifndef EDD_GET_DEVICE_INTERFACE_NAME
+#define EDD_GET_DEVICE_INTERFACE_NAME 0x00000001
+#endif
+
+static const GUID GUID_CLASS_MONITOR = { 0x4d36e96e, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 };
+static const GUID GUID_DEVINTERFACE_MONITOR = { 0xe6f07b5f, 0xee97, 0x4a90, 0xb0, 0x76, 0x33, 0xf5, 0x7b, 0xf4, 0xea, 0xa7 };
+
+#ifdef _UNICODE
+typedef HDEVINFO (WINAPI *SetupDiGetClassDevsPROCADDR)(CONST GUID *ClassGuid,PCWSTR Enumerator,HWND hwndParent,DWORD Flags);
+typedef WINBOOL (WINAPI *SetupDiGetDeviceInstanceIdPROCADDR)(HDEVINFO DeviceInfoSet,PSP_DEVINFO_DATA DeviceInfoData,PCWSTR DeviceInstanceId,DWORD DeviceInstanceIdSize,PDWORD RequiredSize);
+typedef WINBOOL (WINAPI *SetupDiGetDeviceInterfaceDetailPROCADDR)(HDEVINFO DeviceInfoSet,PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,DWORD DeviceInterfaceDetailDataSize,PDWORD RequiredSize,PSP_DEVINFO_DATA DeviceInfoData);
+#else
+typedef HDEVINFO (WINAPI *SetupDiGetClassDevsPROCADDR)(CONST GUID *ClassGuid,PCSTR Enumerator,HWND hwndParent,DWORD Flags);
+typedef WINBOOL (WINAPI *SetupDiGetDeviceInstanceIdPROCADDR)(HDEVINFO DeviceInfoSet,PSP_DEVINFO_DATA DeviceInfoData,PSTR DeviceInstanceId,DWORD DeviceInstanceIdSize,PDWORD RequiredSize);
+typedef WINBOOL (WINAPI *SetupDiGetDeviceInterfaceDetailPROCADDR)(HDEVINFO DeviceInfoSet,PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,DWORD DeviceInterfaceDetailDataSize,PDWORD RequiredSize,PSP_DEVINFO_DATA DeviceInfoData);
+#endif
+
+typedef WINBOOL (WINAPI *SetupDiEnumDeviceInfoPROCADDR)(HDEVINFO DeviceInfoSet,DWORD MemberIndex,PSP_DEVINFO_DATA DeviceInfoData);
+typedef WINBOOL (WINAPI *SetupDiEnumDeviceInterfacesPROCADDR)(HDEVINFO DeviceInfoSet,PSP_DEVINFO_DATA DeviceInfoData,CONST GUID *InterfaceClassGuid,DWORD MemberIndex,PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
+typedef HKEY (WINAPI *SetupDiOpenDevRegKeyPROCADDR)(HDEVINFO DeviceInfoSet,PSP_DEVINFO_DATA DeviceInfoData,DWORD Scope,DWORD HwProfile,DWORD KeyType,REGSAM samDesired);
+typedef WINBOOL (WINAPI *SetupDiDestroyDeviceInfoListPROCADDR)(HDEVINFO DeviceInfoSet);
+
+static int WinSetupAPI_avail = 0;
+static SetupDiGetClassDevsPROCADDR WinSetup_SetupDiGetClassDevs = NULL;
+static SetupDiGetDeviceInstanceIdPROCADDR WinSetup_SetupDiGetDeviceInstanceId = NULL;
+static SetupDiGetDeviceInterfaceDetailPROCADDR WinSetup_SetupDiGetDeviceInterfaceDetail = NULL;
+static SetupDiEnumDeviceInfoPROCADDR WinSetup_SetupDiEnumDeviceInfo = NULL;
+static SetupDiEnumDeviceInterfacesPROCADDR WinSetup_SetupDiEnumDeviceInterfaces = NULL;
+static SetupDiOpenDevRegKeyPROCADDR WinSetup_SetupDiOpenDevRegKey = NULL;
+static SetupDiDestroyDeviceInfoListPROCADDR WinSetup_SetupDiDestroyDeviceInfoList = NULL;
+
+static int _init = 0;
+
+int NewtEDID_init() {
+ if( !_init ) {
+ WinSetupAPI_avail = 0;
+ HANDLE setup = LoadLibrary(TEXT("setupapi.dll"));
+ if( setup ) {
+ #ifdef _UNICODE
+ WinSetup_SetupDiGetClassDevs = (SetupDiGetClassDevsPROCADDR) GetProcAddressA(setup, "SetupDiGetClassDevsW");
+ WinSetup_SetupDiGetDeviceInstanceId = (SetupDiGetDeviceInstanceIdPROCADDR) GetProcAddressA(setup, "SetupDiGetDeviceInstanceIdW");
+ WinSetup_SetupDiGetDeviceInterfaceDetail = (SetupDiGetDeviceInterfaceDetailPROCADDR) GetProcAddressA(setup, "SetupDiGetDeviceInterfaceDetailW");
+ #else
+ WinSetup_SetupDiGetClassDevs = (SetupDiGetClassDevsPROCADDR) GetProcAddressA(setup, "SetupDiGetClassDevsA");
+ WinSetup_SetupDiGetDeviceInstanceId = (SetupDiGetDeviceInstanceIdPROCADDR) GetProcAddressA(setup, "SetupDiGetDeviceInstanceIdA");
+ WinSetup_SetupDiGetDeviceInterfaceDetail = (SetupDiGetDeviceInterfaceDetailPROCADDR) GetProcAddressA(setup, "SetupDiGetDeviceInterfaceDetailA");
+ #endif
+ WinSetup_SetupDiEnumDeviceInfo = (SetupDiEnumDeviceInfoPROCADDR) GetProcAddressA(setup, "SetupDiEnumDeviceInfo");
+ WinSetup_SetupDiEnumDeviceInterfaces = (SetupDiEnumDeviceInterfacesPROCADDR) GetProcAddressA(setup, "SetupDiEnumDeviceInterfaces");
+ WinSetup_SetupDiOpenDevRegKey = (SetupDiOpenDevRegKeyPROCADDR) GetProcAddressA(setup, "SetupDiOpenDevRegKey");
+ WinSetup_SetupDiDestroyDeviceInfoList = (SetupDiDestroyDeviceInfoListPROCADDR) GetProcAddressA(setup, "SetupDiDestroyDeviceInfoList");
+ if( NULL != WinSetup_SetupDiGetClassDevs &&
+ NULL != WinSetup_SetupDiGetDeviceInstanceId &&
+ NULL != WinSetup_SetupDiGetDeviceInterfaceDetail &&
+ NULL != WinSetup_SetupDiEnumDeviceInfo &&
+ NULL != WinSetup_SetupDiEnumDeviceInterfaces &&
+ NULL != WinSetup_SetupDiOpenDevRegKey &&
+ NULL != WinSetup_SetupDiDestroyDeviceInfoList ) {
+ WinSetupAPI_avail = 1;
+ }
+ }
+ _init = 1;
+ }
+ return WinSetupAPI_avail;
+}
+
+static _TCHAR* Get2ndSlashBlock(const _TCHAR* sIn, _TCHAR* sOut, size_t sOutLen)
+{
+ _TCHAR* s = _tcschr(sIn, '\\');
+ if( NULL != s ) {
+ s += 1; // skip '\\'
+ _TCHAR* t = _tcschr(s, '\\');
+ if( NULL != t ) {
+ size_t len = t - s;
+ if( len > 0 ) {
+ if( sOutLen >= len ) {
+ _tcsncpy_s(sOut, sOutLen, s, len);
+ return sOut;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+static int GetMonitorSizeFromEDIDByRegKey(const HKEY hEDIDRegKey, int* widthMm, int* heightMm, int *widthCm, int *heightCm)
+{
+ DWORD dwType, actualValueNameLength = NAME_SIZE;
+ _TCHAR valueName[NAME_SIZE];
+
+ BYTE edidData[1024];
+ DWORD edidSize = sizeof(edidData);
+
+ *widthMm = -1;
+ *heightMm = -1;
+ *widthCm = -1;
+ *heightCm = -1;
+
+ LONG retValue;
+ DWORD i;
+ for (i = 0, retValue = ERROR_SUCCESS; retValue != ERROR_NO_MORE_ITEMS; i++) {
+ retValue = RegEnumValue(hEDIDRegKey, i, &valueName[0],
+ &actualValueNameLength, NULL, &dwType,
+ edidData, // buffer
+ &edidSize); // buffer size
+
+ if ( retValue == ERROR_SUCCESS && edidSize >= 23 &&
+ 0 == _tcscmp(valueName, _T("EDID")) )
+ {
+ DBG_PRINT("*** EDID Version %d.%d, data-size %d\n", (int)edidData[18], (int)edidData[19], edidSize);
+ if( edidSize >= 69 ) {
+ // 54 + 12 = 66: Horizontal display size, mm, 8 lsbits (0–4095 mm, 161 in)
+ // 54 + 13 = 67: Vertical display size, mm, 8 lsbits (0–4095 mm, 161 in)
+ // 54 + 14 = 68:
+ // Bits 7–4 Horizontal display size, mm, 4 msbits
+ // Bits 3–0 Vertical display size, mm, 4 msbits
+ *widthMm = ( (int)(edidData[68] & 0xF0) << 4 ) | (int)edidData[66];
+ *heightMm = ( (int)(edidData[68] & 0x0F) << 8 ) | (int)edidData[67];
+ }
+ *widthCm = (int) edidData[21];
+ *heightCm = (int) edidData[22];
+ return 1; // valid EDID found
+ }
+ }
+ return 0; // EDID not found
+}
+
+int NewtEDID_GetMonitorSizeFromEDIDByModelName(const DISPLAY_DEVICE* ddMon, int* widthMm, int* heightMm, int *widthCm, int *heightCm)
+{
+ _TCHAR useDevModelNameStore[MAX_DEVICE_ID_LEN];
+ _TCHAR *useDevModelName = Get2ndSlashBlock(ddMon->DeviceID, useDevModelNameStore, MAX_DEVICE_ID_LEN);
+ if( NULL == useDevModelName ) {
+ return 0;
+ }
+
+ HDEVINFO devInfo = WinSetup_SetupDiGetClassDevs(
+ &GUID_CLASS_MONITOR, //class GUID
+ NULL, //enumerator
+ NULL, //HWND
+ DIGCF_PRESENT | DIGCF_PROFILE); // Flags //DIGCF_ALLCLASSES|
+
+ if (NULL == devInfo) {
+ return 0;
+ }
+
+ int bRes = 0;
+ DWORD i;
+ DWORD lastError = ERROR_SUCCESS;
+ for (i = 0; !bRes && ERROR_SUCCESS == lastError; i++) {
+ SP_DEVINFO_DATA devInfoData;
+ memset(&devInfoData, 0, sizeof(devInfoData));
+ devInfoData.cbSize = sizeof(devInfoData);
+
+ if (WinSetup_SetupDiEnumDeviceInfo(devInfo, i, &devInfoData)) {
+ _TCHAR devModelName[MAX_DEVICE_ID_LEN];
+ WinSetup_SetupDiGetDeviceInstanceId(devInfo, &devInfoData, devModelName, MAX_PATH, NULL);
+
+ if( NULL != _tcsstr(devModelName, useDevModelName) ) {
+ HKEY hEDIDRegKey = WinSetup_SetupDiOpenDevRegKey(devInfo, &devInfoData,
+ DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
+
+ if ( 0 != hEDIDRegKey && hEDIDRegKey != INVALID_HANDLE_VALUE ) {
+ bRes = GetMonitorSizeFromEDIDByRegKey(hEDIDRegKey, widthMm, heightMm, widthCm, heightCm);
+ RegCloseKey(hEDIDRegKey);
+ }
+ }
+ }
+ lastError = GetLastError();
+ }
+ WinSetup_SetupDiDestroyDeviceInfoList(devInfo);
+ return bRes;
+}
+
+int NewtEDID_GetMonitorSizeFromEDIDByDevice(const DISPLAY_DEVICE* ddMon, int* widthMm, int* heightMm, int *widthCm, int *heightCm)
+{
+ HDEVINFO devInfo = WinSetup_SetupDiGetClassDevs(
+ &GUID_DEVINTERFACE_MONITOR,
+ NULL, //enumerator
+ NULL, //HWND
+ DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); // Flags //DIGCF_ALLCLASSES|
+
+ if (NULL == devInfo) {
+ return 0;
+ }
+
+ DWORD devIfaceDetailDataSize = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA, DevicePath) + MAX_PATH * sizeof(TCHAR);
+ PSP_DEVICE_INTERFACE_DETAIL_DATA pDevIfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(devIfaceDetailDataSize);
+
+ int bRes = 0;
+ DWORD i;
+ DWORD lastError = ERROR_SUCCESS;
+ for (i = 0; !bRes && ERROR_SUCCESS == lastError; i++) {
+ SP_DEVICE_INTERFACE_DATA devIfaceData;
+ memset(&devIfaceData, 0, sizeof(devIfaceData));
+ devIfaceData.cbSize = sizeof(devIfaceData);
+
+ if ( WinSetup_SetupDiEnumDeviceInterfaces(devInfo, NULL, &GUID_DEVINTERFACE_MONITOR, i, &devIfaceData) ) {
+ memset(pDevIfaceDetailData, 0, devIfaceDetailDataSize);
+ pDevIfaceDetailData->cbSize = sizeof(*pDevIfaceDetailData);
+ DWORD devIfaceDetailDataReqSize = 0;
+ SP_DEVINFO_DATA devInfoData2;
+ memset(&devInfoData2, 0, sizeof(devInfoData2));
+ devInfoData2.cbSize = sizeof(devInfoData2);
+ if( WinSetup_SetupDiGetDeviceInterfaceDetail(devInfo, &devIfaceData, pDevIfaceDetailData, devIfaceDetailDataSize,
+ &devIfaceDetailDataReqSize, &devInfoData2) ) {
+ int found = 0 == _tcsicmp(pDevIfaceDetailData->DevicePath, ddMon->DeviceID);
+ DBG_PRINT("*** Got[%d].2 found %d, devicePath <%s>\n", i, found, pDevIfaceDetailData->DevicePath);
+ if( found ) {
+ HKEY hEDIDRegKey = WinSetup_SetupDiOpenDevRegKey(devInfo, &devInfoData2,
+ DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
+ DBG_PRINT("*** Got[%d] hEDIDRegKey %p\n", i, (void*)hEDIDRegKey);
+ if ( 0 != hEDIDRegKey && hEDIDRegKey != INVALID_HANDLE_VALUE ) {
+ bRes = GetMonitorSizeFromEDIDByRegKey(hEDIDRegKey, widthMm, heightMm, widthCm, heightCm);
+ RegCloseKey(hEDIDRegKey);
+ }
+ }
+ } else {
+ lastError = GetLastError();
+ DBG_PRINT("*** fail.2 at %d, werr %d\n", i, lastError);
+ }
+ } else {
+ lastError = GetLastError();
+ DBG_PRINT("*** fail.1 at %d, werr %d\n", i, lastError);
+ }
+ }
+ DBG_PRINT("*** Result: found %d, enum-iter %d, werr %d\n", bRes, i, (int)lastError);
+ WinSetup_SetupDiDestroyDeviceInfoList(devInfo);
+ free(pDevIfaceDetailData);
+ return bRes;
+}
+
+int NewtEDID_GetIndexedDisplayDevice(int useDevIdx, int useMonIdx, DISPLAY_DEVICE* ddMonOut, int getDeviceInterfaceName, int verbose)
+{
+ DISPLAY_DEVICE ddAdp;
+ DWORD devIdx; // device index
+ DWORD monIdx; // monitor index
+
+ memset(&ddAdp, 0, sizeof(ddAdp));
+ ddAdp.cb = sizeof(ddAdp);
+
+ const DWORD dwFlagsMonitor = 0 != getDeviceInterfaceName ? EDD_GET_DEVICE_INTERFACE_NAME : 0;
+
+ for(devIdx = 0;
+ ( devIdx <= useDevIdx || 0 > useDevIdx ) && EnumDisplayDevices(0, devIdx, &ddAdp, 0);
+ devIdx++)
+ {
+ if( NULL != ddAdp.DeviceName && 0 != _tcslen(ddAdp.DeviceName) ) {
+ if( verbose ) {
+ _ftprintf(stderr, __T("*** [%02d:__]: deviceName <%s> flags 0x%X active %d\n"),
+ devIdx, ddAdp.DeviceName, ddAdp.StateFlags, ( 0 != ( ddAdp.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) );
+ _ftprintf(stderr, __T(" deviceString <%s> \n"), ddAdp.DeviceString);
+ _ftprintf(stderr, __T(" deviceID <%s> \n"), ddAdp.DeviceID);
+ }
+ if( devIdx == useDevIdx || 0 > useDevIdx ) {
+ DISPLAY_DEVICE ddMon;
+ memset(&ddMon, 0, sizeof(ddMon));
+ ddMon.cb = sizeof(ddMon);
+
+ for(monIdx = 0;
+ ( monIdx <= useMonIdx || 0 > useMonIdx ) && EnumDisplayDevices(ddAdp.DeviceName, monIdx, &ddMon, dwFlagsMonitor);
+ monIdx++)
+ {
+ if( NULL != ddMon.DeviceName && 0 < _tcslen(ddMon.DeviceName) ) {
+ if( verbose ) {
+ _ftprintf(stderr, __T("*** [%02d:%02d]: deviceName <%s> flags 0x%X active %d\n"),
+ devIdx, monIdx, ddMon.DeviceName, ddMon.StateFlags, ( 0 != ( ddMon.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) );
+ _ftprintf(stderr, __T(" deviceString <%s> \n"), ddMon.DeviceString);
+ _ftprintf(stderr, __T(" deviceID <%s> \n"), ddMon.DeviceID);
+ }
+ if( monIdx == useMonIdx ) {
+ *ddMonOut = ddMon;
+ return 1;
+ }
+ }
+ memset(&ddMon, 0, sizeof(ddMon));
+ ddMon.cb = sizeof(ddMon);
+ }
+ }
+ }
+ memset(&ddAdp, 0, sizeof(ddAdp));
+ ddAdp.cb = sizeof(ddAdp);
+ }
+ memset(ddMonOut, 0, sizeof(*ddMonOut));
+ ddMonOut->cb = sizeof(*ddMonOut);
+ return 0;
+}
+
+#ifdef WINDOWS_EDID_WITH_MAIN
+
+int _tmain(int argc, _TCHAR* argv [])
+{
+#ifdef _UNICODE
+ _ftprintf(stderr, __T("_UNICODE enabled\n"));
+#else
+ fprintf(stderr, "_UNICODE disabled\n");
+#endif
+ if( !NewtEDID_init() ) {
+ _ftprintf(stderr, __T("setupapi not available\n"));
+ return 1;
+ }
+ DISPLAY_DEVICE ddMon;
+
+ if( 3 != argc ) {
+ NewtEDID_GetIndexedDisplayDevice(-1, -1, &ddMon, 0 /* getDeviceInterfaceName */, 1 /* verbose */);
+ _ftprintf(stderr, __T("Usage: %s dev-idx mon-idx\n"), argv[0]);
+ return 1;
+ }
+ int useDevIdx = _tstoi(argv[1]);
+ int useMonIdx = _tstoi(argv[2]);
+ int widthMm, heightMm;
+ int widthCm, heightCm;
+
+ //
+ // Proper method
+ //
+ if( 0 == NewtEDID_GetIndexedDisplayDevice(useDevIdx, useMonIdx, &ddMon, 1 /* getDeviceInterfaceName */, 0 /* verbose */) ) {
+ _ftprintf(stderr, __T("No monitor found at dev %d : mon %d\n"), useDevIdx, useMonIdx);
+ return 1;
+ }
+ _ftprintf(stderr, __T("Found monitor at dev %d : mon %d:\n"), useDevIdx, useMonIdx);
+ _ftprintf(stderr, __T(" Device Name : %s\n"), ddMon.DeviceName);
+ _ftprintf(stderr, __T(" Device String: %s\n"), ddMon.DeviceString);
+ _ftprintf(stderr, __T(" Device ID : %s\n"), ddMon.DeviceID);
+ fflush(NULL);
+
+ if( NewtEDID_GetMonitorSizeFromEDIDByDevice(&ddMon, &widthMm, &heightMm, &widthCm, &heightCm) ) {
+ _ftprintf(stderr, __T("Proper: Found EDID size [%d, %d] [mm], [%d, %d] [cm]\n"), widthMm, heightMm, widthCm, heightCm);
+ }
+
+ //
+ // Monitor model name method
+ //
+ if( 0 == NewtEDID_GetIndexedDisplayDevice(useDevIdx, useMonIdx, &ddMon, 0 /* getDeviceInterfaceName */, 0 /* verbose */) ) {
+ _ftprintf(stderr, __T("No monitor found at dev %d : mon %d\n"), useDevIdx, useMonIdx);
+ return 1;
+ }
+ _ftprintf(stderr, __T("Found monitor at dev %d : mon %d:\n"), useDevIdx, useMonIdx);
+ _ftprintf(stderr, __T(" Device Name : %s\n"), ddMon.DeviceName);
+ _ftprintf(stderr, __T(" Device String: %s\n"), ddMon.DeviceString);
+ _ftprintf(stderr, __T(" Device ID : %s\n"), ddMon.DeviceID);
+ fflush(NULL);
+
+ if( NewtEDID_GetMonitorSizeFromEDIDByModelName(&ddMon, &widthMm, &heightMm, &widthCm, &heightCm) ) {
+ _ftprintf(stderr, __T("ModelN: Found EDID size [%d, %d] [mm], [%d, %d] [cm]\n"), widthMm, heightMm, widthCm, heightCm);
+ }
+ return 0;
+}
+
+#endif /* WINDOWS_EDID_WITH_MAIN */
diff --git a/src/newt/native/WindowsEDID.h b/src/newt/native/WindowsEDID.h
new file mode 100644
index 000000000..ea80ca6df
--- /dev/null
+++ b/src/newt/native/WindowsEDID.h
@@ -0,0 +1,40 @@
+/**
+ * Copyright 2015 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+#ifndef _WINDOWS_EDID_H_
+#define _WINDOWS_EDID_H_
+
+#include <Windows.h>
+#include <Wingdi.h>
+
+int NewtEDID_init();
+int NewtEDID_GetMonitorSizeFromEDIDByModelName(const DISPLAY_DEVICE* ddMon, int* widthMm, int* heightMm, int *widthCm, int *heightCm);
+int NewtEDID_GetMonitorSizeFromEDIDByDevice(const DISPLAY_DEVICE* ddMon, int* widthMm, int* heightMm, int *widthCm, int *heightCm);
+int NewtEDID_GetIndexedDisplayDevice(int useDevIdx, int useMonIdx, DISPLAY_DEVICE* ddMonOut, int getDeviceInterfaceName, int verbose);
+
+#endif /* _WINDOWS_EDID_H_ */
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index 70d0c6f83..d3ad69f92 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -108,6 +108,10 @@
#define TOUCH_COORD_TO_PIXEL(l) (l/100)
#endif
+#ifndef EDD_GET_DEVICE_INTERFACE_NAME
+#define EDD_GET_DEVICE_INTERFACE_NAME 0x00000001
+#endif
+
#ifndef MONITOR_DEFAULTTONULL
#define MONITOR_DEFAULTTONULL 0
#endif
@@ -139,16 +143,18 @@
#include "NewtCommon.h"
+#include "WindowsEDID.h"
+
// #define VERBOSE_ON 1
// #define DEBUG_KEYS 1
#ifdef VERBOSE_ON
- #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+ #define DBG_PRINT(x, ...) _ftprintf(stderr, __T(x), ##__VA_ARGS__); fflush(stderr)
#else
#define DBG_PRINT(...)
#endif
-#define STD_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#define STD_PRINT(x, ...) _ftprintf(stderr, __T(x), ##__VA_ARGS__); fflush(stderr)
static jmethodID insetsChangedID = NULL;
static jmethodID sizeChangedID = NULL;
@@ -175,6 +181,8 @@ static IsTouchWindowPROCADDR WinTouch_IsTouchWindow = NULL;
static RegisterTouchWindowPROCADDR WinTouch_RegisterTouchWindow = NULL;
static UnregisterTouchWindowPROCADDR WinTouch_UnregisterTouchWindow = NULL;
+static int NewtEDID_avail = 0;
+
static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd);
typedef struct {
@@ -1629,11 +1637,11 @@ static int NewtScreen_RotationNewtCCW2NativeCCW(JNIEnv *env, jint newt) {
return native;
}
-static LPCTSTR NewtScreen_getAdapterName(DISPLAY_DEVICE * device, int crt_idx) {
+static LPCTSTR NewtScreen_getAdapterName(DISPLAY_DEVICE * device, int adapter_idx) {
memset(device, 0, sizeof(DISPLAY_DEVICE));
device->cb = sizeof(DISPLAY_DEVICE);
- if( FALSE == EnumDisplayDevices(NULL, crt_idx, device, 0) ) {
- DBG_PRINT("*** WindowsWindow: getAdapterName.EnumDisplayDevices(crt_idx %d) -> FALSE\n", crt_idx);
+ if( FALSE == EnumDisplayDevices(NULL, adapter_idx, device, 0) ) {
+ DBG_PRINT("*** WindowsWindow: getAdapterName.EnumDisplayDevices(adapter_idx %d) -> FALSE\n", adapter_idx);
return NULL;
}
@@ -1647,16 +1655,19 @@ static LPCTSTR NewtScreen_getAdapterName(DISPLAY_DEVICE * device, int crt_idx) {
static LPCTSTR NewtScreen_getMonitorName(LPCTSTR adapterName, DISPLAY_DEVICE * device, int monitor_idx, BOOL onlyActive) {
memset(device, 0, sizeof(DISPLAY_DEVICE));
device->cb = sizeof(DISPLAY_DEVICE);
- if( 0 == monitor_idx ) {
- if( FALSE == EnumDisplayDevices(adapterName, monitor_idx, device, 0) ) {
- DBG_PRINT("*** WindowsWindow: getDisplayName.EnumDisplayDevices(monitor_idx %d).adapter -> FALSE\n", monitor_idx);
+ if( FALSE == EnumDisplayDevices(adapterName, monitor_idx, device, EDD_GET_DEVICE_INTERFACE_NAME) ) {
+ DBG_PRINT("*** WindowsWindow: getDisplayName.EnumDisplayDevices(monitor_idx %d).adapter -> FALSE\n", monitor_idx);
+ return NULL;
+ }
+ if( onlyActive ) {
+ if( 0 == ( device->StateFlags & DISPLAY_DEVICE_ACTIVE ) ) {
+ DBG_PRINT("*** WindowsWindow: !DISPLAY_DEVICE_ACTIVE(monitor_idx %d).display\n", monitor_idx);
+ return NULL;
+ }
+ if( 0 != ( device->StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER ) ) {
+ DBG_PRINT("*** WindowsWindow: DISPLAY_DEVICE_MIRRORING_DRIVER(monitor_idx %d).display\n", monitor_idx);
return NULL;
}
- }
-
- if( onlyActive && 0 == ( device->StateFlags & DISPLAY_DEVICE_ACTIVE ) ) {
- DBG_PRINT("*** WindowsWindow: !DISPLAY_DEVICE_ACTIVE(monitor_idx %d).display\n", monitor_idx);
- return NULL;
}
if( NULL == device->DeviceName || 0 == _tcslen(device->DeviceName) ) {
return NULL;
@@ -1665,6 +1676,23 @@ static LPCTSTR NewtScreen_getMonitorName(LPCTSTR adapterName, DISPLAY_DEVICE * d
return device->DeviceName;
}
+static int NewtScreen_getFirstActiveMonitor(LPCTSTR adapterName, DISPLAY_DEVICE * device) {
+ memset(device, 0, sizeof(DISPLAY_DEVICE));
+ device->cb = sizeof(DISPLAY_DEVICE);
+ int monitor_idx;
+ for(monitor_idx=0; EnumDisplayDevices(adapterName, monitor_idx, device, EDD_GET_DEVICE_INTERFACE_NAME); monitor_idx++) {
+ if( NULL != device->DeviceName &&
+ 0 < _tcslen(device->DeviceName) &&
+ 0 != ( device->StateFlags & DISPLAY_DEVICE_ACTIVE ) &&
+ 0 == ( device->StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER ) ) {
+ return monitor_idx;
+ }
+ memset(device, 0, sizeof(DISPLAY_DEVICE));
+ device->cb = sizeof(DISPLAY_DEVICE);
+ }
+ return -1;
+}
+
JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_dumpMonitorInfo0
(JNIEnv *env, jclass clazz)
{
@@ -1672,10 +1700,16 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_dumpMonitorI
int i = 0, j;
LPCTSTR aName, dName;
while(NULL != (aName = NewtScreen_getAdapterName(&aDevice, i))) {
- fprintf(stderr, "*** [%d]: <%s> flags 0x%X active %d\n", i, aName, aDevice.StateFlags, ( 0 != ( aDevice.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) );
+ STD_PRINT("*** [%02d:__]: deviceName <%s> flags 0x%X active %d\n",
+ i, aDevice.DeviceName, aDevice.StateFlags, ( 0 != ( aDevice.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) );
+ STD_PRINT(" deviceString <%s> \n", aDevice.DeviceString);
+ STD_PRINT(" deviceID <%s> \n", aDevice.DeviceID);
j=0;
while(NULL != (dName = NewtScreen_getMonitorName(aName, &dDevice, j, FALSE))) {
- fprintf(stderr, "*** [%d][%d]: <%s> flags 0x%X active %d\n", i, j, dName, dDevice.StateFlags, ( 0 != ( dDevice.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) );
+ STD_PRINT("*** [%02d:%02d]: deviceName <%s> flags 0x%X active %d\n",
+ i, j, dDevice.DeviceName, dDevice.StateFlags, ( 0 != ( dDevice.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) );
+ STD_PRINT(" deviceString <%s> \n", dDevice.DeviceString);
+ STD_PRINT(" deviceID <%s> \n", dDevice.DeviceID);
j++;
}
i++;
@@ -1692,11 +1726,11 @@ static HDC NewtScreen_createDisplayDC(LPCTSTR displayDeviceName) {
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getAdapterName0
- (JNIEnv *env, jobject obj, jint crt_idx)
+ (JNIEnv *env, jobject obj, jint adapter_idx)
{
DISPLAY_DEVICE device;
- LPCTSTR adapterName = NewtScreen_getAdapterName(&device, crt_idx);
- DBG_PRINT("*** WindowsWindow: getAdapterName(crt_idx %d) -> %s, active %d\n", crt_idx,
+ LPCTSTR adapterName = NewtScreen_getAdapterName(&device, adapter_idx);
+ DBG_PRINT("*** WindowsWindow: getAdapterName(adapter_idx %d) -> %s, active %d\n", adapter_idx,
(NULL==adapterName?"nil":adapterName), 0 == ( device.StateFlags & DISPLAY_DEVICE_ACTIVE ));
if(NULL == adapterName) {
return NULL;
@@ -1710,22 +1744,22 @@ JNIEXPORT jstring JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getAdapte
/*
* Class: jogamp_newt_driver_windows_ScreenDriver
- * Method: getActiveMonitorName0
- * Signature: (Ljava/lang/String;I)Ljava/lang/String;
+ * Method: getMonitorName0
+ * Signature: (Ljava/lang/String;IZ)Ljava/lang/String;
*/
-JNIEXPORT jstring JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getActiveMonitorName0
- (JNIEnv *env, jobject obj, jstring jAdapterName, jint monitor_idx)
+JNIEXPORT jstring JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMonitorName0
+ (JNIEnv *env, jobject obj, jstring jAdapterName, jint monitor_idx, jboolean onlyActive)
{
DISPLAY_DEVICE device;
LPCTSTR monitorName;
#ifdef UNICODE
LPCTSTR adapterName = NewtCommon_GetNullTerminatedStringChars(env, jAdapterName);
- monitorName = NewtScreen_getMonitorName(adapterName, &device, monitor_idx, TRUE);
+ monitorName = NewtScreen_getMonitorName(adapterName, &device, monitor_idx, onlyActive);
DBG_PRINT("*** WindowsWindow: getMonitorName(%s, monitor_idx %d) -> %s\n", adapterName, monitor_idx, (NULL==monitorName?"nil":monitorName));
free((void*) adapterName);
#else
LPCTSTR adapterName = (*env)->GetStringUTFChars(env, jAdapterName, NULL);
- monitorName = NewtScreen_getMonitorName(adapterName, &device, monitor_idx, TRUE);
+ monitorName = NewtScreen_getMonitorName(adapterName, &device, monitor_idx, onlyActive);
DBG_PRINT("*** WindowsWindow: getMonitorName(%s, monitor_idx %d) -> %s\n", adapterName, monitor_idx, (NULL==monitorName?"nil":monitorName));
(*env)->ReleaseStringUTFChars(env, jAdapterName, adapterName);
#endif
@@ -1741,6 +1775,30 @@ JNIEXPORT jstring JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getActive
/*
* Class: jogamp_newt_driver_windows_ScreenDriver
+ * Method: getFirstActiveMonitor0
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getFirstActiveMonitor0
+ (JNIEnv *env, jobject obj, jstring jAdapterName)
+{
+ DISPLAY_DEVICE device;
+ int monitorIdx;
+#ifdef UNICODE
+ LPCTSTR adapterName = NewtCommon_GetNullTerminatedStringChars(env, jAdapterName);
+ monitorIdx = NewtScreen_getFirstActiveMonitor(adapterName, &device);
+ DBG_PRINT("*** WindowsWindow: getFirstActiveMonitor(%s) -> monitor_idx %d, %s\n", adapterName, monitorIdx, (NULL==device.DeviceName?"nil":device.DeviceName));
+ free((void*) adapterName);
+#else
+ LPCTSTR adapterName = (*env)->GetStringUTFChars(env, jAdapterName, NULL);
+ monitorIdx = NewtScreen_getFirstActiveMonitor(adapterName, &device);
+ DBG_PRINT("*** WindowsWindow: getFirstActiveMonitor(%s) -> monitor_idx %d, %s\n", adapterName, monitorIdx, (NULL==device.DeviceName?"nil":device.DeviceName));
+ (*env)->ReleaseStringUTFChars(env, jAdapterName, adapterName);
+#endif
+ return monitorIdx;
+}
+
+/*
+ * Class: jogamp_newt_driver_windows_ScreenDriver
* Method: getMonitorMode0
* Signature: (Ljava/lang/String;I)[I
*/
@@ -1818,9 +1876,8 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni
* Signature: (Ljava/lang/String;I)[I
*/
JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMonitorDevice0
- (JNIEnv *env, jobject obj, jstring jAdapterName, jint monitor_idx)
+ (JNIEnv *env, jobject obj, jstring jAdapterName, jint adapter_idx)
{
- DISPLAY_DEVICE device;
LPCTSTR adapterName;
{
#ifdef UNICODE
@@ -1830,10 +1887,36 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni
#endif
}
- HDC hdc = NewtScreen_createDisplayDC(adapterName);
- int widthmm = GetDeviceCaps(hdc, HORZSIZE);
- int heightmm = GetDeviceCaps(hdc, VERTSIZE);
- DeleteDC(hdc);
+ DBG_PRINT("*** WindowsWindow: adapter[name %s, idx %d], EDID-avail %d\n", adapterName, adapter_idx, NewtEDID_avail);
+ int gotsize = 0;
+ int widthmm, heightmm;
+ if( NewtEDID_avail ) {
+ int widthcm, heightcm;
+ DISPLAY_DEVICE monitorDevice;
+ int monitor_idx = NewtScreen_getFirstActiveMonitor(adapterName, &monitorDevice);
+ if( 0 <= monitor_idx &&
+ NewtEDID_GetMonitorSizeFromEDIDByDevice(&monitorDevice, &widthmm, &heightmm, &widthcm, &heightcm) ) {
+ DBG_PRINT("*** WindowsWindow: EDID %d x %d [mm], %d x %d [cm]\n", widthmm, heightmm, widthcm, heightcm);
+ if( 0 <= widthmm && 0 <= heightmm ) {
+ gotsize = 1; // got mm values
+ DBG_PRINT("*** WindowsWindow: %d x %d [mm] (EDID mm)\n", widthmm, heightmm);
+ } else if( 0 <= widthcm && 0 <= heightcm ) {
+ // fallback using cm values
+ widthmm = widthcm * 10;
+ heightmm = heightcm * 10;
+ gotsize = 1;
+ DBG_PRINT("*** WindowsWindow: %d x %d [mm] (EDID cm)\n", widthmm, heightmm);
+ }
+ }
+ }
+ if( !gotsize ) {
+ // fallback using buggy API resulting in erroneous values
+ HDC hdc = NewtScreen_createDisplayDC(adapterName);
+ widthmm = GetDeviceCaps(hdc, HORZSIZE);
+ heightmm = GetDeviceCaps(hdc, VERTSIZE);
+ DeleteDC(hdc);
+ DBG_PRINT("*** WindowsWindow: %d x %d [mm] (Buggy API)\n", widthmm, heightmm);
+ }
int devModeID = ENUM_CURRENT_SETTINGS;
DEVMODE dm;
@@ -1856,7 +1939,7 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni
int propIndex = 0;
prop[propIndex++] = propCount;
- prop[propIndex++] = monitor_idx;
+ prop[propIndex++] = adapter_idx;
prop[propIndex++] = widthmm;
prop[propIndex++] = heightmm;
prop[propIndex++] = dm.dmPosition.x; // rotated viewport pixel units
@@ -1883,17 +1966,17 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni
* Signature: (IIIIIIIII)Z
*/
JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_setMonitorMode0
- (JNIEnv *env, jobject object, jint monitor_idx, jint x, jint y, jint width, jint height, jint bits, jint rate, jint flags, jint rot)
+ (JNIEnv *env, jobject object, jint adapter_idx, jint x, jint y, jint width, jint height, jint bits, jint rate, jint flags, jint rot)
{
DISPLAY_DEVICE adapterDevice, monitorDevice;
- LPCTSTR adapterName = NewtScreen_getAdapterName(&adapterDevice, monitor_idx);
+ LPCTSTR adapterName = NewtScreen_getAdapterName(&adapterDevice, adapter_idx);
if(NULL == adapterName) {
- DBG_PRINT("*** WindowsWindow: setMonitorMode.getAdapterName(monitor_idx %d) -> NULL\n", monitor_idx);
+ DBG_PRINT("*** WindowsWindow: setMonitorMode.getAdapterName(adapter_idx %d) -> NULL\n", adapter_idx);
return JNI_FALSE;
}
- LPCTSTR monitorName = NewtScreen_getMonitorName(adapterName, &monitorDevice, 0, TRUE);
- if(NULL == monitorName) {
- DBG_PRINT("*** WindowsWindow: setMonitorMode.getMonitorName(monitor_idx 0) -> NULL\n");
+ int monitor_idx = NewtScreen_getFirstActiveMonitor(adapterName, &monitorDevice);
+ if( 0 > monitor_idx ) {
+ DBG_PRINT("*** WindowsWindow: setMonitorMode.getFirstActiveMonitor(%s) -> n/a\n", adapterName);
return JNI_FALSE;
}
@@ -1981,6 +2064,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_initIDs0
WinTouch_func_avail = 0;
}
}
+ NewtEDID_avail = NewtEDID_init();
}
return JNI_TRUE;
}
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 be15e3b7e..e103fc490 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
@@ -173,6 +173,9 @@ public class TestScreenMode00aNEWT extends UITestCase {
for(final Iterator<MonitorDevice> iMonitor=monitors.iterator(); iMonitor.hasNext(); j++) {
final MonitorDevice monitor = iMonitor.next();
System.err.println(j+": "+monitor);
+ final float[] pixelPerMM = monitor.getPixelsPerMM(new float[2]);
+ System.err.println(j+" pp/mm ["+pixelPerMM[0]+", "+pixelPerMM[1]+"]");
+ System.err.println(j+" pp/in ["+pixelPerMM[0]*25.4f+", "+pixelPerMM[1]*25.4f+"]");
final List<MonitorMode> modes = monitor.getSupportedModes();
Assert.assertTrue(modes.size()>0);
int i=0;
@@ -195,21 +198,21 @@ public class TestScreenMode00aNEWT extends UITestCase {
Assert.assertNotNull(sm_c);
Assert.assertEquals(sm_o, sm_c);
}
-
+
final RectangleImmutable zero = new Rectangle();
-
+
final Rectangle monitorViewPU = new Rectangle();
final Rectangle monitorViewWU = new Rectangle();
MonitorDevice.unionOfViewports(monitorViewPU, monitorViewWU, monitors);
- System.err.println("Test.0: Monitor union viewport: "+monitorViewPU+" [pu] / "+monitorViewWU+" [wu]");
+ System.err.println("Test.0: Monitor union viewport: "+monitorViewPU+" [pu] / "+monitorViewWU+" [wu]");
Assert.assertNotEquals(zero, monitorViewPU);
- Assert.assertNotEquals(zero, monitorViewWU);
-
+ Assert.assertNotEquals(zero, monitorViewWU);
+
final RectangleImmutable screenViewPU = screen.getViewport();
- final RectangleImmutable screenViewWU = screen.getViewportInWindowUnits();
- System.err.println("Test.1: Screen viewport: "+screenViewPU+" [pu] / "+screenViewWU+" [wu]");
+ final RectangleImmutable screenViewWU = screen.getViewportInWindowUnits();
+ System.err.println("Test.1: Screen viewport: "+screenViewPU+" [pu] / "+screenViewWU+" [wu]");
Assert.assertNotEquals(zero, screenViewPU);
- Assert.assertNotEquals(zero, screenViewWU);
+ Assert.assertNotEquals(zero, screenViewWU);
screen.removeReference();