diff options
Diffstat (limited to 'src/newt/native')
-rw-r--r-- | src/newt/native/MacWindow.m | 235 | ||||
-rw-r--r-- | src/newt/native/NewtMacWindow.h | 1 | ||||
-rw-r--r-- | src/newt/native/NewtMacWindow.m | 4 | ||||
-rw-r--r-- | src/newt/native/ScreenMode.h | 15 | ||||
-rw-r--r-- | src/newt/native/Window.h | 17 | ||||
-rw-r--r-- | src/newt/native/WindowsWindow.c | 305 | ||||
-rw-r--r-- | src/newt/native/X11RandR11.c | 44 | ||||
-rw-r--r-- | src/newt/native/X11RandR13.c | 597 | ||||
-rw-r--r-- | src/newt/native/X11Screen.c | 31 | ||||
-rw-r--r-- | src/newt/native/X11Screen.h | 1 | ||||
-rw-r--r-- | src/newt/native/X11Window.c | 18 |
11 files changed, 773 insertions, 495 deletions
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index c0552216e..1c7064a66 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -285,47 +285,32 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_stopNSApplic [pool release]; } -static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx) { +static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx, BOOL cap) { NSArray *screens = [NSScreen screens]; - if(screen_idx<0) screen_idx=0; - if(screen_idx>=[screens count]) screen_idx=0; + if( screen_idx<0 || screen_idx>=[screens count] ) { + if( cap ) { + screen_idx=0; + } else { + return NULL; + } + } return (NSScreen *) [screens objectAtIndex: screen_idx]; } -/* - * Class: jogamp_newt_driver_macosx_ScreenDriver - * Method: getWidthImpl - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getWidthImpl0 - (JNIEnv *env, jclass clazz, jint screen_idx) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - NSScreen *screen = NewtScreen_getNSScreenByIndex((int)screen_idx); - NSRect rect = [screen frame]; - - [pool release]; - - return (jint) (rect.size.width); -} - -/* - * Class: jogamp_newt_driver_macosx_ScreenDriver - * Method: getHeightImpl - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getHeightImpl0 - (JNIEnv *env, jclass clazz, jint screen_idx) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - NSScreen *screen = NewtScreen_getNSScreenByIndex((int)screen_idx); - NSRect rect = [screen frame]; - - [pool release]; - - return (jint) (rect.size.height); +static NSScreen * NewtScreen_getNSScreenByCoord(int x, int y) { + NSArray *screens = [NSScreen screens]; + int i; + for(i=[screens count]-1; i>=0; i--) { + NSScreen * screen = (NSScreen *) [screens objectAtIndex: i]; + NSRect frame = [screen frame]; + if( x >= frame.origin.x && + y >= frame.origin.y && + x < frame.origin.x + frame.size.width && + y < frame.origin.y + frame.size.height ) { + return screen; + } + } + return (NSScreen *) [screens objectAtIndex: 0]; } static CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen) { @@ -362,11 +347,11 @@ static long GetDictionaryLong(CFDictionaryRef theDict, const void* key) /* * Class: jogamp_newt_driver_macosx_ScreenDriver - * Method: getScreenSizeMM0 + * Method: getMonitorProps0 * Signature: (I)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScreenSizeMM0 - (JNIEnv *env, jobject obj, jint scrn_idx) +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonitorProps0 + (JNIEnv *env, jobject obj, jint crt_idx) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -376,33 +361,46 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScree timespec_now(&t0); #endif - NSScreen *screen = NewtScreen_getNSScreenByIndex((int)scrn_idx); #ifdef DBG_PERF timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); - fprintf(stderr, "MacScreen_getScreenSizeMM0.1: %ld ms\n", td_ms); fflush(NULL); + fprintf(stderr, "MacScreen_getMonitorProps0.1: %ld ms\n", td_ms); fflush(NULL); #endif - + NSScreen *screen = NewtScreen_getNSScreenByIndex((int)crt_idx, false); + if( NULL == screen ) { + [pool release]; + return NULL; + } CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen); #ifdef DBG_PERF timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); - fprintf(stderr, "MacScreen_getScreenSizeMM0.2: %ld ms\n", td_ms); fflush(NULL); + fprintf(stderr, "MacScreen_getMonitorProps0.2: %ld ms\n", td_ms); fflush(NULL); #endif - CGSize screenDim = CGDisplayScreenSize(display); + CGSize sizeMM = CGDisplayScreenSize(display); #ifdef DBG_PERF timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); - fprintf(stderr, "MacScreen_getScreenSizeMM0.3: %ld ms\n", td_ms); fflush(NULL); + fprintf(stderr, "MacScreen_getMonitorProps0.3: %ld ms\n", td_ms); fflush(NULL); #endif - jint prop[ 2 ]; - prop[0] = (jint) screenDim.width; - prop[1] = (jint) screenDim.height; - - jintArray properties = (*env)->NewIntArray(env, 2); + CGRect bounds = CGDisplayBounds (display); + + jsize propCount = MIN_MONITOR_DEVICE_PROPERTIES - 1 - NUM_MONITOR_MODE_PROPERTIES; + jint prop[ propCount ]; + int offset = 0; + prop[offset++] = propCount; + prop[offset++] = crt_idx; + prop[offset++] = (jint) sizeMM.width; + prop[offset++] = (jint) sizeMM.height; + prop[offset++] = (jint) bounds.origin.x; // rotated viewport x + prop[offset++] = (jint) bounds.origin.y; // rotated viewport y + prop[offset++] = (jint) bounds.size.width; // rotated viewport width + prop[offset++] = (jint) bounds.size.height; // rotated viewport height + + jintArray properties = (*env)->NewIntArray(env, propCount); if (properties == NULL) { - NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size 2"); + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", propCount); } - (*env)->SetIntArrayRegion(env, properties, 0, 2, prop); + (*env)->SetIntArrayRegion(env, properties, 0, propCount, prop); [pool release]; @@ -411,16 +409,19 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScree /* * Class: jogamp_newt_driver_macosx_ScreenDriver - * Method: getScreenMode0 - * Signature: (IIII)[I + * Method: getMonitorMode0 + * Signature: (II)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScreenMode0 - (JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx, jint widthMM, jint heightMM) +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonitorMode0 + (JNIEnv *env, jobject obj, jint crt_idx, jint mode_idx) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - int prop_num = NUM_SCREEN_MODE_PROPERTIES_ALL; - NSScreen *screen = NewtScreen_getNSScreenByIndex((int)scrn_idx); + NSScreen *screen = NewtScreen_getNSScreenByIndex((int)crt_idx, false); + if( NULL == screen ) { + [pool release]; + return NULL; + } CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen); CFArrayRef availableModes = CGDisplayAvailableModes(display); @@ -429,12 +430,13 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScree CFDictionaryRef mode = NULL; int currentCCWRot = (int)CGDisplayRotation(display); jint ccwRot = 0; + int nativeId = 0; #ifdef VERBOSE_ON if(0 >= mode_idx) { // only for current mode (-1) and first mode (scanning) DBG_PRINT( "getScreenMode0: scrn %d (%p, %p), mode %d, avail: %d/%d, current rot %d ccw\n", - (int)scrn_idx, screen, (void*)(intptr_t)display, (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots, currentCCWRot); + (int)crt_idx, screen, (void*)(intptr_t)display, (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots, currentCCWRot); } #endif @@ -443,16 +445,18 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScree DBG_PRINT( "getScreenMode0: end of modes: mode %d, avail: %d/%d\n", (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots); [pool release]; - return (*env)->NewIntArray(env, 0); + return NULL; } else if(-1 < mode_idx) { // only at initialization time, where index >= 0 - prop_num++; // add 1st extra prop, mode_idx - mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, mode_idx / ROTMODES_PER_REALMODE); + nativeId = mode_idx / ROTMODES_PER_REALMODE; ccwRot = mode_idx % ROTMODES_PER_REALMODE * 90; + mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, nativeId); } else { // current mode mode = CGDisplayCurrentMode(display); ccwRot = currentCCWRot; + CFRange range = CFRangeMake (0, numberOfAvailableModes); + nativeId = CFArrayGetFirstIndexOfValue(availableModes, range, (CFDictionaryRef)mode); } // mode = CGDisplayModeRetain(mode); // 10.6 on CGDisplayModeRef @@ -466,36 +470,30 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScree mHeight = tempWidth; } - jint prop[ prop_num ]; + jint prop[ NUM_MONITOR_MODE_PROPERTIES_ALL ]; int propIndex = 0; - int propIndexRes = 0; - if( -1 < mode_idx ) { - prop[propIndex++] = mode_idx; - } int refreshRate = CGDDGetModeRefreshRate(mode); int fRefreshRate = ( 0 < refreshRate ) ? refreshRate : 60; // default .. (experienced on OSX 10.6.8) - prop[propIndex++] = 0; // set later for verification of iterator - propIndexRes = propIndex; + prop[propIndex++] = NUM_MONITOR_MODE_PROPERTIES_ALL; prop[propIndex++] = mWidth; prop[propIndex++] = mHeight; prop[propIndex++] = CGDDGetModeBitsPerPixel(mode); - prop[propIndex++] = widthMM; - prop[propIndex++] = heightMM; - prop[propIndex++] = fRefreshRate; + prop[propIndex++] = fRefreshRate * 100; // Hz*100 + prop[propIndex++] = 0; // flags + prop[propIndex++] = nativeId; prop[propIndex++] = ccwRot; - prop[propIndex - NUM_SCREEN_MODE_PROPERTIES_ALL] = ( -1 < mode_idx ) ? propIndex-1 : propIndex ; // count == NUM_SCREEN_MODE_PROPERTIES_ALL - DBG_PRINT( "getScreenMode0: Mode %d/%d (%d): %dx%d, %d bpp, %dx%d mm, %d / %d Hz, rot %d ccw\n", + DBG_PRINT( "getScreenMode0: Mode %d/%d (%d): %dx%d, %d bpp, %d / %d Hz, nativeId %d, rot %d ccw\n", (int)mode_idx, (int)numberOfAvailableModesRots, (int)numberOfAvailableModes, - (int)prop[propIndexRes+0], (int)prop[propIndexRes+1], (int)prop[propIndexRes+2], - (int)prop[propIndexRes+3], (int)prop[propIndexRes+4], (int)prop[propIndexRes+5], refreshRate, (int)prop[propIndexRes+6]); + (int)prop[1], (int)prop[2], (int)prop[3], + (int)prop[4], refreshRate, (int)prop[6], (int)prop[7]); - jintArray properties = (*env)->NewIntArray(env, prop_num); + jintArray properties = (*env)->NewIntArray(env, NUM_MONITOR_MODE_PROPERTIES_ALL); if (properties == NULL) { - NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", prop_num); + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", NUM_MONITOR_MODE_PROPERTIES_ALL); } - (*env)->SetIntArrayRegion(env, properties, 0, prop_num, prop); + (*env)->SetIntArrayRegion(env, properties, 0, NUM_MONITOR_MODE_PROPERTIES_ALL, prop); // CGDisplayModeRelease(mode); // 10.6 on CGDisplayModeRef [pool release]; @@ -505,36 +503,47 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScree /* * Class: jogamp_newt_driver_macosx_ScreenDriver - * Method: setScreenMode0 - * Signature: (II)Z + * Method: setMonitorMode0 + * Signature: (III)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_setScreenMode0 - (JNIEnv *env, jobject object, jint scrn_idx, jint mode_idx) +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_setMonitorMode0 + (JNIEnv *env, jobject object, jint crt_idx, jint nativeId, jint ccwRot) { jboolean res = JNI_TRUE; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSScreen *screen = NewtScreen_getNSScreenByIndex((int)scrn_idx); + NSScreen *screen = NewtScreen_getNSScreenByIndex((int)crt_idx, false); + if( NULL == screen ) { + [pool release]; + return JNI_FALSE; + } CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen); CFArrayRef availableModes = CGDisplayAvailableModes(display); -#ifdef VERBOSE_ON CFIndex numberOfAvailableModes = CFArrayGetCount(availableModes); +#ifdef VERBOSE_ON CFIndex numberOfAvailableModesRots = ROTMODES_PER_REALMODE * numberOfAvailableModes; #endif - CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, mode_idx / ROTMODES_PER_REALMODE); - // mode = CGDisplayModeRetain(mode); // 10.6 on CGDisplayModeRef - int ccwRot = mode_idx % ROTMODES_PER_REALMODE * 90; - DBG_PRINT( "setScreenMode0: scrn %d (%p, %p), mode %d, rot %d ccw, avail: %d/%d\n", - (int)scrn_idx, screen, (void*)(intptr_t)display, (int)mode_idx, ccwRot, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots); + DBG_PRINT( "setScreenMode0: scrn %d (%p, %p), nativeID %d, rot %d ccw, avail: %d/%d\n", + (int)crt_idx, screen, (void*)(intptr_t)display, (int)nativeId, ccwRot, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots); + + CFDictionaryRef mode = NULL; - if(ccwRot!=0) { + if( 0 != ccwRot ) { // FIXME: How to rotate the display/screen on OSX programmatically ? DBG_PRINT( "setScreenMode0: Don't know how to rotate screen on OS X: rot %d ccw\n", ccwRot); res = JNI_FALSE; + } else { + if( numberOfAvailableModes <= nativeId ) { + res = JNI_FALSE; + } else { + mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, nativeId); + // mode = CGDisplayModeRetain(mode); // 10.6 on CGDisplayModeRef + } } - if(JNI_TRUE == res) { + + if( NULL != mode ) { CGError err = CGDisplaySwitchToMode(display, mode); if(kCGErrorSuccess != err) { DBG_PRINT( "setScreenMode0: SetMode failed: %d\n", (int)err); @@ -593,21 +602,18 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0 /** * Class: jogamp_newt_driver_macosx_WindowDriver * Method: createView0 - * Signature: (IIIIZI)J + * Signature: (IIIIZ)J */ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createView0 (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h, - jboolean fullscreen, jint screen_idx) + jboolean fullscreen) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - DBG_PRINT( "createView0 - %p (this), %d/%d %dx%d, fs %d, screenidx %d (START)\n", - (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen, (int)screen_idx); + DBG_PRINT( "createView0 - %p (this), %d/%d %dx%d, fs %d (START)\n", + (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen); - NSArray *screens = [NSScreen screens]; - if(screen_idx<0) screen_idx=0; - if(screen_idx>=[screens count]) screen_idx=0; - NSScreen *myScreen = (NSScreen *) [screens objectAtIndex: screen_idx]; + NSScreen *myScreen = NewtScreen_getNSScreenByCoord(x, y); NSRect rectWin; if (fullscreen) { @@ -634,24 +640,21 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createView0 * * Class: jogamp_newt_driver_macosx_WindowDriver * Method: createWindow0 - * Signature: (IIIIZIIIJ)J + * Signature: (IIIIZIIJ)J */ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow0 (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h, - jboolean fullscreen, jint styleMask, jint bufferingType, jint screen_idx, jlong jview) + jboolean fullscreen, jint styleMask, jint bufferingType, jlong jview) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NewtView* myView = (NewtView*) (intptr_t) jview ; DBG_PRINT( "createWindow0 - %p (this), %d/%d %dx%d, fs %d, style %X, buffType %X, screenidx %d, view %p (START)\n", (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen, - (int)styleMask, (int)bufferingType, (int)screen_idx, myView); + (int)styleMask, (int)bufferingType, myView); (void)myView; - NSArray *screens = [NSScreen screens]; - if(screen_idx<0) screen_idx=0; - if(screen_idx>=[screens count]) screen_idx=0; - NSScreen *myScreen = (NSScreen *) [screens objectAtIndex: screen_idx]; + NSScreen *myScreen = NewtScreen_getNSScreenByCoord(x, y); NSRect rectWin; if (fullscreen) { @@ -670,7 +673,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow styleMask: (NSUInteger) styleMask backing: (NSBackingStoreType) bufferingType defer: YES - screen: myScreen isFullscreenWindow: fullscreen]; // DBG_PRINT( "createWindow0.1 - %p, isVisible %d\n", myWindow, [myWindow isVisible]); @@ -687,26 +689,23 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow * * Class: jogamp_newt_driver_macosx_WindowDriver * Method: initWindow0 - * Signature: (JJIIIIZZZIJ)V + * Signature: (JJIIIIZZZJ)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initWindow0 (JNIEnv *env, jobject jthis, jlong parent, jlong window, jint x, jint y, jint w, jint h, - jboolean opaque, jboolean fullscreen, jboolean visible, jint screen_idx, jlong jview) + jboolean opaque, jboolean fullscreen, jboolean visible, jlong jview) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window); NewtView* myView = (NewtView*) (intptr_t) jview ; - DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, opaque %d, fs %d, visible %d, screenidx %d, view %p (START)\n", + DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, opaque %d, fs %d, visible %d, view %p (START)\n", (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, (int)x, (int)y, (int)w, (int)h, - (int) opaque, (int)fullscreen, (int)visible, (int)screen_idx, myView); + (int) opaque, (int)fullscreen, (int)visible, myView); - NSArray *screens = [NSScreen screens]; - if(screen_idx<0) screen_idx=0; - if(screen_idx>=[screens count]) screen_idx=0; - NSScreen *myScreen = (NSScreen *) [screens objectAtIndex: screen_idx]; - NSRect rectWin; + NSScreen *myScreen = NewtScreen_getNSScreenByCoord(x, y); + NSRect rectWin; if (fullscreen) { rectWin = [myScreen frame]; x = 0; diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h index 09f4a1fd3..c9d53f53b 100644 --- a/src/newt/native/NewtMacWindow.h +++ b/src/newt/native/NewtMacWindow.h @@ -128,7 +128,6 @@ styleMask: (NSUInteger) windowStyle backing: (NSBackingStoreType) bufferingType defer: (BOOL) deferCreation - screen:(NSScreen *)screen isFullscreenWindow:(BOOL)isfs; #ifdef DBG_LIFECYCLE - (void) release; diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m index 005e82d72..35d3ffbc5 100644 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -439,14 +439,12 @@ static UniChar CKCH_CharForKeyCode(jshort keyCode) { styleMask: (NSUInteger) windowStyle backing: (NSBackingStoreType) bufferingType defer: (BOOL) deferCreation - screen:(NSScreen *)screen isFullscreenWindow:(BOOL)isfs { id res = [super initWithContentRect: contentRect styleMask: windowStyle backing: bufferingType - defer: deferCreation - screen: screen]; + defer: deferCreation]; isFullscreenWindow = isfs; // Why is this necessary? Without it we don't get any of the // delegate methods like resizing and window movement. diff --git a/src/newt/native/ScreenMode.h b/src/newt/native/ScreenMode.h index bb782910e..110f1c493 100644 --- a/src/newt/native/ScreenMode.h +++ b/src/newt/native/ScreenMode.h @@ -33,12 +33,17 @@ #ifndef _SCREEN_MODE_H #define _SCREEN_MODE_H -#define NUM_RESOLUTION_PROPERTIES 2 /* width, height */ -#define NUM_SURFACE_SIZE_PROPERTIES 1 /* bpp */ -#define NUM_MONITOR_MODE_PROPERTIES 3 /* ScreenSizeMM[width, height], refresh-rate */ -#define NUM_SCREEN_MODE_PROPERTIES 1 /* rotation */ +#define NUM_RESOLUTION_PROPERTIES 2 /* width, height */ +#define NUM_SURFACE_SIZE_PROPERTIES 1 /* bpp */ +#define NUM_SIZEANDRATE_PROPERTIES 2 /* refresh-rate, flags */ +#define NUM_MONITOR_MODE_PROPERTIES 2 /* id, rotation */ -#define NUM_SCREEN_MODE_PROPERTIES_ALL 8 /* count + the above */ +#define NUM_MONITOR_MODE_PROPERTIES_ALL 8 /* count + the above */ + +#define MIN_MONITOR_DEVICE_PROPERTIES 11 /* count + id, ScreenSizeMM[width, height], rotated Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+ */ + +#define FLAG_INTERLACE ( 1 << 0 ) +#define FLAG_DOUBLESCAN ( 1 << 1 ) #endif diff --git a/src/newt/native/Window.h b/src/newt/native/Window.h index 4755c4fc5..d9ee5fd1f 100644 --- a/src/newt/native/Window.h +++ b/src/newt/native/Window.h @@ -38,8 +38,9 @@ #define FLAG_HAS_PARENT ( 1 << 8 ) #define FLAG_IS_UNDECORATED ( 1 << 9 ) #define FLAG_IS_FULLSCREEN ( 1 << 10 ) -#define FLAG_IS_ALWAYSONTOP ( 1 << 11 ) -#define FLAG_IS_VISIBLE ( 1 << 12 ) +#define FLAG_IS_FULLSCREEN_SPAN ( 1 << 11 ) +#define FLAG_IS_ALWAYSONTOP ( 1 << 12 ) +#define FLAG_IS_VISIBLE ( 1 << 13 ) #define TST_FLAG_CHANGE_PARENTING(f) ( 0 != ( (f) & FLAG_CHANGE_PARENTING ) ) #define TST_FLAG_CHANGE_DECORATION(f) ( 0 != ( (f) & FLAG_CHANGE_DECORATION ) ) @@ -47,11 +48,11 @@ #define TST_FLAG_CHANGE_ALWAYSONTOP(f) ( 0 != ( (f) & FLAG_CHANGE_ALWAYSONTOP ) ) #define TST_FLAG_CHANGE_VISIBILITY(f) ( 0 != ( (f) & FLAG_CHANGE_VISIBILITY ) ) -#define TST_FLAG_HAS_PARENT(f) ( 0 != ( (f) & FLAG_HAS_PARENT ) ) -#define TST_FLAG_IS_UNDECORATED(f) ( 0 != ( (f) & FLAG_IS_UNDECORATED ) ) -#define TST_FLAG_IS_FULLSCREEN(f) ( 0 != ( (f) & FLAG_IS_FULLSCREEN ) ) -#define TST_FLAG_IS_FULLSCREEN(f) ( 0 != ( (f) & FLAG_IS_FULLSCREEN ) ) -#define TST_FLAG_IS_ALWAYSONTOP(f) ( 0 != ( (f) & FLAG_IS_ALWAYSONTOP ) ) -#define TST_FLAG_IS_VISIBLE(f) ( 0 != ( (f) & FLAG_IS_VISIBLE ) ) +#define TST_FLAG_HAS_PARENT(f) ( 0 != ( (f) & FLAG_HAS_PARENT ) ) +#define TST_FLAG_IS_UNDECORATED(f) ( 0 != ( (f) & FLAG_IS_UNDECORATED ) ) +#define TST_FLAG_IS_FULLSCREEN(f) ( 0 != ( (f) & FLAG_IS_FULLSCREEN ) ) +#define TST_FLAG_IS_FULLSCREEN_SPAN(f) ( 0 != ( (f) & FLAG_IS_FULLSCREEN_SPAN ) ) +#define TST_FLAG_IS_ALWAYSONTOP(f) ( 0 != ( (f) & FLAG_IS_ALWAYSONTOP ) ) +#define TST_FLAG_IS_VISIBLE(f) ( 0 != ( (f) & FLAG_IS_VISIBLE ) ) #endif diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index 5c1115592..7ede3a20d 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -101,6 +101,9 @@ #ifndef DISPLAY_DEVICE_ACTIVE #define DISPLAY_DEVICE_ACTIVE 0x00000001 #endif +#ifndef DM_INTERLACED +#define DM_INTERLACED 2 +#endif #include "jogamp_newt_driver_windows_DisplayDriver.h" #include "jogamp_newt_driver_windows_ScreenDriver.h" @@ -1116,11 +1119,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_DisplayDriver_DispatchMes /* * Class: jogamp_newt_driver_windows_ScreenDriver - * Method: getOriginX0 - * Signature: (I)I + * Method: getVirtualOriginX0 + * Signature: ()I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getOriginX0 - (JNIEnv *env, jobject obj, jint scrn_idx) +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getVirtualOriginX0 + (JNIEnv *env, jobject obj) { if( GetSystemMetrics( SM_CMONITORS) > 1) { return (jint)GetSystemMetrics(SM_XVIRTUALSCREEN); @@ -1131,11 +1134,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getOriginX0 /* * Class: jogamp_newt_driver_windows_ScreenDriver - * Method: getOriginY0 - * Signature: (I)I + * Method: getVirtualOriginY0 + * Signature: ()I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getOriginY0 - (JNIEnv *env, jobject obj, jint scrn_idx) +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getVirtualOriginY0 + (JNIEnv *env, jobject obj) { if( GetSystemMetrics( SM_CMONITORS ) > 1) { return (jint)GetSystemMetrics(SM_YVIRTUALSCREEN); @@ -1146,11 +1149,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getOriginY0 /* * Class: jogamp_newt_driver_windows_ScreenDriver - * Method: getWidthImpl - * Signature: (I)I + * Method: getVirtualWidthImpl + * Signature: ()I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getWidthImpl0 - (JNIEnv *env, jobject obj, jint scrn_idx) +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getVirtualWidthImpl0 + (JNIEnv *env, jobject obj) { if( GetSystemMetrics( SM_CMONITORS) > 1) { return (jint)GetSystemMetrics(SM_CXVIRTUALSCREEN); @@ -1161,11 +1164,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getWidthImpl /* * Class: jogamp_newt_driver_windows_ScreenDriver - * Method: getHeightImpl - * Signature: (I)I + * Method: getVirtualHeightImpl + * Signature: ()I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getHeightImpl0 - (JNIEnv *env, jobject obj, jint scrn_idx) +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getVirtualHeightImpl0 + (JNIEnv *env, jobject obj) { if( GetSystemMetrics( SM_CMONITORS ) > 1) { return (jint)GetSystemMetrics(SM_CYVIRTUALSCREEN); @@ -1217,65 +1220,137 @@ static int NewtScreen_RotationNewtCCW2NativeCCW(JNIEnv *env, jint newt) { return native; } -/* -static void NewtScreen_scanDisplayDevices() { - DISPLAY_DEVICE device; - int i = 0; - LPCTSTR name; - while(NULL != (name = NewtScreen_getDisplayDeviceName(&device, i))) { - DBG_PRINT("*** [%d]: <%s> active %d\n", i, name, ( 0 != ( device.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) ); - i++; +static LPCTSTR NewtScreen_getAdapterName(DISPLAY_DEVICE * device, int crt_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); + return NULL; } -}*/ -static LPCTSTR NewtScreen_getDisplayDeviceName(DISPLAY_DEVICE * device, int scrn_idx) { - device->cb = sizeof(DISPLAY_DEVICE); - if( FALSE == EnumDisplayDevices(NULL, scrn_idx, device, 0) ) { - DBG_PRINT("*** WindowsWindow: getDisplayDeviceName.EnumDisplayDevices(scrn_idx %d) -> FALSE\n", scrn_idx); + if( NULL == device->DeviceName || 0 == _tcslen(device->DeviceName) ) { return NULL; } - if( 0 == ( device->StateFlags & DISPLAY_DEVICE_ACTIVE ) ) { - DBG_PRINT("*** WindowsWindow: !DISPLAY_DEVICE_ACTIVE(scrn_idx %d)\n", scrn_idx); + return device->DeviceName; +} + +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); + 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; } return device->DeviceName; } +JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_dumpMonitorInfo0 + (JNIEnv *env, jclass clazz) +{ + DISPLAY_DEVICE aDevice, dDevice; + 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 ) ) ); + 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 ) ) ); + j++; + } + i++; + } +} + static HDC NewtScreen_createDisplayDC(LPCTSTR displayDeviceName) { return CreateDC("DISPLAY", displayDeviceName, NULL, NULL); } /* * Class: jogamp_newt_driver_windows_ScreenDriver - * Method: getScreenMode0 - * Signature: (II)[I + * Method: getAdapterName0 + * Signature: (I)Ljava/lang/String; */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getScreenMode0 - (JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx) +JNIEXPORT jstring JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getAdapterName0 + (JNIEnv *env, jobject obj, jint crt_idx) { DISPLAY_DEVICE device; - int prop_num = NUM_SCREEN_MODE_PROPERTIES_ALL; - LPCTSTR deviceName = NewtScreen_getDisplayDeviceName(&device, scrn_idx); - if(NULL == deviceName) { - DBG_PRINT("*** WindowsWindow: getScreenMode.getDisplayDeviceName(scrn_idx %d) -> NULL\n", scrn_idx); - return (*env)->NewIntArray(env, 0); + LPCTSTR adapterName = NewtScreen_getAdapterName(&device, crt_idx); + DBG_PRINT("*** WindowsWindow: getAdapterName(crt_idx %d) -> %s, active %d\n", crt_idx, + (NULL==adapterName?"nil":adapterName), 0 == ( device.StateFlags & DISPLAY_DEVICE_ACTIVE )); + if(NULL == adapterName) { + return NULL; } +#ifdef UNICODE + return (*env)->NewString(env, adapterName, wcslen(adapterName)); +#else + return (*env)->NewStringUTF(env, adapterName); +#endif +} + +/* + * Class: jogamp_newt_driver_windows_ScreenDriver + * Method: getActiveMonitorName0 + * Signature: (Ljava/lang/String;I)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getActiveMonitorName0 + (JNIEnv *env, jobject obj, jstring jAdapterName, jint monitor_idx) +{ + DISPLAY_DEVICE device; + LPCTSTR monitorName; +#ifdef UNICODE + LPCTSTR adapterName = NewtCommon_GetNullTerminatedStringChars(env, jAdapterName); + monitorName = NewtScreen_getMonitorName(adapterName, &device, monitor_idx, TRUE); + 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); + DBG_PRINT("*** WindowsWindow: getMonitorName(%s, monitor_idx %d) -> %s\n", adapterName, monitor_idx, (NULL==monitorName?"nil":monitorName)); + (*env)->ReleaseStringUTFChars(env, jAdapterName, adapterName); +#endif + if(NULL == monitorName) { + return NULL; + } +#ifdef UNICODE + return (*env)->NewString(env, monitorName, wcslen(monitorName)); +#else + return (*env)->NewStringUTF(env, monitorName); +#endif +} +/* + * Class: jogamp_newt_driver_windows_ScreenDriver + * Method: getMonitorMode0 + * Signature: (Ljava/lang/String;I)[I + */ +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMonitorMode0 + (JNIEnv *env, jobject obj, jstring jAdapterName, jint mode_idx) +{ + DISPLAY_DEVICE device; + LPCTSTR adapterName; + { +#ifdef UNICODE + adapterName = NewtCommon_GetNullTerminatedStringChars(env, jAdapterName); +#else + adapterName = (*env)->GetStringUTFChars(env, jAdapterName, NULL); +#endif + } int devModeID; - int widthmm, heightmm; if(-1 < mode_idx) { - // only at initialization time, where index >= 0 - HDC hdc = NewtScreen_createDisplayDC(deviceName); - widthmm = GetDeviceCaps(hdc, HORZSIZE); - heightmm = GetDeviceCaps(hdc, VERTSIZE); - DeleteDC(hdc); devModeID = (int) mode_idx; - prop_num++; // add 1st extra prop, mode_idx } else { - widthmm = 0; - heightmm = 0; devModeID = ENUM_CURRENT_SETTINGS; } @@ -1283,11 +1358,18 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getScre ZeroMemory(&dm, sizeof(dm)); dm.dmSize = sizeof(dm); - if (0 == EnumDisplaySettingsEx(deviceName, devModeID, &dm, ( ENUM_CURRENT_SETTINGS == devModeID ) ? 0 : EDS_ROTATEDMODE)) { - DBG_PRINT("*** WindowsWindow: getScreenMode.EnumDisplaySettingsEx(mode_idx %d/%d) -> NULL\n", mode_idx, devModeID); + int res = EnumDisplaySettingsEx(adapterName, devModeID, &dm, ( ENUM_CURRENT_SETTINGS == devModeID ) ? 0 : EDS_ROTATEDMODE); + DBG_PRINT("*** WindowsWindow: getMonitorMode.EnumDisplaySettingsEx(%s, mode_idx %d/%d) -> %d\n", adapterName, mode_idx, devModeID, res); +#ifdef UNICODE + free((void*) adapterName); +#else + (*env)->ReleaseStringUTFChars(env, jAdapterName, adapterName); +#endif + + if (0 == res) { return (*env)->NewIntArray(env, 0); } - + // swap width and height, since Windows reflects rotated dimension, we don't if (DMDO_90 == dm.dmDisplayOrientation || DMDO_270 == dm.dmDisplayOrientation) { int tempWidth = dm.dmPelsWidth; @@ -1295,43 +1377,110 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getScre dm.dmPelsHeight = tempWidth; } - jint prop[ prop_num ]; + int flags = 0; + if( 0 != ( dm.dmDisplayFlags & DM_INTERLACED ) ) { + flags |= FLAG_INTERLACE; + } + + jint prop[ NUM_MONITOR_MODE_PROPERTIES_ALL ]; int propIndex = 0; - if( -1 < mode_idx ) { - prop[propIndex++] = mode_idx; - } - prop[propIndex++] = 0; // set later for verification of iterator + prop[propIndex++] = NUM_MONITOR_MODE_PROPERTIES_ALL; prop[propIndex++] = dm.dmPelsWidth; prop[propIndex++] = dm.dmPelsHeight; prop[propIndex++] = dm.dmBitsPerPel; - prop[propIndex++] = widthmm; - prop[propIndex++] = heightmm; - prop[propIndex++] = dm.dmDisplayFrequency; + prop[propIndex++] = dm.dmDisplayFrequency * 100; // Hz*100 + prop[propIndex++] = flags; + prop[propIndex++] = 0; // not bound to id prop[propIndex++] = NewtScreen_RotationNativeCCW2NewtCCW(env, dm.dmDisplayOrientation); - prop[propIndex - NUM_SCREEN_MODE_PROPERTIES_ALL] = ( -1 < mode_idx ) ? propIndex-1 : propIndex ; // count == NUM_SCREEN_MODE_PROPERTIES_ALL - jintArray properties = (*env)->NewIntArray(env, prop_num); + jintArray properties = (*env)->NewIntArray(env, NUM_MONITOR_MODE_PROPERTIES_ALL); if (properties == NULL) { - NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", prop_num); + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", NUM_MONITOR_MODE_PROPERTIES_ALL); } - (*env)->SetIntArrayRegion(env, properties, 0, prop_num, prop); + (*env)->SetIntArrayRegion(env, properties, 0, NUM_MONITOR_MODE_PROPERTIES_ALL, prop); return properties; } /* * Class: jogamp_newt_driver_windows_ScreenDriver - * Method: setScreenMode0 - * Signature: (IIIIII)Z + * Method: getMonitorDevice0 + * Signature: (Ljava/lang/String;I)[I */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_setScreenMode0 - (JNIEnv *env, jobject object, jint scrn_idx, jint width, jint height, jint bits, jint rate, jint rot) +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMonitorDevice0 + (JNIEnv *env, jobject obj, jstring jAdapterName, jint monitor_idx) { DISPLAY_DEVICE device; - LPCTSTR deviceName = NewtScreen_getDisplayDeviceName(&device, scrn_idx); - if(NULL == deviceName) { - DBG_PRINT("*** WindowsWindow: setScreenMode.getDisplayDeviceName(scrn_idx %d) -> NULL\n", scrn_idx); + LPCTSTR adapterName; + { +#ifdef UNICODE + adapterName = NewtCommon_GetNullTerminatedStringChars(env, jAdapterName); +#else + adapterName = (*env)->GetStringUTFChars(env, jAdapterName, NULL); +#endif + } + + HDC hdc = NewtScreen_createDisplayDC(adapterName); + int widthmm = GetDeviceCaps(hdc, HORZSIZE); + int heightmm = GetDeviceCaps(hdc, VERTSIZE); + DeleteDC(hdc); + int devModeID = ENUM_CURRENT_SETTINGS; + + DEVMODE dm; + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(dm); + + 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); + } + + jsize propCount = MIN_MONITOR_DEVICE_PROPERTIES - 1 - NUM_MONITOR_MODE_PROPERTIES; + jint prop[ propCount ]; + int propIndex = 0; + + prop[propIndex++] = propCount; + prop[propIndex++] = monitor_idx; + prop[propIndex++] = widthmm; + prop[propIndex++] = heightmm; + prop[propIndex++] = dm.dmPosition.x; // rotated viewport + prop[propIndex++] = dm.dmPosition.y; // rotated viewport + prop[propIndex++] = dm.dmPelsWidth; // rotated viewport + prop[propIndex++] = dm.dmPelsHeight; // rotated viewport + + jintArray properties = (*env)->NewIntArray(env, propCount); + if (properties == NULL) { + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", propCount); + } + (*env)->SetIntArrayRegion(env, properties, 0, propCount, prop); + + return properties; +} + +/* + * Class: jogamp_newt_driver_windows_ScreenDriver + * Method: setMonitorMode0 + * 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) +{ + DISPLAY_DEVICE adapterDevice, monitorDevice; + LPCTSTR adapterName = NewtScreen_getAdapterName(&adapterDevice, monitor_idx); + if(NULL == adapterName) { + DBG_PRINT("*** WindowsWindow: setMonitorMode.getAdapterName(monitor_idx %d) -> NULL\n", monitor_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; } @@ -1339,10 +1488,17 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_setScree // initialize the DEVMODE structure ZeroMemory(&dm, sizeof(dm)); dm.dmSize = sizeof(dm); + if( 0 <= x && 0 <= y ) { + dm.dmPosition.x = (int)x; + dm.dmPosition.y = (int)y; + } dm.dmPelsWidth = (int)width; dm.dmPelsHeight = (int)height; dm.dmBitsPerPel = (int)bits; dm.dmDisplayFrequency = (int)rate; + if( 0 != ( flags & FLAG_INTERLACE ) ) { + dm.dmDisplayFlags |= DM_INTERLACED; + } dm.dmDisplayOrientation = NewtScreen_RotationNewtCCW2NativeCCW(env, rot); // swap width and height, since Windows reflects rotated dimension, we don't @@ -1352,9 +1508,12 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_setScree dm.dmPelsHeight = tempWidth; } - dm.dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; + dm.dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS; + if( 0 <= x && 0 <= y ) { + dm.dmFields |= DM_POSITION; + } - return ( DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettings(&dm, 0) ) ? JNI_TRUE : JNI_FALSE ; + return ( DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(adapterName, &dm, NULL, 0, NULL) ) ? JNI_TRUE : JNI_FALSE ; } /* diff --git a/src/newt/native/X11RandR11.c b/src/newt/native/X11RandR11.c index cbf911a38..81a6726b5 100644 --- a/src/newt/native/X11RandR11.c +++ b/src/newt/native/X11RandR11.c @@ -30,10 +30,10 @@ /* * Class: jogamp_newt_driver_x11_RandR11 - * Method: getAvailableScreenModeRotations0 + * Method: getAvailableScreenRotations0 * Signature: (JI)I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getAvailableScreenModeRotations0 +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getAvailableScreenRotations0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -75,10 +75,10 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getAvailableScre /* * Class: jogamp_newt_driver_x11_RandR11 - * Method: getNumScreenModeResolution0 + * Method: getNumScreenResolution0 * Signature: (JI)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR11_getNumScreenModeResolutions0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR11_getNumScreenResolutions0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -90,7 +90,7 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR11_getNumScreenModeResol #ifdef DBG_PERF timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); - fprintf(stderr, "X11Screen_getNumScreenModeResolution0.1: %ld ms\n", td_ms); fflush(NULL); + fprintf(stderr, "X11Screen_getNumScreenResolution0.1: %ld ms\n", td_ms); fflush(NULL); #endif int num_sizes; @@ -98,20 +98,20 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR11_getNumScreenModeResol #ifdef DBG_PERF timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); - fprintf(stderr, "X11Screen_getNumScreenModeResolution0.2 (XRRSizes): %ld ms\n", td_ms); fflush(NULL); + fprintf(stderr, "X11Screen_getNumScreenResolution0.2 (XRRSizes): %ld ms\n", td_ms); fflush(NULL); #endif - DBG_PRINT("getNumScreenModeResolutions0: %p:%d -> %d\n", dpy, (int)scrn_idx, num_sizes); + DBG_PRINT("getNumScreenResolutions0: %p:%d -> %d\n", dpy, (int)scrn_idx, num_sizes); return num_sizes; } /* * Class: jogamp_newt_driver_x11_RandR11 - * Method: getScreenModeResolutions0 + * Method: getScreenResolutions0 * Signature: (JII)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getScreenModeResolution0 +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getScreenResolution0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -145,10 +145,10 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getScreenModeRes /* * Class: jogamp_newt_driver_x11_RandR11 - * Method: getScreenModeRates0 + * Method: getScreenRates0 * Signature: (JII)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getScreenModeRates0 +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getScreenRates0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -289,36 +289,20 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR11_setCurrentScreenM int num_sizes; XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions - int rot; if( 0 > resMode_idx || resMode_idx >= num_sizes ) { NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes); } - switch(rotation) { - case 0: - rot = RR_Rotate_0; - break; - case 90: - rot = RR_Rotate_90; - break; - case 180: - rot = RR_Rotate_180; - break; - case 270: - rot = RR_Rotate_270; - break; - default: - NewtCommon_throwNewRuntimeException(env, "Invalid rotation: %d", rotation); - } - DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n", resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation); + int xrot = NewtScreen_Degree2XRotation(env, rotation); + XRRSelectInput (dpy, root, RRScreenChangeNotifyMask); XSync(dpy, False); - XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime); + XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, xrot, (short)freq, CurrentTime); XSync(dpy, False); return JNI_TRUE; diff --git a/src/newt/native/X11RandR13.c b/src/newt/native/X11RandR13.c index ea72cd35d..92c20e893 100644 --- a/src/newt/native/X11RandR13.c +++ b/src/newt/native/X11RandR13.c @@ -38,22 +38,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_RandR13_getScreenResources0 { Display *dpy = (Display *) (intptr_t) display; Window root = RootWindow(dpy, (int)screen_idx); -#ifdef DBG_PERF - struct timespec t0, t1, td; - long td_ms; - timespec_now(&t0); -#endif - -#ifdef DBG_PERF - timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); - fprintf(stderr, "X11Screen_getScreenResources0.1: %ld ms\n", td_ms); fflush(NULL); -#endif - - XRRScreenResources *res = XRRGetScreenResourcesCurrent( dpy, root); -#ifdef DBG_PERF - timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td); - fprintf(stderr, "X11Screen_getScreenResources0.2 (XRRScreenResources): %ld ms\n", td_ms); fflush(NULL); -#endif + + XRRScreenResources *res = XRRGetScreenResourcesCurrent( dpy, root); // 1.3 + // XRRScreenResources *res = XRRGetScreenResources( dpy, root); // 1.2 return (jlong) (intptr_t) res; } @@ -66,48 +53,166 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_RandR13_getScreenResources0 JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_RandR13_freeScreenResources0 (JNIEnv *env, jclass clazz, jlong screenResources) { - XRRFreeScreenResources( (XRRScreenResources *) (intptr_t) screenResources ); + XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources; + if( NULL != resources ) { + XRRFreeScreenResources( resources ); + } +} + +#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); + for(i=0; i<noutput; i++) { + RROutput output = outputs[i]; + XRROutputInfo * xrrOutputInfo = XRRGetOutputInfo (dpy, resources, output); + fprintf(stderr, " Output[%d]: id %#lx, crtx 0x%X, name %s (%d), %lux%lu, ncrtc %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->nmode, xrrOutputInfo->npreferred); + for(j=0; j<xrrOutputInfo->nmode; j++) { + fprintf(stderr, " Output[%d].Mode[%d].id %#lx\n", i, j, xrrOutputInfo->modes[j]); + } + XRRFreeOutputInfo (xrrOutputInfo); + } } -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getOrigin0 - (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) +/** Returns vertical refresh rate in hertz */ +static float getVRefresh(XRRModeInfo *mode) { + float rate; + unsigned int vTotal = mode->vTotal; + + if (mode->modeFlags & RR_DoubleScan) { + /* doublescan doubles the number of lines */ + vTotal *= 2; + } + + if (mode->modeFlags & RR_Interlace) { + /* interlace splits the frame into two fields */ + /* the field rate is what is typically reported by monitors */ + vTotal /= 2; + } + + if (mode->hTotal && vTotal) { + rate = ( (float) mode->dotClock / + ( (float) mode->hTotal * (float) vTotal ) + ); + } else { + rate = 0; + } + return rate; +} + + +JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_RandR13_dumpInfo0 + (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenResources) { Display * dpy = (Display *) (intptr_t) display; - Window root = RootWindow(dpy, (int)scrn_idx); + Window root = RootWindow(dpy, (int)screen_idx); + XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources; int pos[] = { 0, 0 } ; + int i, j, minWidth, minHeight, maxWidth, maxHeight; - int i; - XRRScreenResources *xrrScreenResources = XRRGetScreenResources(dpy, root); - fprintf(stderr, "XRRScreenResources %p: RRCrtc crtcs %d\n", xrrScreenResources, xrrScreenResources->ncrtc); - for(i=0; i<xrrScreenResources->ncrtc; i++) { - RRCrtc crtc = xrrScreenResources->crtcs[i]; - XRRCrtcInfo *xrrCrtcInfo = XRRGetCrtcInfo (dpy, xrrScreenResources, crtc); - fprintf(stderr, "RRCrtc %d: %d/%d %dx%d\n", i, xrrCrtcInfo->x, xrrCrtcInfo->y, xrrCrtcInfo->width, xrrCrtcInfo->height); + int vs_width = DisplayWidth(dpy, screen_idx); + int vs_height = DisplayHeight(dpy, screen_idx); + int vs_width_mm = DisplayWidthMM(dpy, screen_idx); + int vs_height_mm = DisplayHeightMM(dpy, screen_idx); + fprintf(stderr, "ScreenVirtualSize: %dx%d %dx%d mm\n", vs_width, vs_height, vs_width_mm, vs_height_mm); + + XRRGetScreenSizeRange (dpy, root, &minWidth, &minHeight, &maxWidth, &maxHeight); + fprintf(stderr, "XRRGetScreenSizeRange: %dx%d .. %dx%d\n", minWidth, minHeight, maxWidth, maxHeight); + + if( NULL == resources ) { + fprintf(stderr, "XRRScreenResources NULL\n"); + return; + } + fprintf(stderr, "XRRScreenResources %p: Crtc count %d\n", resources, resources->ncrtc); + for(i=0; i<resources->ncrtc; i++) { + RRCrtc crtc = resources->crtcs[i]; + XRRCrtcInfo *xrrCrtcInfo = XRRGetCrtcInfo (dpy, resources, crtc); + fprintf(stderr, "Crtc[%d]: %d/%d %dx%d, rot 0x%X, mode.id %#lx\n", + i, xrrCrtcInfo->x, xrrCrtcInfo->y, xrrCrtcInfo->width, xrrCrtcInfo->height, xrrCrtcInfo->rotations, xrrCrtcInfo->mode); + for(j=0; j<xrrCrtcInfo->noutput; j++) { + fprintf(stderr, " Crtc[%d].Output[%d].id %#lx\n", i, j, xrrCrtcInfo->outputs[j]); + } XRRFreeCrtcInfo(xrrCrtcInfo); } - jintArray jpos = (*env)->NewIntArray(env, num_rotations); - if (properties == NULL) { - NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", 2); + dumpOutputs("XRRScreenResources.outputs", dpy, resources, resources->noutput, resources->outputs); + + fprintf(stderr, "XRRScreenResources %p: Mode count %d\n", resources, resources->nmode); + for(i=0; i<resources->nmode; i++) { + XRRModeInfo *mode = &resources->modes[i]; + + unsigned int dots = mode->hTotal * mode->vTotal; + float refresh = getVRefresh(mode); + fprintf(stderr, "Mode[%d, id %#lx]: %ux%u@%f, name %s\n", i, mode->id, mode->width, mode->height, refresh, SAFE_STRING(mode->name)); } - - // move from the temp structure to the java structure - (*env)->SetIntArrayRegion(env, jpos, 0, 2, pos); - return jpos; } -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getAvailableScreenModeRotations0 - (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) +/* + * Class: jogamp_newt_driver_x11_RandR13 + * Method: getMonitorDeviceCount0 + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorDeviceCount0 + (JNIEnv *env, jclass clazz, jlong screenResources) +{ + XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources; + return ( NULL != resources ) ? resources->ncrtc : 0; +} + +/* + * Class: jogamp_newt_driver_x11_RandR13 + * Method: getMonitorInfoHandle0 + * Signature: (JIJI)J + */ +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorInfoHandle0 + (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenResources, jint crt_idx) { Display *dpy = (Display *) (intptr_t) display; - Window root = RootWindow(dpy, (int)scrn_idx); - int num_rotations = 0; - Rotation cur_rotation, rotations_supported; - int rotations[4]; - int major, minor; + Window root = RootWindow(dpy, (int)screen_idx); + XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources; - rotations_supported = XRRRotations (dpy, (int)scrn_idx, &cur_rotation); + if( NULL == resources || crt_idx >= resources->ncrtc ) { + return 0; + } + RRCrtc crtc = resources->crtcs[crt_idx]; + XRRCrtcInfo *xrrCrtcInfo = XRRGetCrtcInfo (dpy, resources, crtc); + return (jlong) (intptr_t) xrrCrtcInfo; +} + +/* + * Class: jogamp_newt_driver_x11_RandR13 + * Method: freeMonitorInfoHandle0 + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_RandR13_freeMonitorInfoHandle0 + (JNIEnv *env, jclass clazz, jlong monitorInfo) +{ + XRRCrtcInfo *xrrCrtcInfo = (XRRCrtcInfo *) (intptr_t) monitorInfo; + if( NULL != xrrCrtcInfo ) { + XRRFreeCrtcInfo( xrrCrtcInfo ); + } +} + +/* + * Class: jogamp_newt_driver_x11_RandR13 + * Method: getAvailableRotations0 + * Signature: (J)I + */ +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getAvailableRotations0 + (JNIEnv *env, jclass clazz, jlong monitorInfo) +{ + XRRCrtcInfo *xrrCrtcInfo = (XRRCrtcInfo *) (intptr_t) monitorInfo; + if( NULL == xrrCrtcInfo ) { + return NULL; + } + Rotation rotations_supported = xrrCrtcInfo->rotations; + + int num_rotations = 0; + int rotations[4]; if(0 != (rotations_supported & RR_Rotate_0)) { rotations[num_rotations++] = 0; } @@ -120,7 +225,7 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getAvailableScre if(0 != (rotations_supported & RR_Rotate_270)) { rotations[num_rotations++] = 270; } - + jintArray properties = NULL; if(num_rotations>0) { @@ -136,273 +241,275 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getAvailableScre return properties; } -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR13_getNumScreenModeResolutions0 - (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) +/* + * Class: jogamp_newt_driver_x11_RandR13 + * Method: getMonitorViewport0 + * Signature: (J)[I + */ +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorViewport0 + (JNIEnv *env, jclass clazz, jlong monitorInfo) { - Display *dpy = (Display *) (intptr_t) display; - Window root = RootWindow(dpy, (int)scrn_idx); - - int num_sizes; - XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions - - DBG_PRINT("getNumScreenModeResolutions0: %d\n", num_sizes); + XRRCrtcInfo *xrrCrtcInfo = (XRRCrtcInfo *) (intptr_t) monitorInfo; - int i; - XRRScreenResources *xrrScreenResources = XRRGetScreenResources(dpy, root); - fprintf(stderr, "XRRScreenResources %p: RRCrtc crtcs %d\n", xrrScreenResources, xrrScreenResources->ncrtc); - for(i=0; i<xrrScreenResources->ncrtc; i++) { - RRCrtc crtc = xrrScreenResources->crtcs[i]; - XRRCrtcInfo *xrrCrtcInfo = XRRGetCrtcInfo (dpy, xrrScreenResources, crtc); - fprintf(stderr, "RRCrtc %d: %d/%d %dx%d\n", i, xrrCrtcInfo->x, xrrCrtcInfo->y, xrrCrtcInfo->width, xrrCrtcInfo->height); - XRRFreeCrtcInfo(xrrCrtcInfo); + if( NULL == xrrCrtcInfo ) { + // n/a + return NULL; } - fprintf(stderr, "XRRScreenResources %p: XRRModeInfo modes %d\n", xrrScreenResources, xrrScreenResources->nmode); - for(i=0; i<xrrScreenResources->nmode; i++) { - XRRModeInfo xrrModeInfo = xrrScreenResources->modes[i]; - fprintf(stderr, "XRRModeInfo %d: %dx%d, %s, %X\n", i, xrrModeInfo.width, xrrModeInfo.height, xrrModeInfo.name, xrrModeInfo.id); + + if( None == xrrCrtcInfo->mode || 0 == xrrCrtcInfo->noutput ) { + // disabled + return NULL; } - XRRFreeScreenResources(xrrScreenResources); - return num_sizes; + jsize propCount = 4; + jint prop[ propCount ]; + int propIndex = 0; + + prop[propIndex++] = xrrCrtcInfo->x; + prop[propIndex++] = xrrCrtcInfo->y; + prop[propIndex++] = xrrCrtcInfo->width; + prop[propIndex++] = xrrCrtcInfo->height; + + jintArray properties = (*env)->NewIntArray(env, propCount); + if (properties == NULL) { + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", propCount); + } + (*env)->SetIntArrayRegion(env, properties, 0, propCount, prop); + + return properties; } /* * Class: jogamp_newt_driver_x11_RandR13 - * Method: getScreenModeResolutions0 - * Signature: (JII)[I + * Method: getMonitorMode0 + * Signature: (JI)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getScreenModeResolution0 - (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx) +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorMode0 + (JNIEnv *env, jclass clazz, jlong screenResources, jint mode_idx) { - Display *dpy = (Display *) (intptr_t) display; - - int num_sizes; - XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions + XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources; + + if( NULL == resources || mode_idx >= resources->nmode ) { + return NULL; + } - if( 0 > resMode_idx || resMode_idx >= num_sizes ) { - NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes); + XRRModeInfo *mode = &resources->modes[mode_idx]; + unsigned int dots = mode->hTotal * mode->vTotal; + int refresh = (int) ( getVRefresh(mode) * 100.0f ); // Hz * 100 + int flags = 0; + if (mode->modeFlags & RR_Interlace) { + flags |= FLAG_INTERLACE; } - - // Fill the properties in temp jint array + if (mode->modeFlags & RR_DoubleScan) { + flags |= FLAG_DOUBLESCAN; + } + + jint prop[ NUM_MONITOR_MODE_PROPERTIES_ALL ]; int propIndex = 0; - jint prop[4]; - - prop[propIndex++] = xrrs[(int)resMode_idx].width; - prop[propIndex++] = xrrs[(int)resMode_idx].height; - prop[propIndex++] = xrrs[(int)resMode_idx].mwidth; - prop[propIndex++] = xrrs[(int)resMode_idx].mheight; - - jintArray properties = (*env)->NewIntArray(env, 4); + + prop[propIndex++] = NUM_MONITOR_MODE_PROPERTIES_ALL; + prop[propIndex++] = mode->width; + prop[propIndex++] = mode->height; + prop[propIndex++] = 32; // TODO: XRandR > 1.4 may support bpp + prop[propIndex++] = refresh; + prop[propIndex++] = flags; + prop[propIndex++] = mode->id; + prop[propIndex++] = -1; // rotation placeholder + + jintArray properties = (*env)->NewIntArray(env, NUM_MONITOR_MODE_PROPERTIES_ALL); if (properties == NULL) { - NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", 4); + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", NUM_MONITOR_MODE_PROPERTIES_ALL); } - - // move from the temp structure to the java structure - (*env)->SetIntArrayRegion(env, properties, 0, 4, prop); + (*env)->SetIntArrayRegion(env, properties, 0, NUM_MONITOR_MODE_PROPERTIES_ALL, prop); return properties; } /* * Class: jogamp_newt_driver_x11_RandR13 - * Method: getScreenModeRates0 - * Signature: (JII)[I + * Method: getMonitorCurrentMode0 + * Signature: (JJ)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getScreenModeRates0 - (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx) +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorCurrentMode0 + (JNIEnv *env, jclass clazz, jlong screenResources, jlong monitorInfo) { - Display *dpy = (Display *) (intptr_t) display; - - int num_sizes; - XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions + XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources; + XRRCrtcInfo *xrrCrtcInfo = (XRRCrtcInfo *) (intptr_t) monitorInfo; - if( 0 > resMode_idx || resMode_idx >= num_sizes ) { - NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes); + if( NULL == resources || NULL == xrrCrtcInfo ) { + // n/a + return NULL; } - - int num_rates; - short *rates = XRRRates(dpy, (int)scrn_idx, (int)resMode_idx, &num_rates); - - jint prop[num_rates]; + + if( None == xrrCrtcInfo->mode || 0 == xrrCrtcInfo->noutput ) { + // disabled + return NULL; + } + + int modeId = xrrCrtcInfo->mode; + XRRModeInfo *mode = NULL; int i; - for(i=0; i<num_rates; i++) { - prop[i] = (int) rates[i]; - /** fprintf(stderr, "rate[%d, %d, %d/%d]: %d\n", (int)scrn_idx, resMode_idx, i, num_rates, prop[i]); */ + for(i=0; i<resources->nmode; i++) { + XRRModeInfo *imode = &resources->modes[i]; + if( imode->id == modeId ) { + mode = imode; + break; + } } - - jintArray properties = (*env)->NewIntArray(env, num_rates); + if( NULL == mode ) { + // oops .. + return NULL; + } + + unsigned int dots = mode->hTotal * mode->vTotal; + int refresh = (int) ( getVRefresh(mode) * 100.0f ); // Hz * 100 + int flags = 0; + if (mode->modeFlags & RR_Interlace) { + flags |= FLAG_INTERLACE; + } + if (mode->modeFlags & RR_DoubleScan) { + flags |= FLAG_DOUBLESCAN; + } + + jint prop[ NUM_MONITOR_MODE_PROPERTIES_ALL ]; + int propIndex = 0; + + prop[propIndex++] = NUM_MONITOR_MODE_PROPERTIES_ALL; + prop[propIndex++] = mode->width; + prop[propIndex++] = mode->height; + prop[propIndex++] = 32; // TODO: XRandR > 1.4 may support bpp + prop[propIndex++] = refresh; + prop[propIndex++] = flags; + prop[propIndex++] = mode->id; + prop[propIndex++] = NewtScreen_XRotation2Degree(env, xrrCrtcInfo->rotation); + + jintArray properties = (*env)->NewIntArray(env, NUM_MONITOR_MODE_PROPERTIES_ALL); if (properties == NULL) { - NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rates); + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", NUM_MONITOR_MODE_PROPERTIES_ALL); } - - // move from the temp structure to the java structure - (*env)->SetIntArrayRegion(env, properties, 0, num_rates, prop); + (*env)->SetIntArrayRegion(env, properties, 0, NUM_MONITOR_MODE_PROPERTIES_ALL, prop); return properties; } /* * Class: jogamp_newt_driver_x11_RandR13 - * Method: getCurrentScreenRate0 - * Signature: (JI)I + * Method: getMonitorDevice0 + * Signature: (JJJJ)[I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR13_getCurrentScreenRate0 - (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorDevice0 + (JNIEnv *env, jclass clazz, jlong display, jlong screenResources, jlong monitorInfo, jint crt_idx) { - Display *dpy = (Display *) (intptr_t) display; - Window root = RootWindow(dpy, (int)scrn_idx); - - // get current resolutions and frequencies - XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root); - short original_rate = XRRConfigCurrentRate(conf); + Display * dpy = (Display *) (intptr_t) display; + XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources; + XRRCrtcInfo *xrrCrtcInfo = (XRRCrtcInfo *) (intptr_t) monitorInfo; - //free - XRRFreeScreenConfigInfo(conf); - - DBG_PRINT("getCurrentScreenRate0: %d\n", (int)original_rate); + if( NULL == resources || NULL == xrrCrtcInfo || crt_idx >= resources->ncrtc ) { + // n/a + return NULL; + } - return (jint) original_rate; -} + if( None == xrrCrtcInfo->mode || 0 == xrrCrtcInfo->noutput ) { + // disabled + return NULL; + } -/* - * Class: jogamp_newt_driver_x11_RandR13 - * Method: getCurrentScreenRotation0 - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR13_getCurrentScreenRotation0 - (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) -{ - Display *dpy = (Display *) (intptr_t) display; - Window root = RootWindow(dpy, (int)scrn_idx); - - //get current resolutions and frequencies - XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root); - - Rotation rotation; - XRRConfigCurrentConfiguration(conf, &rotation); + RROutput output = xrrCrtcInfo->outputs[0]; + XRROutputInfo * xrrOutputInfo = XRRGetOutputInfo (dpy, resources, output); + int numModes = xrrOutputInfo->nmode; - //free - XRRFreeScreenConfigInfo(conf); - - return NewtScreen_XRotation2Degree(env, rotation); -} + jsize propCount = MIN_MONITOR_DEVICE_PROPERTIES - 1 + numModes; + jint prop[ propCount ]; + int propIndex = 0; + prop[propIndex++] = propCount; + prop[propIndex++] = crt_idx; + prop[propIndex++] = xrrOutputInfo->mm_width; + prop[propIndex++] = xrrOutputInfo->mm_height; + prop[propIndex++] = xrrCrtcInfo->x; + prop[propIndex++] = xrrCrtcInfo->y; + prop[propIndex++] = xrrCrtcInfo->width; + prop[propIndex++] = xrrCrtcInfo->height; + prop[propIndex++] = xrrCrtcInfo->mode; // current mode id + prop[propIndex++] = NewtScreen_XRotation2Degree(env, xrrCrtcInfo->rotation); + int i; + for(i=0; i<numModes; i++) { + // avail modes .. + prop[propIndex++] = xrrOutputInfo->modes[i]; + } -/* - * Class: jogamp_newt_driver_x11_RandR13 - * Method: getCurrentScreenResolutionIndex0 - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR13_getCurrentScreenResolutionIndex0 - (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) -{ - Display *dpy = (Display *) (intptr_t) display; - Window root = RootWindow(dpy, (int)scrn_idx); - - // get current resolutions and frequency configuration - XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root); - short original_rate = XRRConfigCurrentRate(conf); - - Rotation original_rotation; - SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation); - - //free - XRRFreeScreenConfigInfo(conf); - - DBG_PRINT("getCurrentScreenResolutionIndex0: %d\n", (int)original_size_id); - return (jint)original_size_id; + XRRFreeOutputInfo (xrrOutputInfo); + + jintArray properties = (*env)->NewIntArray(env, propCount); + if (properties == NULL) { + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", propCount); + } + (*env)->SetIntArrayRegion(env, properties, 0, propCount, prop); + + return properties; } /* * Class: jogamp_newt_driver_x11_RandR13 - * Method: setCurrentScreenModeStart0 - * Signature: (JIIII)Z + * Method: setMonitorMode0 + * Signature: (JJJIIIII)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR13_setCurrentScreenModeStart0 - (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation) +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR13_setMonitorMode0 + (JNIEnv *env, jclass clazz, jlong display, jlong screenResources, jlong monitorInfo, jint crt_idx, jint modeId, jint rotation, jint x, jint y) { - Display *dpy = (Display *) (intptr_t) display; - Window root = RootWindow(dpy, (int)screen_idx); + Display * dpy = (Display *) (intptr_t) display; + XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources; + XRRCrtcInfo *xrrCrtcInfo = (XRRCrtcInfo *) (intptr_t) monitorInfo; + jboolean res = JNI_FALSE; - int num_sizes; - XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions - XRRScreenConfiguration *conf; - int rot; - - if( 0 > resMode_idx || resMode_idx >= num_sizes ) { - NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes); + if( NULL == resources || NULL == xrrCrtcInfo || crt_idx >= resources->ncrtc ) { + // n/a + return res; } - conf = XRRGetScreenInfo(dpy, root); - - rot = int NewtScreen_Degree2XRotation(env, rotation); - - DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n", - resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation); + if( None == xrrCrtcInfo->mode || 0 == xrrCrtcInfo->noutput ) { + // disabled + return res; + } - XRRSelectInput (dpy, root, RRScreenChangeNotifyMask); + if( 0 >= modeId ) { + // oops .. + return res; + } - XSync(dpy, False); - XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime); - XSync(dpy, False); + if( 0 > x || 0 > y ) { + x = xrrCrtcInfo->x; + y = xrrCrtcInfo->y; + } - //free - XRRFreeScreenConfigInfo(conf); - XSync(dpy, False); + Status status = XRRSetCrtcConfig( dpy, resources, resources->crtcs[crt_idx], CurrentTime, + x, y, modeId, NewtScreen_Degree2XRotation(env, rotation), + xrrCrtcInfo->outputs, xrrCrtcInfo->noutput ); + res = status == RRSetConfigSuccess; - return JNI_TRUE; + return res; } /* * Class: jogamp_newt_driver_x11_RandR13 - * Method: setCurrentScreenModePollEnd0 - * Signature: (J)Z + * Method: setScreenViewport0 + * Signature: (JIJIIII)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR13_setCurrentScreenModePollEnd0 - (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation) +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR13_setScreenViewport0 + (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenResources, jint x, jint y, jint width, jint height) { - Display *dpy = (Display *) (intptr_t) display; - int randr_event_base, randr_error_base; - XEvent evt; - XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt; + Display * dpy = (Display *) (intptr_t) display; + Window root = RootWindow(dpy, (int)screen_idx); + XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources; + jboolean res = JNI_FALSE; - int num_sizes; - XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions - XRRScreenConfiguration *conf; - - if( 0 > resMode_idx || resMode_idx >= num_sizes ) { - NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes); + if( NULL == resources ) { + // n/a + return JNI_FALSE; } - XRRQueryExtension(dpy, &randr_event_base, &randr_error_base); - - int done = 0; - int rot; - do { - if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) ) { - return; - } - XNextEvent(dpy, &evt); - - switch (evt.type - randr_event_base) { - case RRScreenChangeNotify: - rot = NewtScreen_XRotation2Degree(env, (int)scn_event->rotation); - DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call %p (root %p) resIdx %d rot %d %dx%d\n", - (void*)scn_event->window, (void*)scn_event->root, - (int)scn_event->size_index, rot, - scn_event->width, scn_event->height); - // done = scn_event->size_index == resMode_idx; // not reliable .. - done = rot == rotation && - scn_event->width == xrrs[resMode_idx].width && - scn_event->height == xrrs[resMode_idx].height; - break; - default: - DBG_PRINT("RANDR: event . unhandled %d 0x%X call %p\n", (int)evt.type, (int)evt.type, (void*)evt.xany.window); - } - XRRUpdateConfiguration(&evt); - } while(!done); - - XSync(dpy, False); - + XRRSetScreenSize (dpy, root, width, height, DisplayWidthMM(dpy, screen_idx), DisplayHeightMM(dpy, screen_idx)); + return JNI_TRUE; } + diff --git a/src/newt/native/X11Screen.c b/src/newt/native/X11Screen.c index 3d4b2a26c..152a092c9 100644 --- a/src/newt/native/X11Screen.c +++ b/src/newt/native/X11Screen.c @@ -75,22 +75,41 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getHeight0 } int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) { - int rot; + int degree; if(xrotation == RR_Rotate_0) { - rot = 0; + degree = 0; } else if(xrotation == RR_Rotate_90) { - rot = 90; + degree = 90; } else if(xrotation == RR_Rotate_180) { - rot = 180; + degree = 180; } else if(xrotation == RR_Rotate_270) { - rot = 270; + degree = 270; } else { NewtCommon_throwNewRuntimeException(env, "invalid native rotation: %d", xrotation); } - return rot; + return degree; +} + +int NewtScreen_Degree2XRotation(JNIEnv *env, int degree) { + int xrot; + if(degree == 0) { + xrot = RR_Rotate_0; + } + else if(degree == 90) { + xrot = RR_Rotate_90; + } + else if(degree == 180) { + xrot = RR_Rotate_180; + } + else if(degree == 270) { + xrot = RR_Rotate_270; + } else { + NewtCommon_throwNewRuntimeException(env, "invalid degree: %d", degree); + } + return xrot; } /* diff --git a/src/newt/native/X11Screen.h b/src/newt/native/X11Screen.h index 1a1440054..c81ee05d5 100644 --- a/src/newt/native/X11Screen.h +++ b/src/newt/native/X11Screen.h @@ -33,5 +33,6 @@ #include "X11Common.h" int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation); +int NewtScreen_Degree2XRotation(JNIEnv *env, int degree); #endif /* _X11SCREEN_H */ diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 9e96169f5..6c5a127b6 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -438,7 +438,7 @@ Status NewtWindows_updateInsets(JNIEnv *env, jobject jwindow, Display *dpy, Wind return 0; // Error } -static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy, Window w, jboolean force) { +static void NewtWindows_requestFocus (Display *dpy, Window w, Bool force) { XWindowAttributes xwa; Window focus_return; int revert_to_return; @@ -447,7 +447,7 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy, XGetInputFocus(dpy, &focus_return, &revert_to_return); DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d, hasFocus %d\n", dpy, (void*)w, force, focus_return==w); - if( JNI_TRUE==force || focus_return!=w) { + if( True==force || focus_return!=w) { DBG_PRINT( "X11: XRaiseWindow dpy %p, win %p\n", dpy, (void*)w); XRaiseWindow(dpy, w); NewtWindows_setCWAbove(dpy, w); @@ -743,7 +743,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo Bool tempInvisible = ( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_PARENTING(flags) ) && isVisible ; int fsEWMHFlags = 0; if( TST_FLAG_CHANGE_FULLSCREEN(flags) ) { - fsEWMHFlags |= _NET_WM_FULLSCREEN; + if( !TST_FLAG_IS_FULLSCREEN_SPAN(flags) ) { // doesn't work w/ spanning across monitors + fsEWMHFlags |= _NET_WM_FULLSCREEN; + } if( TST_FLAG_IS_FULLSCREEN(flags) ) { if( TST_FLAG_IS_ALWAYSONTOP(flags) ) { fsEWMHFlags |= _NET_WM_ABOVE; // fs on, above on @@ -756,12 +758,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo fsEWMHFlags |= _NET_WM_ABOVE; // toggle above } - DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d, parent %p/%p, win %p, %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d, tempInvisible %d, fsEWMHFlags %d\n", + DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d, parent %p/%p, win %p, %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d (span %d), alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d, tempInvisible %d, fsEWMHFlags %d\n", (void*)dpy, screen_index, (void*) jparent, (void*)parent, (void*)w, x, y, width, height, TST_FLAG_CHANGE_PARENTING(flags), TST_FLAG_HAS_PARENT(flags), TST_FLAG_CHANGE_DECORATION(flags), TST_FLAG_IS_UNDECORATED(flags), - TST_FLAG_CHANGE_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN(flags), + TST_FLAG_CHANGE_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN_SPAN(flags), TST_FLAG_CHANGE_ALWAYSONTOP(flags), TST_FLAG_IS_ALWAYSONTOP(flags), TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags), tempInvisible, fsEWMHFlags); @@ -769,9 +771,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo // However, we have to consider other cases like reparenting and WM which don't support it. if( fsEWMHFlags && !TST_FLAG_CHANGE_PARENTING(flags) && isVisible && + !TST_FLAG_IS_FULLSCREEN_SPAN(flags) && ( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) ) { Bool enable = TST_FLAG_CHANGE_FULLSCREEN(flags) ? TST_FLAG_IS_FULLSCREEN(flags) : TST_FLAG_IS_ALWAYSONTOP(flags) ; if( NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, enable) ) { + if ( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) { // FS off - restore decoration + NewtWindows_setDecorations (dpy, w, TST_FLAG_IS_UNDECORATED(flags) ? False : True); + } #ifdef FS_GRAB_KEYBOARD if(TST_FLAG_CHANGE_FULLSCREEN(flags)) { if(TST_FLAG_IS_FULLSCREEN(flags)) { @@ -866,7 +872,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_requestFocus0 (JNIEnv *env, jobject obj, jlong display, jlong window, jboolean force) { - NewtWindows_requestFocus ( env, obj, (Display *) (intptr_t) display, (Window)window, force ) ; + NewtWindows_requestFocus ( (Display *) (intptr_t) display, (Window)window, JNI_TRUE==force?True:False ) ; } /* |