From 0adbc977ac7848e8092fa1d58174d0a37aabb86b Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Mon, 9 Mar 2015 15:45:36 +0100 Subject: Bug 1142 - NEWT: Add support to retrieve the primary MonitorDevice Support added for - Windows - X11 XRandR 1.3 - OSX Note: Our whole MonitorMode association handling is currently _not_ dynamic. - only on Windows we actually use native unique ID, which might not change (adapter and monitor idx) - On OSX and X11 we simply use indices, but if monitor setup changes - they refer to different instances. In case it is desired to cover dynamic monitor setup change, we need to address this issue in a new bug entry. --- src/newt/native/MacWindow.m | 3 +- src/newt/native/ScreenMode.h | 12 ++++++-- src/newt/native/WindowsWindow.c | 66 +++++++++++++++++++++++++++-------------- src/newt/native/X11RandR13.c | 29 +++++++++++++----- 4 files changed, 77 insertions(+), 33 deletions(-) (limited to 'src/newt/native') diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index 690aaa505..fbac6b37e 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -517,7 +517,8 @@ 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++] = 0; // isClone + prop[offset++] = 0 == crt_idx ? 1 : 0; // isPrimary 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 18e773107..5ae865b8e 100644 --- a/src/newt/native/ScreenMode.h +++ b/src/newt/native/ScreenMode.h @@ -40,8 +40,16 @@ #define NUM_MONITOR_MODE_PROPERTIES_ALL 8 /* count + the above */ -#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 MIN_MONITOR_DEVICE_PROPERTIES 17 /* count + id + isClone + isPrimary, + ScreenSizeMM[width, height], + rotated Viewport pixel-units, + rotated Viewport pixel-units, + currentMonitorModeId, + rotation, + supportedModeId+ + + with Viewport := [x, y, width, height] (4 elements) + */ #define FLAG_INTERLACE ( 1 << 0 ) #define FLAG_DOUBLESCAN ( 1 << 1 ) diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index 7e15cd925..8c29978f0 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -124,9 +124,28 @@ #ifndef EDS_ROTATEDMODE #define EDS_ROTATEDMODE 0x00000004 #endif + +// #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001 +// #define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002 +#ifndef DISPLAY_DEVICE_PRIMARY_DEVICE +#define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004 +#endif +#ifndef DISPLAY_DEVICE_MIRRORING_DRIVER +#define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008 +#endif +// #define DISPLAY_DEVICE_VGA_COMPATIBLE 0x00000010 +// #define DISPLAY_DEVICE_REMOVABLE 0x00000020 +// #define DISPLAY_DEVICE_MODESPRUNED 0x08000000 +// #define DISPLAY_DEVICE_REMOTE 0x04000000 +// #define DISPLAY_DEVICE_DISCONNECT 0x02000000 + #ifndef DISPLAY_DEVICE_ACTIVE #define DISPLAY_DEVICE_ACTIVE 0x00000001 #endif +#ifndef DISPLAY_DEVICE_ATTACHED +#define DISPLAY_DEVICE_ATTACHED 0x00000002 +#endif + #ifndef DM_INTERLACED #define DM_INTERLACED 2 #endif @@ -1704,8 +1723,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_dumpMonitorI int i = 0, j; LPCTSTR aName, dName; while(NULL != (aName = NewtScreen_getAdapterName(&aDevice, i))) { - STD_PRINT("*** [%02d:__]: deviceName <%s> flags 0x%X active %d\n", - i, aDevice.DeviceName, aDevice.StateFlags, ( 0 != ( aDevice.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) ); + STD_PRINT("*** [%02d:__]: deviceName <%s>, flags 0x%X, active %d, primary %d\n", + i, aDevice.DeviceName, aDevice.StateFlags, + ( 0 != ( aDevice.StateFlags & DISPLAY_DEVICE_ACTIVE ) ), + ( 0 != ( aDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE ) )); STD_PRINT(" deviceString <%s> \n", aDevice.DeviceString); STD_PRINT(" deviceID <%s> \n", aDevice.DeviceID); j=0; @@ -1858,27 +1879,30 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni * 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, jint monitor_idx, jint monitor_id) + (JNIEnv *env, jobject obj, jint adapter_idx, jint monitor_idx, jint monitor_id) { - LPCTSTR adapterName; - { -#ifdef UNICODE - adapterName = NewtCommon_GetNullTerminatedStringChars(env, jAdapterName); -#else - adapterName = (*env)->GetStringUTFChars(env, jAdapterName, NULL); -#endif - } + int gotsize = 0; + int widthmm, heightmm; + DISPLAY_DEVICE adapterDevice, monitorDevice; + LPCTSTR monitorName = NULL; + LPCTSTR adapterName = NULL; + adapterName = NewtScreen_getAdapterName(&adapterDevice, adapter_idx); + if( NULL == adapterName ) { + DBG_PRINT("ERROR WindowsWindow: adapter[idx %d]: NULL\n", adapter_idx); + return (*env)->NewIntArray(env, 0); + } 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); + + monitorName = NewtScreen_getMonitorName(adapterName, &monitorDevice, monitor_idx, TRUE); + if( NULL == monitorName ) { + DBG_PRINT("ERROR WindowsWindow: monitor[idx %d]: NULL\n", monitor_idx); + return (*env)->NewIntArray(env, 0); + } if( NewtEDID_avail ) { int widthcm, heightcm; - if( NULL != monitorName && - NewtEDID_GetMonitorSizeFromEDIDByDevice(&monitorDevice, &widthmm, &heightmm, &widthcm, &heightcm) ) { + if( 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 @@ -1908,11 +1932,6 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni int res = EnumDisplaySettingsEx(adapterName, devModeID, &dm, 0); DBG_PRINT("*** WindowsWindow: getMonitorDevice.EnumDisplaySettingsEx(%s, devModeID %d) -> %d\n", adapterName, devModeID, res); -#ifdef UNICODE - free((void*) adapterName); -#else - (*env)->ReleaseStringUTFChars(env, jAdapterName, adapterName); -#endif if (0 == res) { return (*env)->NewIntArray(env, 0); } @@ -1923,7 +1942,8 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni prop[propIndex++] = propCount; prop[propIndex++] = monitor_id; - prop[propIndex++] = NULL != monitorName && 0 != ( monitorDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER ); + prop[propIndex++] = 0 != ( monitorDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER ); // isClone + prop[propIndex++] = 0 != ( adapterDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE ); // isPrimary prop[propIndex++] = widthmm; prop[propIndex++] = heightmm; prop[propIndex++] = dm.dmPosition.x; // rotated viewport pixel units diff --git a/src/newt/native/X11RandR13.c b/src/newt/native/X11RandR13.c index 1d721efcb..4f52ad190 100644 --- a/src/newt/native/X11RandR13.c +++ b/src/newt/native/X11RandR13.c @@ -61,16 +61,23 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_RandR13_freeScreenResources0 #define SAFE_STRING(s) (NULL==s?"":s) -static void dumpOutputs(const char *prefix, Display *dpy, XRRScreenResources *resources, int noutput, RROutput * outputs) { - int i, j; - fprintf(stderr, "%s %p: Output count %d\n", prefix, resources, noutput); +static void dumpOutputs(const char *prefix, Display *dpy, int screen_idx, XRRScreenResources *resources, int noutput, RROutput * outputs) { + int i, j, primIdx=0; + Window root = RootWindow(dpy, screen_idx); + RROutput pxid = XRRGetOutputPrimary (dpy, root); + fprintf(stderr, "%s %p: Output[count %d, prim %#lx]\n", prefix, resources, noutput, pxid); for(i=0; icrtc, SAFE_STRING(xrrOutputInfo->name), xrrOutputInfo->nameLen, xrrOutputInfo->mm_width, xrrOutputInfo->mm_height, - xrrOutputInfo->ncrtc, xrrOutputInfo->nclone, xrrOutputInfo->nmode, xrrOutputInfo->npreferred); + xrrOutputInfo->ncrtc, xrrOutputInfo->nclone, xrrOutputInfo->nmode, xrrOutputInfo->npreferred, isPrim); for(j=0; jncrtc; j++) { fprintf(stderr, " Output[%d].Crtc[%d].id %#lx\n", i, j, xrrOutputInfo->crtcs[j]); } @@ -145,7 +152,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_RandR13_dumpInfo0 XRRFreeCrtcInfo(xrrCrtcInfo); } - dumpOutputs("XRRScreenResources.outputs", dpy, resources, resources->noutput, resources->outputs); + dumpOutputs("XRRScreenResources.outputs", dpy, (int)screen_idx, resources, resources->noutput, resources->outputs); fprintf(stderr, "XRRScreenResources %p: Mode count %d\n", resources, resources->nmode); for(i=0; inmode; i++) { @@ -421,7 +428,14 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorDevice return NULL; } + Window root = RootWindow(dpy, 0); // FIXME screen_idx); + RROutput pxid = XRRGetOutputPrimary (dpy, root); + int isPrimary = 0; + RROutput output = xrrCrtcInfo->outputs[0]; + if ( None != pxid && pxid == output ) { + isPrimary = 1; + } XRROutputInfo * xrrOutputInfo = XRRGetOutputInfo (dpy, resources, output); int numModes = xrrOutputInfo->nmode; @@ -431,7 +445,8 @@ 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++] = 0; // isClone, does not work: 0 < xrrOutputInfo->nclone ? 1 : 0; + prop[propIndex++] = isPrimary; prop[propIndex++] = xrrOutputInfo->mm_width; prop[propIndex++] = xrrOutputInfo->mm_height; prop[propIndex++] = xrrCrtcInfo->x; // rotated viewport pixel units -- cgit v1.2.3