From 559ecad2a2387ba0aa34ce9e35ca8a2c5a31e655 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 17 Feb 2015 01:14:49 +0100 Subject: NEWT MonitorDevice: Identify cloned devices (fully covered) ; Windows: Iterate-over and identify all adapter:monitor. (Bug 1129) - Identify cloned devices (fully covered) - MonitorDevice gets 'isCloned()' to identify whether it is a cloned device, i.e. fully covered by another monitor. This detection may happen natively but will always performed platform agnostic. - getMainMonitor(..) now exclude 'cloned' devices - Windows: Iterate-over and identify all adapter:monitor - Since we also list cloned monitor, we need to iterate over all adapter and all it's monitor-devices. - The native monitor-id is now defined as: ( adapter-idx << 8 ) | monitor-idx. - Bug 1129 <- listed under this bug entry for convenience --- src/newt/native/MacWindow.m | 1 + src/newt/native/ScreenMode.h | 2 +- src/newt/native/WindowsWindow.c | 74 +++++++++++++++++------------------------ src/newt/native/X11RandR13.c | 14 ++++++-- 4 files changed, 44 insertions(+), 47 deletions(-) (limited to 'src/newt/native') diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index e0f8be856..690aaa505 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -517,6 +517,7 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonit int offset = 0; prop[offset++] = propCount; prop[offset++] = crt_idx; + prop[offset++] = 0; // is-clone prop[offset++] = (jint) sizeMM.width; prop[offset++] = (jint) sizeMM.height; prop[offset++] = (jint) dBounds.origin.x; // rotated viewport x (pixel units, will be fixed in java code) diff --git a/src/newt/native/ScreenMode.h b/src/newt/native/ScreenMode.h index 56c424b11..18e773107 100644 --- a/src/newt/native/ScreenMode.h +++ b/src/newt/native/ScreenMode.h @@ -40,7 +40,7 @@ #define NUM_MONITOR_MODE_PROPERTIES_ALL 8 /* count + the above */ -#define MIN_MONITOR_DEVICE_PROPERTIES 15 /* count + id, ScreenSizeMM[width, height], rotated Viewport pixel-units, rotated Viewport pixel-units, currentMonitorModeId, rotation, supportedModeId+ */ +#define MIN_MONITOR_DEVICE_PROPERTIES 16 /* count + id + is_clone, ScreenSizeMM[width, height], rotated Viewport pixel-units, rotated Viewport pixel-units, currentMonitorModeId, rotation, supportedModeId+ */ /* Viewport := [x, y, width, height] (4 elements) */ #define FLAG_INTERLACE ( 1 << 0 ) diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index d3ad69f92..7e15cd925 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -1638,6 +1638,10 @@ static int NewtScreen_RotationNewtCCW2NativeCCW(JNIEnv *env, jint newt) { } 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, adapter_idx, device, 0) ) { @@ -1653,10 +1657,14 @@ static LPCTSTR NewtScreen_getAdapterName(DISPLAY_DEVICE * device, int adapter_id } 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( FALSE == EnumDisplayDevices(adapterName, monitor_idx, device, EDD_GET_DEVICE_INTERFACE_NAME) ) { - DBG_PRINT("*** WindowsWindow: getDisplayName.EnumDisplayDevices(monitor_idx %d).adapter -> FALSE\n", monitor_idx); + DBG_PRINT("*** WindowsWindow: getMonitorName.EnumDisplayDevices(monitor_idx %d).adapter -> FALSE\n", monitor_idx); return NULL; } if( onlyActive ) { @@ -1664,10 +1672,6 @@ static LPCTSTR NewtScreen_getMonitorName(LPCTSTR adapterName, DISPLAY_DEVICE * d 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( NULL == device->DeviceName || 0 == _tcslen(device->DeviceName) ) { return NULL; @@ -1676,7 +1680,7 @@ static LPCTSTR NewtScreen_getMonitorName(LPCTSTR adapterName, DISPLAY_DEVICE * d return device->DeviceName; } -static int NewtScreen_getFirstActiveMonitor(LPCTSTR adapterName, DISPLAY_DEVICE * device) { +static int NewtScreen_getFirstActiveNonCloneMonitor(LPCTSTR adapterName, DISPLAY_DEVICE * device) { memset(device, 0, sizeof(DISPLAY_DEVICE)); device->cb = sizeof(DISPLAY_DEVICE); int monitor_idx; @@ -1706,8 +1710,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_dumpMonitorI STD_PRINT(" deviceID <%s> \n", aDevice.DeviceID); j=0; while(NULL != (dName = NewtScreen_getMonitorName(aName, &dDevice, j, FALSE))) { - 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("*** [%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++; @@ -1773,30 +1779,6 @@ JNIEXPORT jstring JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMonito #endif } -/* - * 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 @@ -1873,10 +1855,10 @@ 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 adapter_idx) + (JNIEnv *env, jobject obj, jstring jAdapterName, jint adapter_idx, jint monitor_idx, jint monitor_id) { LPCTSTR adapterName; { @@ -1887,14 +1869,15 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni #endif } - DBG_PRINT("*** WindowsWindow: adapter[name %s, idx %d], EDID-avail %d\n", adapterName, adapter_idx, NewtEDID_avail); + 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; - DISPLAY_DEVICE monitorDevice; - int monitor_idx = NewtScreen_getFirstActiveMonitor(adapterName, &monitorDevice); - if( 0 <= monitor_idx && + 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 ) { @@ -1939,7 +1922,8 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni int propIndex = 0; prop[propIndex++] = propCount; - prop[propIndex++] = adapter_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 @@ -1974,10 +1958,14 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_setMonit DBG_PRINT("*** WindowsWindow: setMonitorMode.getAdapterName(adapter_idx %d) -> NULL\n", adapter_idx); return JNI_FALSE; } - int monitor_idx = NewtScreen_getFirstActiveMonitor(adapterName, &monitorDevice); - if( 0 > monitor_idx ) { - DBG_PRINT("*** WindowsWindow: setMonitorMode.getFirstActiveMonitor(%s) -> n/a\n", adapterName); - 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; diff --git a/src/newt/native/X11RandR13.c b/src/newt/native/X11RandR13.c index 4e92a32b4..5eacbf216 100644 --- a/src/newt/native/X11RandR13.c +++ b/src/newt/native/X11RandR13.c @@ -67,9 +67,16 @@ static void dumpOutputs(const char *prefix, Display *dpy, XRRScreenResources *re for(i=0; icrtc, SAFE_STRING(xrrOutputInfo->name), xrrOutputInfo->nameLen, xrrOutputInfo->mm_width, xrrOutputInfo->mm_height, - xrrOutputInfo->ncrtc, xrrOutputInfo->nmode, xrrOutputInfo->npreferred); + fprintf(stderr, " Output[%d]: id %#lx, crtx 0x%X, name %s (%d), %lux%lu, ncrtc %d, nclone %d, nmode %d (preferred %d)\n", + i, output, xrrOutputInfo->crtc, SAFE_STRING(xrrOutputInfo->name), xrrOutputInfo->nameLen, + xrrOutputInfo->mm_width, xrrOutputInfo->mm_height, + xrrOutputInfo->ncrtc, xrrOutputInfo->nclone, xrrOutputInfo->nmode, xrrOutputInfo->npreferred); + for(j=0; jncrtc; j++) { + fprintf(stderr, " Output[%d].Crtc[%d].id %#lx\n", i, j, xrrOutputInfo->crtcs[j]); + } + for(j=0; jnclone; j++) { + fprintf(stderr, " Output[%d].Clones[%d].id %#lx\n", i, j, xrrOutputInfo->clones[j]); + } for(j=0; jnmode; j++) { fprintf(stderr, " Output[%d].Mode[%d].id %#lx\n", i, j, xrrOutputInfo->modes[j]); } @@ -424,6 +431,7 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorDevice prop[propIndex++] = propCount; prop[propIndex++] = crt_idx; + prop[propIndex++] = 0; // is_clone, does not work: 0 < xrrOutputInfo->nclone ? 1 : 0; prop[propIndex++] = xrrOutputInfo->mm_width; prop[propIndex++] = xrrOutputInfo->mm_height; prop[propIndex++] = xrrCrtcInfo->x; // rotated viewport pixel units -- cgit v1.2.3