summaryrefslogtreecommitdiffstats
path: root/src/newt/native/WindowsWindow.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/native/WindowsWindow.c')
-rw-r--r--src/newt/native/WindowsWindow.c150
1 files changed, 111 insertions, 39 deletions
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index 70d0c6f83..7e15cd925 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,15 @@ 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) {
+ if( 0 > adapter_idx ) {
+ DBG_PRINT("*** WindowsWindow: getAdapterName(adapter_idx %d < 0)\n", adapter_idx);
+ return NULL;
+ }
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;
}
@@ -1645,19 +1657,22 @@ static LPCTSTR NewtScreen_getAdapterName(DISPLAY_DEVICE * device, int crt_idx) {
}
static LPCTSTR NewtScreen_getMonitorName(LPCTSTR adapterName, DISPLAY_DEVICE * device, int monitor_idx, BOOL onlyActive) {
+ if( 0 > monitor_idx ) {
+ DBG_PRINT("*** WindowsWindow: getMonitorName(monitor_idx %d < 0)\n", monitor_idx);
+ return NULL;
+ }
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: getMonitorName.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( 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 +1680,23 @@ static LPCTSTR NewtScreen_getMonitorName(LPCTSTR adapterName, DISPLAY_DEVICE * d
return device->DeviceName;
}
+static int NewtScreen_getFirstActiveNonCloneMonitor(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 +1704,18 @@ 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, mirror %d\n",
+ i, j, dDevice.DeviceName, dDevice.StateFlags,
+ 0 != ( dDevice.StateFlags & DISPLAY_DEVICE_ACTIVE ),
+ 0 != ( dDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER ) );
+ STD_PRINT(" deviceString <%s> \n", dDevice.DeviceString);
+ STD_PRINT(" deviceID <%s> \n", dDevice.DeviceID);
j++;
}
i++;
@@ -1692,11 +1732,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 +1750,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
@@ -1815,12 +1855,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni
/*
* Class: jogamp_newt_driver_windows_ScreenDriver
* Method: getMonitorDevice0
- * Signature: (Ljava/lang/String;I)[I
+ * Signature: (Ljava/lang/String;II)[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, jint monitor_idx, jint monitor_id)
{
- DISPLAY_DEVICE device;
LPCTSTR adapterName;
{
#ifdef UNICODE
@@ -1830,10 +1869,37 @@ 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], monitor[idx %d, id %d], EDID-avail %d\n",
+ adapterName, adapter_idx, monitor_idx, monitor_id, NewtEDID_avail);
+ int gotsize = 0;
+ int widthmm, heightmm;
+ DISPLAY_DEVICE monitorDevice;
+ LPCTSTR monitorName = NewtScreen_getMonitorName(adapterName, &monitorDevice, monitor_idx, TRUE);
+ if( NewtEDID_avail ) {
+ int widthcm, heightcm;
+ if( NULL != monitorName &&
+ 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 +1922,8 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni
int propIndex = 0;
prop[propIndex++] = propCount;
- prop[propIndex++] = monitor_idx;
+ prop[propIndex++] = monitor_id;
+ prop[propIndex++] = NULL != monitorName && 0 != ( monitorDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER );
prop[propIndex++] = widthmm;
prop[propIndex++] = heightmm;
prop[propIndex++] = dm.dmPosition.x; // rotated viewport pixel units
@@ -1883,18 +1950,22 @@ 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");
- return JNI_FALSE;
+
+ {
+ // Just test whether there is an active non-mirror monitor attached
+ int monitor_idx = NewtScreen_getFirstActiveNonCloneMonitor(adapterName, &monitorDevice);
+ if( 0 > monitor_idx ) {
+ DBG_PRINT("*** WindowsWindow: setMonitorMode.getFirstActiveNonCloneMonitor(%s) -> n/a\n", adapterName);
+ return JNI_FALSE;
+ }
}
DEVMODE dm;
@@ -1981,6 +2052,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_initIDs0
WinTouch_func_avail = 0;
}
}
+ NewtEDID_avail = NewtEDID_init();
}
return JNI_TRUE;
}