diff options
Diffstat (limited to 'src/newt/native/WindowsWindow.c')
-rw-r--r-- | src/newt/native/WindowsWindow.c | 150 |
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; } |