From fd06292d4a208cbd613f4bdce7cae12e075e70ec Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Thu, 5 Jul 2012 14:32:00 +0200 Subject: NativeWindow/Newt X11ErrorHandler enhancement / unification - don't throw exceptions. Handles also XAWT BadMatch X_SetInputFocus. X11ErrorHandler code now dumps proper information about the opcode and error message and the running Java thread. Having propery "nativewindow.debug.X11Util.XErrorStackDump" or "nativewindow.debug=all' set, a stack trace is dumped. Since the X11ErrorHandler may catch an XAWT error: BadMatch X_SetInputFocus, we cannot throw an exception and better keep running. --- src/newt/native/X11Window.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/newt/native/X11Window.c') diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 0f93b3e76..daf9f2b53 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -683,12 +683,16 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0 DBG_PRINT( "X11: CloseWindow START dpy %p, win %p\n", (void*)dpy, (void*)w); + NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0); + jwindow = getJavaWindowProperty(env, dpy, w, javaObjectAtom, True); if(NULL==jwindow) { + NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); NewtCommon_throwNewRuntimeException(env, "could not fetch Java Window object, bail out!"); return; } if ( JNI_FALSE == (*env)->IsSameObject(env, jwindow, obj) ) { + NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); NewtCommon_throwNewRuntimeException(env, "Internal Error .. Window global ref not the same!"); return; } @@ -696,7 +700,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0 XSync(dpy, False); XSelectInput(dpy, w, 0); XUnmapWindow(dpy, w); - XSync(dpy, False); + NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); // Drain all events related to this window .. Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom); @@ -757,7 +761,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0 fsEWMHFlags |= _NET_WM_ABOVE; // toggle above } - NewtDisplay_displayDispatchErrorHandlerEnable(1, env); + NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0); 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", (void*)dpy, screen_index, (void*) jparent, (void*)parent, (void*)w, @@ -775,7 +779,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0 ( 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) ) { - NewtDisplay_displayDispatchErrorHandlerEnable(0, env); + NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); #ifdef FS_GRAB_KEYBOARD if(TST_FLAG_CHANGE_FULLSCREEN(flags)) { if(TST_FLAG_IS_FULLSCREEN(flags)) { @@ -859,7 +863,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0 #endif } - NewtDisplay_displayDispatchErrorHandlerEnable(0, env); + NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); DBG_PRINT( "X11: reconfigureWindow0 X\n"); } -- cgit v1.2.3 From a694cadca4ab72481e777222f412f006f973f77e Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 18 Aug 2012 14:12:54 +0200 Subject: NEWT Platform Driver: Uniform impl. class names [DisplayDriver, ScreenDriver, WindowDriver] to reduce complexity and programatic selection. --- make/build-newt.xml | 36 +- make/scripts/tests.sh | 4 +- .../media/nativewindow/NativeWindowFactory.java | 12 +- .../classes/com/jogamp/newt/util/MainThread.java | 2 +- src/newt/classes/jogamp/newt/DisplayImpl.java | 22 +- src/newt/classes/jogamp/newt/ScreenImpl.java | 28 +- src/newt/classes/jogamp/newt/WindowImpl.java | 21 +- .../jogamp/newt/driver/android/AndroidDisplay.java | 66 --- .../jogamp/newt/driver/android/AndroidScreen.java | 138 ------- .../jogamp/newt/driver/android/AndroidWindow.java | 458 --------------------- .../jogamp/newt/driver/android/DisplayDriver.java | 66 +++ .../newt/driver/android/NewtBaseActivity.java | 10 +- .../newt/driver/android/NewtVersionActivity.java | 2 +- .../jogamp/newt/driver/android/ScreenDriver.java | 138 +++++++ .../jogamp/newt/driver/android/WindowDriver.java | 458 +++++++++++++++++++++ .../classes/jogamp/newt/driver/awt/AWTCanvas.java | 1 + .../classes/jogamp/newt/driver/awt/AWTDisplay.java | 73 ---- .../classes/jogamp/newt/driver/awt/AWTScreen.java | 81 ---- .../classes/jogamp/newt/driver/awt/AWTWindow.java | 233 ----------- .../jogamp/newt/driver/awt/DisplayDriver.java | 73 ++++ .../jogamp/newt/driver/awt/ScreenDriver.java | 81 ++++ .../jogamp/newt/driver/awt/WindowDriver.java | 233 +++++++++++ .../jogamp/newt/driver/bcm/egl/Display.java | 85 ---- .../jogamp/newt/driver/bcm/egl/DisplayDriver.java | 85 ++++ .../classes/jogamp/newt/driver/bcm/egl/Screen.java | 75 ---- .../jogamp/newt/driver/bcm/egl/ScreenDriver.java | 75 ++++ .../classes/jogamp/newt/driver/bcm/egl/Window.java | 170 -------- .../jogamp/newt/driver/bcm/egl/WindowDriver.java | 170 ++++++++ .../jogamp/newt/driver/bcm/vc/iv/Display.java | 78 ---- .../newt/driver/bcm/vc/iv/DisplayDriver.java | 78 ++++ .../jogamp/newt/driver/bcm/vc/iv/Screen.java | 73 ---- .../jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java | 73 ++++ .../jogamp/newt/driver/bcm/vc/iv/Window.java | 149 ------- .../jogamp/newt/driver/bcm/vc/iv/WindowDriver.java | 149 +++++++ .../jogamp/newt/driver/intel/gdl/Display.java | 104 ----- .../newt/driver/intel/gdl/DisplayDriver.java | 105 +++++ .../jogamp/newt/driver/intel/gdl/Screen.java | 85 ---- .../jogamp/newt/driver/intel/gdl/ScreenDriver.java | 86 ++++ .../jogamp/newt/driver/intel/gdl/Window.java | 146 ------- .../jogamp/newt/driver/intel/gdl/WindowDriver.java | 147 +++++++ .../classes/jogamp/newt/driver/kd/Display.java | 77 ---- .../jogamp/newt/driver/kd/DisplayDriver.java | 77 ++++ src/newt/classes/jogamp/newt/driver/kd/Screen.java | 75 ---- .../jogamp/newt/driver/kd/ScreenDriver.java | 75 ++++ src/newt/classes/jogamp/newt/driver/kd/Window.java | 163 -------- .../jogamp/newt/driver/kd/WindowDriver.java | 163 ++++++++ .../jogamp/newt/driver/macosx/DisplayDriver.java | 88 ++++ .../jogamp/newt/driver/macosx/MacDisplay.java | 87 ---- .../jogamp/newt/driver/macosx/MacKeyUtil.java | 27 ++ .../jogamp/newt/driver/macosx/MacScreen.java | 143 ------- .../jogamp/newt/driver/macosx/MacWindow.java | 431 ------------------- .../jogamp/newt/driver/macosx/ScreenDriver.java | 143 +++++++ .../jogamp/newt/driver/macosx/WindowDriver.java | 431 +++++++++++++++++++ .../jogamp/newt/driver/windows/DisplayDriver.java | 95 +++++ .../jogamp/newt/driver/windows/ScreenDriver.java | 124 ++++++ .../jogamp/newt/driver/windows/WindowDriver.java | 311 ++++++++++++++ .../jogamp/newt/driver/windows/WindowsDisplay.java | 95 ----- .../jogamp/newt/driver/windows/WindowsScreen.java | 124 ------ .../jogamp/newt/driver/windows/WindowsWindow.java | 311 -------------- .../jogamp/newt/driver/x11/DisplayDriver.java | 171 ++++++++ .../jogamp/newt/driver/x11/ScreenDriver.java | 357 ++++++++++++++++ .../jogamp/newt/driver/x11/WindowDriver.java | 261 ++++++++++++ .../classes/jogamp/newt/driver/x11/X11Display.java | 171 -------- .../classes/jogamp/newt/driver/x11/X11Screen.java | 357 ---------------- .../classes/jogamp/newt/driver/x11/X11Window.java | 261 ------------ src/newt/native/AndroidWindow.c | 18 +- src/newt/native/IntelGDL.c | 24 +- src/newt/native/KDWindow.c | 20 +- src/newt/native/MacWindow.m | 116 +++--- src/newt/native/WindowsWindow.c | 78 ++-- src/newt/native/X11Common.h | 6 +- src/newt/native/X11Display.c | 22 +- src/newt/native/X11Screen.c | 62 +-- src/newt/native/X11Window.c | 42 +- src/newt/native/bcm_egl.c | 16 +- src/newt/native/bcm_vc_iv.c | 30 +- .../opengl/test/android/MovieSimpleActivity0.java | 6 +- .../opengl/test/android/MovieSimpleActivity1.java | 10 +- 78 files changed, 4608 insertions(+), 4629 deletions(-) delete mode 100644 src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java delete mode 100644 src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java delete mode 100644 src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java create mode 100644 src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java create mode 100644 src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java create mode 100644 src/newt/classes/jogamp/newt/driver/android/WindowDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java delete mode 100644 src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java delete mode 100644 src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java create mode 100644 src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java create mode 100644 src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java create mode 100644 src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/bcm/egl/Display.java create mode 100644 src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/bcm/egl/Screen.java create mode 100644 src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/bcm/egl/Window.java create mode 100644 src/newt/classes/jogamp/newt/driver/bcm/egl/WindowDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/bcm/vc/iv/Display.java create mode 100644 src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/bcm/vc/iv/Screen.java create mode 100644 src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/bcm/vc/iv/Window.java create mode 100644 src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/intel/gdl/Display.java create mode 100644 src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java create mode 100644 src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java create mode 100644 src/newt/classes/jogamp/newt/driver/intel/gdl/WindowDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/kd/Display.java create mode 100644 src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/kd/Screen.java create mode 100644 src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/kd/Window.java create mode 100644 src/newt/classes/jogamp/newt/driver/kd/WindowDriver.java create mode 100644 src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java delete mode 100644 src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java delete mode 100644 src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java create mode 100644 src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java create mode 100644 src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java create mode 100644 src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java create mode 100644 src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java create mode 100644 src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/windows/WindowsDisplay.java delete mode 100644 src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java delete mode 100644 src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java create mode 100644 src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java create mode 100644 src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java create mode 100644 src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java delete mode 100644 src/newt/classes/jogamp/newt/driver/x11/X11Display.java delete mode 100644 src/newt/classes/jogamp/newt/driver/x11/X11Screen.java delete mode 100644 src/newt/classes/jogamp/newt/driver/x11/X11Window.java (limited to 'src/newt/native/X11Window.c') diff --git a/make/build-newt.xml b/make/build-newt.xml index 0a12374dd..64dccc6ac 100644 --- a/make/build-newt.xml +++ b/make/build-newt.xml @@ -670,30 +670,30 @@ - + - - - + + + - - - - + + + + - - - - - - - - - + + + + + + + + + - + diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 5a8d596df..cccc825ee 100755 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -247,7 +247,7 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* -#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* +testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestRedSquareES1NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestRedSquareES2NEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.TestWindows01NEWT $* @@ -274,7 +274,7 @@ function testawtswt() { #testawt javax.media.opengl.awt.GLCanvas $* #testawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLCanvasAWT $* #testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug551AWT $* -testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn $* +#testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn $* #testawt com.jogamp.opengl.test.junit.jogl.acore.TestAWTCloseX11DisplayBug565 $* #testawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListAWT $* #testawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextNewtAWTBug523 $* diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index 94f5d753c..867d0733b 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -57,22 +57,22 @@ public abstract class NativeWindowFactory { protected static final boolean DEBUG; /** OpenKODE/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}*/ - public static final String TYPE_EGL = "EGL"; + public static final String TYPE_EGL = "jogamp.newt.driver.kd"; /** Microsoft Windows type, as retrieved with {@link #getNativeWindowType(boolean)} */ - public static final String TYPE_WINDOWS = "Windows"; + public static final String TYPE_WINDOWS = "jogamp.newt.driver.windows"; /** X11 type, as retrieved with {@link #getNativeWindowType(boolean)} */ - public static final String TYPE_X11 = "X11"; + public static final String TYPE_X11 = "jogamp.newt.driver.x11"; /** Android/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}*/ - public static final String TYPE_ANDROID = "ANDROID"; + public static final String TYPE_ANDROID = "jogamp.newt.driver.android"; /** Mac OS X type, as retrieved with {@link #getNativeWindowType(boolean)} */ - public static final String TYPE_MACOSX = "MacOSX"; + public static final String TYPE_MACOSX = "jogamp.newt.driver.macosx"; /** Generic AWT type, as retrieved with {@link #getNativeWindowType(boolean)} */ - public static final String TYPE_AWT = "AWT"; + public static final String TYPE_AWT = "jogamp.newt.driver.awt"; /** Generic DEFAULT type, where platform implementation don't care, as retrieved with {@link #getNativeWindowType(boolean)} */ public static final String TYPE_DEFAULT = "default"; diff --git a/src/newt/classes/com/jogamp/newt/util/MainThread.java b/src/newt/classes/com/jogamp/newt/util/MainThread.java index a6e2ae02b..9c2f2a0b7 100644 --- a/src/newt/classes/com/jogamp/newt/util/MainThread.java +++ b/src/newt/classes/com/jogamp/newt/util/MainThread.java @@ -74,7 +74,7 @@ import jogamp.newt.NEWTJNILibLoader; * * To support your NEWT Window platform, * you have to pass your main thread actions to {@link #invoke invoke(..)}, - * have a look at the {@link com.jogamp.newt.macosx.MacWindow MacWindow} implementation.
+ * have a look at the {@link jogamp.newt.driver.macosx.WindowDriver NEWT Mac OSX Window} driver implementation.
* TODO: Some hardcoded dependencies exist in this implementation, * where you have to patch this code or factor it out.

* diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java index 867a1f176..bac4031f0 100644 --- a/src/newt/classes/jogamp/newt/DisplayImpl.java +++ b/src/newt/classes/jogamp/newt/DisplayImpl.java @@ -44,7 +44,6 @@ import com.jogamp.newt.util.EDTUtil; import java.util.ArrayList; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.NativeWindowFactory; public abstract class DisplayImpl extends Display { private static int serialno = 1; @@ -52,26 +51,9 @@ public abstract class DisplayImpl extends Display { private static Class getDisplayClass(String type) throws ClassNotFoundException { - Class displayClass = NewtFactory.getCustomClass(type, "Display"); + final Class displayClass = NewtFactory.getCustomClass(type, "DisplayDriver"); if(null==displayClass) { - if (NativeWindowFactory.TYPE_ANDROID == type) { - displayClass = Class.forName("jogamp.newt.driver.android.AndroidDisplay"); - } else if (NativeWindowFactory.TYPE_EGL == type) { - displayClass = Class.forName("jogamp.newt.driver.kd.Display"); - } else if (NativeWindowFactory.TYPE_WINDOWS == type) { - displayClass = Class.forName("jogamp.newt.driver.windows.WindowsDisplay"); - } else if (NativeWindowFactory.TYPE_MACOSX == type) { - displayClass = Class.forName("jogamp.newt.driver.macosx.MacDisplay"); - } else if (NativeWindowFactory.TYPE_X11 == type) { - displayClass = Class.forName("jogamp.newt.driver.x11.X11Display"); - } else if (NativeWindowFactory.TYPE_AWT == type) { - displayClass = Class.forName("jogamp.newt.driver.awt.AWTDisplay"); - } else { - throw new RuntimeException("Unknown display type \"" + type + "\""); - } - } - if(null==displayClass) { - throw new ClassNotFoundException("Failed to find NEWT Display Class <"+type+".Display>"); + throw new ClassNotFoundException("Failed to find NEWT Display Class <"+type+".DisplayDriver>"); } return displayClass; } diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java index 9f75a0d25..e2c0f746f 100644 --- a/src/newt/classes/jogamp/newt/ScreenImpl.java +++ b/src/newt/classes/jogamp/newt/ScreenImpl.java @@ -90,31 +90,13 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { }); } - @SuppressWarnings("unchecked") - private static Class getScreenClass(String type) throws ClassNotFoundException + private static Class getScreenClass(String type) throws ClassNotFoundException { - Class screenClass = NewtFactory.getCustomClass(type, "Screen"); + final Class screenClass = NewtFactory.getCustomClass(type, "ScreenDriver"); if(null==screenClass) { - if (NativeWindowFactory.TYPE_ANDROID == type) { - screenClass = Class.forName("jogamp.newt.driver.android.AndroidScreen"); - } else if (NativeWindowFactory.TYPE_EGL == type) { - screenClass = Class.forName("jogamp.newt.driver.kd.Screen"); - } else if (NativeWindowFactory.TYPE_WINDOWS == type) { - screenClass = Class.forName("jogamp.newt.driver.windows.WindowsScreen"); - } else if (NativeWindowFactory.TYPE_MACOSX == type) { - screenClass = Class.forName("jogamp.newt.driver.macosx.MacScreen"); - } else if (NativeWindowFactory.TYPE_X11 == type) { - screenClass = Class.forName("jogamp.newt.driver.x11.X11Screen"); - } else if (NativeWindowFactory.TYPE_AWT == type) { - screenClass = Class.forName("jogamp.newt.driver.awt.AWTScreen"); - } else { - throw new RuntimeException("Unknown window type \"" + type + "\""); - } - } - if(null==screenClass) { - throw new ClassNotFoundException("Failed to find NEWT Screen Class <"+type+".Screen>"); + throw new ClassNotFoundException("Failed to find NEWT Screen Class <"+type+".ScreenDriver>"); } - return (Class)screenClass; + return screenClass; } public static Screen create(Display display, int idx) { @@ -133,7 +115,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { } } synchronized(screenList) { - Class screenClass = getScreenClass(display.getType()); + Class screenClass = getScreenClass(display.getType()); ScreenImpl screen = (ScreenImpl) screenClass.newInstance(); screen.display = (DisplayImpl) display; idx = screen.validateScreenIndex(idx); diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 2971fa07e..ad7195944 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -152,26 +152,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private static Class getWindowClass(String type) throws ClassNotFoundException { - Class windowClass = NewtFactory.getCustomClass(type, "Window"); + final Class windowClass = NewtFactory.getCustomClass(type, "WindowDriver"); if(null==windowClass) { - if (NativeWindowFactory.TYPE_ANDROID == type) { - windowClass = Class.forName("jogamp.newt.driver.android.AndroidWindow"); - } else if (NativeWindowFactory.TYPE_EGL == type) { - windowClass = Class.forName("jogamp.newt.driver.kd.Window"); - } else if (NativeWindowFactory.TYPE_WINDOWS == type) { - windowClass = Class.forName("jogamp.newt.driver.windows.WindowsWindow"); - } else if (NativeWindowFactory.TYPE_MACOSX == type) { - windowClass = Class.forName("jogamp.newt.driver.macosx.MacWindow"); - } else if (NativeWindowFactory.TYPE_X11 == type) { - windowClass = Class.forName("jogamp.newt.driver.x11.X11Window"); - } else if (NativeWindowFactory.TYPE_AWT == type) { - windowClass = Class.forName("jogamp.newt.driver.awt.AWTWindow"); - } else { - throw new NativeWindowException("Unknown window type \"" + type + "\""); - } - } - if(null==windowClass) { - throw new ClassNotFoundException("Failed to find NEWT Window Class <"+type+".Window>"); + throw new ClassNotFoundException("Failed to find NEWT Window Class <"+type+".WindowDriver>"); } return windowClass; } diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java b/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java deleted file mode 100644 index 0a43c9b8f..000000000 --- a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright 2011 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ - -package jogamp.newt.driver.android; - -import jogamp.newt.*; -import jogamp.opengl.egl.*; - -import javax.media.nativewindow.*; - -public class AndroidDisplay extends jogamp.newt.DisplayImpl { - static { - NEWTJNILibLoader.loadNEWT(); - - if (!AndroidWindow.initIDs0()) { - throw new NativeWindowException("Failed to initialize Android NEWT Windowing library"); - } - } - - public static void initSingleton() { - // just exist to ensure static init has been run - } - - - public AndroidDisplay() { - } - - protected void createNativeImpl() { - // EGL Device - aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); - } - - protected void closeNativeImpl() { - aDevice.close(); - } - - protected void dispatchMessagesNative() { - // n/a .. DispatchMessages(); - } -} - diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java b/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java deleted file mode 100644 index e108ed0bb..000000000 --- a/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java +++ /dev/null @@ -1,138 +0,0 @@ -/** - * Copyright 2011 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ - -package jogamp.newt.driver.android; - -import javax.media.nativewindow.*; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.Point; - -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.util.ScreenModeUtil; - -import android.content.Context; -import android.graphics.PixelFormat; -import android.util.DisplayMetrics; -import android.view.Surface; -import android.view.WindowManager; - -public class AndroidScreen extends jogamp.newt.ScreenImpl { - - static { - AndroidDisplay.initSingleton(); - } - - public AndroidScreen() { - } - - protected void createNativeImpl() { - aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx); - } - - protected void closeNativeImpl() { } - - protected ScreenMode getCurrentScreenModeImpl() { - final Context ctx = jogamp.common.os.android.StaticContext.getContext(); - final WindowManager wmgr = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); - final DisplayMetrics outMetrics = new DisplayMetrics(); - final android.view.Display aDisplay = wmgr.getDefaultDisplay(); - aDisplay.getMetrics(outMetrics); - - final int arot = aDisplay.getRotation(); - final int nrot = androidRotation2NewtRotation(arot); - int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL]; - int offset = 1; // set later for verification of iterator - offset = getScreenSize(outMetrics, nrot, props, offset); - offset = getBpp(aDisplay, props, offset); - offset = getScreenSizeMM(outMetrics, props, offset); - props[offset++] = (int) aDisplay.getRefreshRate(); - props[offset++] = nrot; - props[offset - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = offset; // count - return ScreenModeUtil.streamIn(props, 0); - } - - protected int validateScreenIndex(int idx) { - return 0; // FIXME: only one screen available ? - } - - protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { - virtualOrigin.setX(0); - virtualOrigin.setY(0); - final ScreenMode sm = getCurrentScreenMode(); - virtualSize.setWidth(sm.getRotatedWidth()); - virtualSize.setHeight(sm.getRotatedHeight()); - } - - //---------------------------------------------------------------------- - // Internals only - // - static int androidRotation2NewtRotation(int arot) { - switch(arot) { - case Surface.ROTATION_270: return ScreenMode.ROTATE_270; - case Surface.ROTATION_180: return ScreenMode.ROTATE_180; - case Surface.ROTATION_90: return ScreenMode.ROTATE_90; - case Surface.ROTATION_0: - } - return ScreenMode.ROTATE_0; - } - static int getScreenSize(DisplayMetrics outMetrics, int nrot, int[] props, int offset) { - // swap width and height, since Android reflects rotated dimension, we don't - if (ScreenMode.ROTATE_90 == nrot || ScreenMode.ROTATE_270 == nrot) { - props[offset++] = outMetrics.heightPixels; - props[offset++] = outMetrics.widthPixels; - } else { - props[offset++] = outMetrics.widthPixels; - props[offset++] = outMetrics.heightPixels; - } - return offset; - } - static int getBpp(android.view.Display aDisplay, int[] props, int offset) { - int bpp; - switch(aDisplay.getPixelFormat()) { - case PixelFormat.RGBA_8888: bpp=32; break; - case PixelFormat.RGBX_8888: bpp=32; break; - case PixelFormat.RGB_888: bpp=24; break; - case PixelFormat.RGB_565: bpp=16; break; - case PixelFormat.RGBA_5551: bpp=16; break; - case PixelFormat.RGBA_4444: bpp=16; break; - case PixelFormat.RGB_332: bpp= 8; break; - default: bpp=32; - } - props[offset++] = bpp; - return offset; - } - static int getScreenSizeMM(DisplayMetrics outMetrics, int[] props, int offset) { - final float iw = (float) outMetrics.widthPixels / outMetrics.xdpi; - final float ih = (float) outMetrics.heightPixels / outMetrics.xdpi; - final float mmpi = 25.4f; - props[offset++] = (int) ((iw * mmpi)+0.5); - props[offset++] = (int) ((ih * mmpi)+0.5); - return offset; - } -} - diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java b/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java deleted file mode 100644 index 73192a07f..000000000 --- a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java +++ /dev/null @@ -1,458 +0,0 @@ -/** - * Copyright 2011 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ - -package jogamp.newt.driver.android; - -import jogamp.common.os.android.StaticContext; -import jogamp.newt.driver.android.event.AndroidNewtEventFactory; - -import javax.media.nativewindow.Capabilities; -import javax.media.nativewindow.CapabilitiesImmutable; -import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.VisualIDHolder; -import javax.media.nativewindow.util.Insets; -import javax.media.nativewindow.util.Point; -import javax.media.opengl.GLCapabilitiesChooser; -import javax.media.opengl.GLCapabilitiesImmutable; - -import com.jogamp.nativewindow.egl.EGLGraphicsDevice; - -import jogamp.opengl.egl.EGL; -import jogamp.opengl.egl.EGLGraphicsConfiguration; -import jogamp.opengl.egl.EGLGraphicsConfigurationFactory; - -import android.content.Context; -import android.graphics.PixelFormat; -import android.os.Bundle; -import android.os.IBinder; -import android.os.ResultReceiver; -import android.util.Log; -import android.view.Surface; -import android.view.SurfaceHolder; -import android.view.SurfaceHolder.Callback2; -import android.view.inputmethod.InputMethodManager; -import android.view.SurfaceView; -import android.view.View; - -public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 { - static { - AndroidDisplay.initSingleton(); - } - - public static CapabilitiesImmutable fixCaps(boolean matchFormatPrecise, int format, CapabilitiesImmutable rCaps) { - PixelFormat pf = new PixelFormat(); - PixelFormat.getPixelFormatInfo(format, pf); - final CapabilitiesImmutable res; - int r, g, b, a; - - switch(format) { - case PixelFormat.RGBA_8888: r=8; g=8; b=8; a=8; break; - case PixelFormat.RGBX_8888: r=8; g=8; b=8; a=0; break; - case PixelFormat.RGB_888: r=8; g=8; b=8; a=0; break; - case PixelFormat.RGB_565: r=5; g=6; b=5; a=0; break; - case PixelFormat.RGBA_5551: r=5; g=5; b=5; a=1; break; - case PixelFormat.RGBA_4444: r=4; g=4; b=4; a=4; break; - case PixelFormat.RGB_332: r=3; g=3; b=2; a=0; break; - default: throw new InternalError("Unhandled pixelformat: "+format); - } - final boolean change = matchFormatPrecise || - rCaps.getRedBits() > r && - rCaps.getGreenBits() > g && - rCaps.getBlueBits() > b && - rCaps.getAlphaBits() > a ; - - if(change) { - Capabilities nCaps = (Capabilities) rCaps.cloneMutable(); - nCaps.setRedBits(r); - nCaps.setGreenBits(g); - nCaps.setBlueBits(b); - nCaps.setAlphaBits(a); - res = nCaps; - } else { - res = rCaps; - } - Log.d(MD.TAG, "fixCaps: format: "+format); - Log.d(MD.TAG, "fixCaps: requested: "+rCaps); - Log.d(MD.TAG, "fixCaps: chosen: "+res); - - return res; - } - - public static int getFormat(CapabilitiesImmutable rCaps) { - int fmt = PixelFormat.UNKNOWN; - - if(!rCaps.isBackgroundOpaque()) { - fmt = PixelFormat.TRANSLUCENT; - } else if(rCaps.getRedBits()<=5 && - rCaps.getGreenBits()<=6 && - rCaps.getBlueBits()<=5 && - rCaps.getAlphaBits()==0) { - fmt = PixelFormat.RGB_565; - } - /* else if(rCaps.getRedBits()<=5 && - rCaps.getGreenBits()<=5 && - rCaps.getBlueBits()<=5 && - rCaps.getAlphaBits()==1) { - fmt = PixelFormat.RGBA_5551; // FIXME: Supported ? - } */ - else { - fmt = PixelFormat.RGBA_8888; - } - Log.d(MD.TAG, "getFormat: requested: "+rCaps); - Log.d(MD.TAG, "getFormat: returned: "+fmt); - - return fmt; - } - - public static boolean isAndroidFormatTransparent(int aFormat) { - switch (aFormat) { - case PixelFormat.TRANSLUCENT: - case PixelFormat.TRANSPARENT: - return true; - } - return false; - } - - class AndroidEvents implements View.OnKeyListener, View.OnTouchListener, View.OnFocusChangeListener { - - @Override - public boolean onTouch(View v, android.view.MotionEvent event) { - final com.jogamp.newt.event.MouseEvent[] newtEvents = AndroidNewtEventFactory.createMouseEvents(event, AndroidWindow.this); - if(null != newtEvents) { - focusChanged(false, true); - for(int i=0; i[] getCustomConstructorArgumentTypes() { - return new Class[] { Context.class } ; - } - - public AndroidWindow() { - reset(); - } - - private void reset() { - ownAndroidWindow = false; - androidView = null; - nativeFormat = VisualIDHolder.VID_UNDEFINED; - androidFormat = VisualIDHolder.VID_UNDEFINED; - capsByFormat = null; - surface = null; - surfaceHandle = 0; - eglSurface = 0; - definePosition(0, 0); // default to 0/0 - setBrokenFocusChange(true); - } - - @Override - protected void instantiationFinished() { - final Context ctx = StaticContext.getContext(); - if(null == ctx) { - throw new NativeWindowException("No static [Application] Context has been set. Call StaticContext.setContext(Context) first."); - } - androidView = new MSurfaceView(ctx); - - final AndroidEvents ae = new AndroidEvents(); - androidView.setOnTouchListener(ae); - androidView.setClickable(false); - androidView.setOnKeyListener(ae); - androidView.setOnFocusChangeListener(ae); - androidView.setFocusable(true); - androidView.setFocusableInTouchMode(true); - - final SurfaceHolder sh = androidView.getHolder(); - sh.addCallback(AndroidWindow.this); - sh.setFormat(getFormat(getRequestedCapabilities())); - - // default size -> TBD ! - defineSize(0, 0); - } - - public SurfaceView getAndroidView() { return androidView; } - - @Override - protected boolean canCreateNativeImpl() { - final boolean b = 0 != surfaceHandle; - Log.d(MD.TAG, "canCreateNativeImpl: "+b); - return b; - } - - @Override - protected void createNativeImpl() { - Log.d(MD.TAG, "createNativeImpl 0 - surfaceHandle 0x"+Long.toHexString(surfaceHandle)+ - ", format [a "+androidFormat+", n "+nativeFormat+"], "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+" - "+Thread.currentThread().getName()); - - if(0!=getParentWindowHandle()) { - throw new NativeWindowException("Window parenting not supported (yet)"); - } - if(0==surfaceHandle) { - throw new InternalError("XXX"); - } - - final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) getScreen().getDisplay().getGraphicsDevice(); - final EGLGraphicsConfiguration eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic( - capsByFormat, (GLCapabilitiesImmutable) getRequestedCapabilities(), - (GLCapabilitiesChooser)capabilitiesChooser, getScreen().getGraphicsScreen(), nativeFormat, - isAndroidFormatTransparent(androidFormat)); - if (eglConfig == null) { - throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); - } - final int nativeVisualID = eglConfig.getVisualID(VisualIDHolder.VIDType.NATIVE); - Log.d(MD.TAG, "nativeVisualID 0x"+Integer.toHexString(nativeVisualID)); - if(VisualIDHolder.VID_UNDEFINED != nativeVisualID) { - setSurfaceVisualID0(surfaceHandle, nativeVisualID); - } - - eglSurface = EGL.eglCreateWindowSurface(eglDevice.getHandle(), eglConfig.getNativeConfig(), surfaceHandle, null); - if (EGL.EGL_NO_SURFACE==eglSurface) { - throw new NativeWindowException("Creation of window surface failed: "+eglConfig+", surfaceHandle 0x"+Long.toHexString(surfaceHandle)+", error "+toHexString(EGL.eglGetError())); - } - - // propagate data .. - setGraphicsConfiguration(eglConfig); - setWindowHandle(surfaceHandle); - focusChanged(false, true); - Log.d(MD.TAG, "createNativeImpl X"); - } - - @Override - protected void closeNativeImpl() { - release0(surfaceHandle); - surface = null; - surfaceHandle = 0; - eglSurface = 0; - } - - @Override - public final long getSurfaceHandle() { - return eglSurface; - } - - protected void requestFocusImpl(boolean reparented) { - if(null != androidView) { - Log.d(MD.TAG, "requestFocusImpl: reparented "+reparented); - androidView.post(new Runnable() { - public void run() { - androidView.requestFocus(); - androidView.bringToFront(); - } - }); - } - } - - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { - if( 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) { - Log.d(MD.TAG, "reconfigureWindowImpl.setFullscreen post creation (setContentView()) n/a"); - return false; - } - if(width>0 || height>0) { - if(0!=getWindowHandle()) { - Log.d(MD.TAG, "reconfigureWindowImpl.setSize n/a"); - return false; - } - } - if(x>=0 || y>=0) { - Log.d(MD.TAG, "reconfigureWindowImpl.setPos n/a"); - return false; - } - if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { - visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); - } - return true; - } - - protected Point getLocationOnScreenImpl(int x, int y) { - return new Point(x,y); - } - - protected void updateInsetsImpl(Insets insets) { - // nop .. - } - - //---------------------------------------------------------------------- - // Virtual On-Screen Keyboard / SoftInput - // - - private class KeyboardVisibleReceiver extends ResultReceiver { - public KeyboardVisibleReceiver() { - super(null); - } - - @Override - public void onReceiveResult(int r, Bundle data) { - boolean v = false; - - switch(r) { - case InputMethodManager.RESULT_UNCHANGED_SHOWN: - case InputMethodManager.RESULT_SHOWN: - v = true; - break; - case InputMethodManager.RESULT_HIDDEN: - case InputMethodManager.RESULT_UNCHANGED_HIDDEN: - v = false; - break; - } - Log.d(MD.TAG, "keyboardVisible: "+v); - keyboardVisibilityChanged(v); - } - } - private KeyboardVisibleReceiver keyboardVisibleReceiver = new KeyboardVisibleReceiver(); - - protected final boolean setKeyboardVisibleImpl(boolean visible) { - if(null != androidView) { - final InputMethodManager imm = (InputMethodManager) getAndroidView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - final IBinder winid = getAndroidView().getWindowToken(); - if(visible) { - // Show soft-keyboard: - imm.showSoftInput(androidView, 0, keyboardVisibleReceiver); - } else { - // hide keyboard : - imm.hideSoftInputFromWindow(winid, 0, keyboardVisibleReceiver); - } - return visible; - } else { - return false; // nop - } - } - - //---------------------------------------------------------------------- - // Surface Callbacks - // - - public void surfaceCreated(SurfaceHolder holder) { - Log.d(MD.TAG, "surfaceCreated: "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()); - } - - public void surfaceChanged(SurfaceHolder aHolder, int aFormat, int aWidth, int aHeight) { - Log.d(MD.TAG, "surfaceChanged: f "+nativeFormat+" -> "+aFormat+", "+aWidth+"x"+aHeight+", current surfaceHandle: 0x"+Long.toHexString(surfaceHandle)); - if(0!=surfaceHandle && androidFormat != aFormat ) { - // re-create - Log.d(MD.TAG, "surfaceChanged (destroy old)"); - if(!windowDestroyNotify(true)) { - destroy(); - } - surfaceHandle = 0; - surface=null; - } - if(getScreen().isNativeValid()) { - getScreen().getCurrentScreenMode(); // if ScreenMode changed .. trigger ScreenMode event - } - - if(0>getX() || 0>getY()) { - positionChanged(false, 0, 0); - } - - if(0 == surfaceHandle) { - androidFormat = aFormat; - surface = aHolder.getSurface(); - surfaceHandle = getSurfaceHandle0(surface); - acquire0(surfaceHandle); - nativeFormat = getSurfaceVisualID0(surfaceHandle); - final int nWidth = getWidth0(surfaceHandle); - final int nHeight = getHeight0(surfaceHandle); - capsByFormat = (GLCapabilitiesImmutable) fixCaps(true /* matchFormatPrecise */, nativeFormat, getRequestedCapabilities()); - sizeChanged(false, nWidth, nHeight, false); - - Log.d(MD.TAG, "surfaceRealized: isValid: "+surface.isValid()+ - ", new surfaceHandle 0x"+Long.toHexString(surfaceHandle)+ - ", format [a "+androidFormat+"/n "+nativeFormat+"], "+ - getX()+"/"+getY()+" "+nWidth+"x"+nHeight+", visible: "+isVisible()); - - if(isVisible()) { - setVisible(true); - } - } - sizeChanged(false, aWidth, aHeight, false); - windowRepaint(0, 0, aWidth, aHeight); - Log.d(MD.TAG, "surfaceChanged: X"); - } - - public void surfaceDestroyed(SurfaceHolder holder) { - Log.d(MD.TAG, "surfaceDestroyed"); - windowDestroyNotify(true); // actually too late .. however .. - } - - public void surfaceRedrawNeeded(SurfaceHolder holder) { - Log.d(MD.TAG, "surfaceRedrawNeeded"); - windowRepaint(0, 0, getWidth(), getHeight()); - } - - private boolean ownAndroidWindow; - private MSurfaceView androidView; - private int nativeFormat; // chosen current native PixelFormat (suitable for EGL) - private int androidFormat; // chosen current android PixelFormat (-1, -2 ..) - private GLCapabilitiesImmutable capsByFormat; // fixed requestedCaps by PixelFormat - private Surface surface; - private volatile long surfaceHandle; - private long eglSurface; - - class MSurfaceView extends SurfaceView { - public MSurfaceView (Context ctx) { - super(ctx); - setBackgroundDrawable(null); - // setBackgroundColor(Color.TRANSPARENT); - } - } - //---------------------------------------------------------------------- - // Internals only - // - protected static native boolean initIDs0(); - protected static native long getSurfaceHandle0(Surface surface); - protected static native int getSurfaceVisualID0(long surfaceHandle); - protected static native void setSurfaceVisualID0(long surfaceHandle, int nativeVisualID); - protected static native int getWidth0(long surfaceHandle); - protected static native int getHeight0(long surfaceHandle); - protected static native void acquire0(long surfaceHandle); - protected static native void release0(long surfaceHandle); -} diff --git a/src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java new file mode 100644 index 000000000..a367462c4 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java @@ -0,0 +1,66 @@ +/** + * Copyright 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.newt.driver.android; + +import jogamp.newt.*; +import jogamp.opengl.egl.*; + +import javax.media.nativewindow.*; + +public class DisplayDriver extends jogamp.newt.DisplayImpl { + static { + NEWTJNILibLoader.loadNEWT(); + + if (!WindowDriver.initIDs0()) { + throw new NativeWindowException("Failed to initialize Android NEWT Windowing library"); + } + } + + public static void initSingleton() { + // just exist to ensure static init has been run + } + + + public DisplayDriver() { + } + + protected void createNativeImpl() { + // EGL Device + aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); + } + + protected void closeNativeImpl() { + aDevice.close(); + } + + protected void dispatchMessagesNative() { + // n/a .. DispatchMessages(); + } +} + diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java index 4537fa963..91c589beb 100644 --- a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java +++ b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java @@ -36,7 +36,7 @@ import javax.media.opengl.FPSCounter; import com.jogamp.newt.Window; import com.jogamp.opengl.util.Animator; -import jogamp.newt.driver.android.AndroidWindow; +import jogamp.newt.driver.android.WindowDriver; import android.app.Activity; import android.content.Context; @@ -83,10 +83,10 @@ public class NewtBaseActivity extends Activity { */ public void setContentView(android.view.Window androidWindow, Window newtWindow) { newtWindow = newtWindow.getDelegatedWindow(); - if(newtWindow instanceof AndroidWindow) { + if(newtWindow instanceof WindowDriver) { adaptTheme4Transparency(newtWindow.getRequestedCapabilities()); layoutForNEWTWindow(androidWindow, newtWindow); - AndroidWindow newtAWindow = (AndroidWindow)newtWindow; + WindowDriver newtAWindow = (WindowDriver)newtWindow; androidWindow.setContentView(newtAWindow.getAndroidView()); registerNEWTWindow(newtAWindow); } else { @@ -107,8 +107,8 @@ public class NewtBaseActivity extends Activity { */ public void addContentView(android.view.Window androidWindow, Window newtWindow, android.view.ViewGroup.LayoutParams params) { newtWindow = newtWindow.getDelegatedWindow(); - if(newtWindow instanceof AndroidWindow) { - AndroidWindow newtAWindow = (AndroidWindow)newtWindow; + if(newtWindow instanceof WindowDriver) { + WindowDriver newtAWindow = (WindowDriver)newtWindow; androidWindow.addContentView(newtAWindow.getAndroidView(), params); registerNEWTWindow(newtAWindow); } else { diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java index 36b83337a..a49f1648c 100644 --- a/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java +++ b/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java @@ -69,7 +69,7 @@ public class NewtVersionActivity extends NewtBaseActivity { glWindow.setUndecorated(true); glWindow.setSize(32, 32); glWindow.setPosition(0, 0); - final android.view.View androidGLView = ((AndroidWindow)glWindow.getDelegatedWindow()).getAndroidView(); + final android.view.View androidGLView = ((WindowDriver)glWindow.getDelegatedWindow()).getAndroidView(); viewGroup.addView(androidGLView, new android.widget.FrameLayout.LayoutParams(glWindow.getWidth(), glWindow.getHeight(), Gravity.BOTTOM|Gravity.RIGHT)); registerNEWTWindow(glWindow); diff --git a/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java new file mode 100644 index 000000000..795aac5fb --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java @@ -0,0 +1,138 @@ +/** + * Copyright 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.newt.driver.android; + +import javax.media.nativewindow.*; +import javax.media.nativewindow.util.Dimension; +import javax.media.nativewindow.util.Point; + +import com.jogamp.newt.ScreenMode; +import com.jogamp.newt.util.ScreenModeUtil; + +import android.content.Context; +import android.graphics.PixelFormat; +import android.util.DisplayMetrics; +import android.view.Surface; +import android.view.WindowManager; + +public class ScreenDriver extends jogamp.newt.ScreenImpl { + + static { + DisplayDriver.initSingleton(); + } + + public ScreenDriver() { + } + + protected void createNativeImpl() { + aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx); + } + + protected void closeNativeImpl() { } + + protected ScreenMode getCurrentScreenModeImpl() { + final Context ctx = jogamp.common.os.android.StaticContext.getContext(); + final WindowManager wmgr = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); + final DisplayMetrics outMetrics = new DisplayMetrics(); + final android.view.Display aDisplay = wmgr.getDefaultDisplay(); + aDisplay.getMetrics(outMetrics); + + final int arot = aDisplay.getRotation(); + final int nrot = androidRotation2NewtRotation(arot); + int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL]; + int offset = 1; // set later for verification of iterator + offset = getScreenSize(outMetrics, nrot, props, offset); + offset = getBpp(aDisplay, props, offset); + offset = getScreenSizeMM(outMetrics, props, offset); + props[offset++] = (int) aDisplay.getRefreshRate(); + props[offset++] = nrot; + props[offset - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = offset; // count + return ScreenModeUtil.streamIn(props, 0); + } + + protected int validateScreenIndex(int idx) { + return 0; // FIXME: only one screen available ? + } + + protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { + virtualOrigin.setX(0); + virtualOrigin.setY(0); + final ScreenMode sm = getCurrentScreenMode(); + virtualSize.setWidth(sm.getRotatedWidth()); + virtualSize.setHeight(sm.getRotatedHeight()); + } + + //---------------------------------------------------------------------- + // Internals only + // + static int androidRotation2NewtRotation(int arot) { + switch(arot) { + case Surface.ROTATION_270: return ScreenMode.ROTATE_270; + case Surface.ROTATION_180: return ScreenMode.ROTATE_180; + case Surface.ROTATION_90: return ScreenMode.ROTATE_90; + case Surface.ROTATION_0: + } + return ScreenMode.ROTATE_0; + } + static int getScreenSize(DisplayMetrics outMetrics, int nrot, int[] props, int offset) { + // swap width and height, since Android reflects rotated dimension, we don't + if (ScreenMode.ROTATE_90 == nrot || ScreenMode.ROTATE_270 == nrot) { + props[offset++] = outMetrics.heightPixels; + props[offset++] = outMetrics.widthPixels; + } else { + props[offset++] = outMetrics.widthPixels; + props[offset++] = outMetrics.heightPixels; + } + return offset; + } + static int getBpp(android.view.Display aDisplay, int[] props, int offset) { + int bpp; + switch(aDisplay.getPixelFormat()) { + case PixelFormat.RGBA_8888: bpp=32; break; + case PixelFormat.RGBX_8888: bpp=32; break; + case PixelFormat.RGB_888: bpp=24; break; + case PixelFormat.RGB_565: bpp=16; break; + case PixelFormat.RGBA_5551: bpp=16; break; + case PixelFormat.RGBA_4444: bpp=16; break; + case PixelFormat.RGB_332: bpp= 8; break; + default: bpp=32; + } + props[offset++] = bpp; + return offset; + } + static int getScreenSizeMM(DisplayMetrics outMetrics, int[] props, int offset) { + final float iw = (float) outMetrics.widthPixels / outMetrics.xdpi; + final float ih = (float) outMetrics.heightPixels / outMetrics.xdpi; + final float mmpi = 25.4f; + props[offset++] = (int) ((iw * mmpi)+0.5); + props[offset++] = (int) ((ih * mmpi)+0.5); + return offset; + } +} + diff --git a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java new file mode 100644 index 000000000..8ad11b35f --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java @@ -0,0 +1,458 @@ +/** + * Copyright 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.newt.driver.android; + +import jogamp.common.os.android.StaticContext; +import jogamp.newt.driver.android.event.AndroidNewtEventFactory; + +import javax.media.nativewindow.Capabilities; +import javax.media.nativewindow.CapabilitiesImmutable; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.VisualIDHolder; +import javax.media.nativewindow.util.Insets; +import javax.media.nativewindow.util.Point; +import javax.media.opengl.GLCapabilitiesChooser; +import javax.media.opengl.GLCapabilitiesImmutable; + +import com.jogamp.nativewindow.egl.EGLGraphicsDevice; + +import jogamp.opengl.egl.EGL; +import jogamp.opengl.egl.EGLGraphicsConfiguration; +import jogamp.opengl.egl.EGLGraphicsConfigurationFactory; + +import android.content.Context; +import android.graphics.PixelFormat; +import android.os.Bundle; +import android.os.IBinder; +import android.os.ResultReceiver; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceHolder.Callback2; +import android.view.inputmethod.InputMethodManager; +import android.view.SurfaceView; +import android.view.View; + +public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 { + static { + DisplayDriver.initSingleton(); + } + + public static CapabilitiesImmutable fixCaps(boolean matchFormatPrecise, int format, CapabilitiesImmutable rCaps) { + PixelFormat pf = new PixelFormat(); + PixelFormat.getPixelFormatInfo(format, pf); + final CapabilitiesImmutable res; + int r, g, b, a; + + switch(format) { + case PixelFormat.RGBA_8888: r=8; g=8; b=8; a=8; break; + case PixelFormat.RGBX_8888: r=8; g=8; b=8; a=0; break; + case PixelFormat.RGB_888: r=8; g=8; b=8; a=0; break; + case PixelFormat.RGB_565: r=5; g=6; b=5; a=0; break; + case PixelFormat.RGBA_5551: r=5; g=5; b=5; a=1; break; + case PixelFormat.RGBA_4444: r=4; g=4; b=4; a=4; break; + case PixelFormat.RGB_332: r=3; g=3; b=2; a=0; break; + default: throw new InternalError("Unhandled pixelformat: "+format); + } + final boolean change = matchFormatPrecise || + rCaps.getRedBits() > r && + rCaps.getGreenBits() > g && + rCaps.getBlueBits() > b && + rCaps.getAlphaBits() > a ; + + if(change) { + Capabilities nCaps = (Capabilities) rCaps.cloneMutable(); + nCaps.setRedBits(r); + nCaps.setGreenBits(g); + nCaps.setBlueBits(b); + nCaps.setAlphaBits(a); + res = nCaps; + } else { + res = rCaps; + } + Log.d(MD.TAG, "fixCaps: format: "+format); + Log.d(MD.TAG, "fixCaps: requested: "+rCaps); + Log.d(MD.TAG, "fixCaps: chosen: "+res); + + return res; + } + + public static int getFormat(CapabilitiesImmutable rCaps) { + int fmt = PixelFormat.UNKNOWN; + + if(!rCaps.isBackgroundOpaque()) { + fmt = PixelFormat.TRANSLUCENT; + } else if(rCaps.getRedBits()<=5 && + rCaps.getGreenBits()<=6 && + rCaps.getBlueBits()<=5 && + rCaps.getAlphaBits()==0) { + fmt = PixelFormat.RGB_565; + } + /* else if(rCaps.getRedBits()<=5 && + rCaps.getGreenBits()<=5 && + rCaps.getBlueBits()<=5 && + rCaps.getAlphaBits()==1) { + fmt = PixelFormat.RGBA_5551; // FIXME: Supported ? + } */ + else { + fmt = PixelFormat.RGBA_8888; + } + Log.d(MD.TAG, "getFormat: requested: "+rCaps); + Log.d(MD.TAG, "getFormat: returned: "+fmt); + + return fmt; + } + + public static boolean isAndroidFormatTransparent(int aFormat) { + switch (aFormat) { + case PixelFormat.TRANSLUCENT: + case PixelFormat.TRANSPARENT: + return true; + } + return false; + } + + class AndroidEvents implements View.OnKeyListener, View.OnTouchListener, View.OnFocusChangeListener { + + @Override + public boolean onTouch(View v, android.view.MotionEvent event) { + final com.jogamp.newt.event.MouseEvent[] newtEvents = AndroidNewtEventFactory.createMouseEvents(event, WindowDriver.this); + if(null != newtEvents) { + focusChanged(false, true); + for(int i=0; i[] getCustomConstructorArgumentTypes() { + return new Class[] { Context.class } ; + } + + public WindowDriver() { + reset(); + } + + private void reset() { + ownAndroidWindow = false; + androidView = null; + nativeFormat = VisualIDHolder.VID_UNDEFINED; + androidFormat = VisualIDHolder.VID_UNDEFINED; + capsByFormat = null; + surface = null; + surfaceHandle = 0; + eglSurface = 0; + definePosition(0, 0); // default to 0/0 + setBrokenFocusChange(true); + } + + @Override + protected void instantiationFinished() { + final Context ctx = StaticContext.getContext(); + if(null == ctx) { + throw new NativeWindowException("No static [Application] Context has been set. Call StaticContext.setContext(Context) first."); + } + androidView = new MSurfaceView(ctx); + + final AndroidEvents ae = new AndroidEvents(); + androidView.setOnTouchListener(ae); + androidView.setClickable(false); + androidView.setOnKeyListener(ae); + androidView.setOnFocusChangeListener(ae); + androidView.setFocusable(true); + androidView.setFocusableInTouchMode(true); + + final SurfaceHolder sh = androidView.getHolder(); + sh.addCallback(WindowDriver.this); + sh.setFormat(getFormat(getRequestedCapabilities())); + + // default size -> TBD ! + defineSize(0, 0); + } + + public SurfaceView getAndroidView() { return androidView; } + + @Override + protected boolean canCreateNativeImpl() { + final boolean b = 0 != surfaceHandle; + Log.d(MD.TAG, "canCreateNativeImpl: "+b); + return b; + } + + @Override + protected void createNativeImpl() { + Log.d(MD.TAG, "createNativeImpl 0 - surfaceHandle 0x"+Long.toHexString(surfaceHandle)+ + ", format [a "+androidFormat+", n "+nativeFormat+"], "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+" - "+Thread.currentThread().getName()); + + if(0!=getParentWindowHandle()) { + throw new NativeWindowException("Window parenting not supported (yet)"); + } + if(0==surfaceHandle) { + throw new InternalError("XXX"); + } + + final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) getScreen().getDisplay().getGraphicsDevice(); + final EGLGraphicsConfiguration eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic( + capsByFormat, (GLCapabilitiesImmutable) getRequestedCapabilities(), + (GLCapabilitiesChooser)capabilitiesChooser, getScreen().getGraphicsScreen(), nativeFormat, + isAndroidFormatTransparent(androidFormat)); + if (eglConfig == null) { + throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); + } + final int nativeVisualID = eglConfig.getVisualID(VisualIDHolder.VIDType.NATIVE); + Log.d(MD.TAG, "nativeVisualID 0x"+Integer.toHexString(nativeVisualID)); + if(VisualIDHolder.VID_UNDEFINED != nativeVisualID) { + setSurfaceVisualID0(surfaceHandle, nativeVisualID); + } + + eglSurface = EGL.eglCreateWindowSurface(eglDevice.getHandle(), eglConfig.getNativeConfig(), surfaceHandle, null); + if (EGL.EGL_NO_SURFACE==eglSurface) { + throw new NativeWindowException("Creation of window surface failed: "+eglConfig+", surfaceHandle 0x"+Long.toHexString(surfaceHandle)+", error "+toHexString(EGL.eglGetError())); + } + + // propagate data .. + setGraphicsConfiguration(eglConfig); + setWindowHandle(surfaceHandle); + focusChanged(false, true); + Log.d(MD.TAG, "createNativeImpl X"); + } + + @Override + protected void closeNativeImpl() { + release0(surfaceHandle); + surface = null; + surfaceHandle = 0; + eglSurface = 0; + } + + @Override + public final long getSurfaceHandle() { + return eglSurface; + } + + protected void requestFocusImpl(boolean reparented) { + if(null != androidView) { + Log.d(MD.TAG, "requestFocusImpl: reparented "+reparented); + androidView.post(new Runnable() { + public void run() { + androidView.requestFocus(); + androidView.bringToFront(); + } + }); + } + } + + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + if( 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) { + Log.d(MD.TAG, "reconfigureWindowImpl.setFullscreen post creation (setContentView()) n/a"); + return false; + } + if(width>0 || height>0) { + if(0!=getWindowHandle()) { + Log.d(MD.TAG, "reconfigureWindowImpl.setSize n/a"); + return false; + } + } + if(x>=0 || y>=0) { + Log.d(MD.TAG, "reconfigureWindowImpl.setPos n/a"); + return false; + } + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); + } + return true; + } + + protected Point getLocationOnScreenImpl(int x, int y) { + return new Point(x,y); + } + + protected void updateInsetsImpl(Insets insets) { + // nop .. + } + + //---------------------------------------------------------------------- + // Virtual On-Screen Keyboard / SoftInput + // + + private class KeyboardVisibleReceiver extends ResultReceiver { + public KeyboardVisibleReceiver() { + super(null); + } + + @Override + public void onReceiveResult(int r, Bundle data) { + boolean v = false; + + switch(r) { + case InputMethodManager.RESULT_UNCHANGED_SHOWN: + case InputMethodManager.RESULT_SHOWN: + v = true; + break; + case InputMethodManager.RESULT_HIDDEN: + case InputMethodManager.RESULT_UNCHANGED_HIDDEN: + v = false; + break; + } + Log.d(MD.TAG, "keyboardVisible: "+v); + keyboardVisibilityChanged(v); + } + } + private KeyboardVisibleReceiver keyboardVisibleReceiver = new KeyboardVisibleReceiver(); + + protected final boolean setKeyboardVisibleImpl(boolean visible) { + if(null != androidView) { + final InputMethodManager imm = (InputMethodManager) getAndroidView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + final IBinder winid = getAndroidView().getWindowToken(); + if(visible) { + // Show soft-keyboard: + imm.showSoftInput(androidView, 0, keyboardVisibleReceiver); + } else { + // hide keyboard : + imm.hideSoftInputFromWindow(winid, 0, keyboardVisibleReceiver); + } + return visible; + } else { + return false; // nop + } + } + + //---------------------------------------------------------------------- + // Surface Callbacks + // + + public void surfaceCreated(SurfaceHolder holder) { + Log.d(MD.TAG, "surfaceCreated: "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()); + } + + public void surfaceChanged(SurfaceHolder aHolder, int aFormat, int aWidth, int aHeight) { + Log.d(MD.TAG, "surfaceChanged: f "+nativeFormat+" -> "+aFormat+", "+aWidth+"x"+aHeight+", current surfaceHandle: 0x"+Long.toHexString(surfaceHandle)); + if(0!=surfaceHandle && androidFormat != aFormat ) { + // re-create + Log.d(MD.TAG, "surfaceChanged (destroy old)"); + if(!windowDestroyNotify(true)) { + destroy(); + } + surfaceHandle = 0; + surface=null; + } + if(getScreen().isNativeValid()) { + getScreen().getCurrentScreenMode(); // if ScreenMode changed .. trigger ScreenMode event + } + + if(0>getX() || 0>getY()) { + positionChanged(false, 0, 0); + } + + if(0 == surfaceHandle) { + androidFormat = aFormat; + surface = aHolder.getSurface(); + surfaceHandle = getSurfaceHandle0(surface); + acquire0(surfaceHandle); + nativeFormat = getSurfaceVisualID0(surfaceHandle); + final int nWidth = getWidth0(surfaceHandle); + final int nHeight = getHeight0(surfaceHandle); + capsByFormat = (GLCapabilitiesImmutable) fixCaps(true /* matchFormatPrecise */, nativeFormat, getRequestedCapabilities()); + sizeChanged(false, nWidth, nHeight, false); + + Log.d(MD.TAG, "surfaceRealized: isValid: "+surface.isValid()+ + ", new surfaceHandle 0x"+Long.toHexString(surfaceHandle)+ + ", format [a "+androidFormat+"/n "+nativeFormat+"], "+ + getX()+"/"+getY()+" "+nWidth+"x"+nHeight+", visible: "+isVisible()); + + if(isVisible()) { + setVisible(true); + } + } + sizeChanged(false, aWidth, aHeight, false); + windowRepaint(0, 0, aWidth, aHeight); + Log.d(MD.TAG, "surfaceChanged: X"); + } + + public void surfaceDestroyed(SurfaceHolder holder) { + Log.d(MD.TAG, "surfaceDestroyed"); + windowDestroyNotify(true); // actually too late .. however .. + } + + public void surfaceRedrawNeeded(SurfaceHolder holder) { + Log.d(MD.TAG, "surfaceRedrawNeeded"); + windowRepaint(0, 0, getWidth(), getHeight()); + } + + private boolean ownAndroidWindow; + private MSurfaceView androidView; + private int nativeFormat; // chosen current native PixelFormat (suitable for EGL) + private int androidFormat; // chosen current android PixelFormat (-1, -2 ..) + private GLCapabilitiesImmutable capsByFormat; // fixed requestedCaps by PixelFormat + private Surface surface; + private volatile long surfaceHandle; + private long eglSurface; + + class MSurfaceView extends SurfaceView { + public MSurfaceView (Context ctx) { + super(ctx); + setBackgroundDrawable(null); + // setBackgroundColor(Color.TRANSPARENT); + } + } + //---------------------------------------------------------------------- + // Internals only + // + protected static native boolean initIDs0(); + protected static native long getSurfaceHandle0(Surface surface); + protected static native int getSurfaceVisualID0(long surfaceHandle); + protected static native void setSurfaceVisualID0(long surfaceHandle, int nativeVisualID); + protected static native int getWidth0(long surfaceHandle); + protected static native int getHeight0(long surfaceHandle); + protected static native void acquire0(long surfaceHandle); + protected static native void release0(long surfaceHandle); +} diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java index a7950048a..b3fdcad41 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java +++ b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java b/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java deleted file mode 100644 index 65f8b4715..000000000 --- a/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.awt; - -import com.jogamp.nativewindow.awt.AWTGraphicsDevice; -import com.jogamp.newt.NewtFactory; -import com.jogamp.newt.util.EDTUtil; - -import jogamp.newt.DisplayImpl; - -public class AWTDisplay extends DisplayImpl { - public AWTDisplay() { - } - - protected void createNativeImpl() { - aDevice = AWTGraphicsDevice.createDefault(); - } - - protected void setAWTGraphicsDevice(AWTGraphicsDevice d) { - aDevice = d; - } - - protected void closeNativeImpl() { } - - @Override - protected EDTUtil createEDTUtil() { - final EDTUtil def; - if(NewtFactory.useEDT()) { - def = AWTEDTUtil.getSingleton(); - if(DEBUG) { - System.err.println("AWTDisplay.createNative("+getFQName()+") Create EDTUtil: "+def.getClass().getName()); - } - } else { - def = null; - } - return def; - } - - protected void dispatchMessagesNative() { /* nop */ } -} - diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java b/src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java deleted file mode 100644 index a3c0281b1..000000000 --- a/src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.awt; - -import java.awt.DisplayMode; - -import jogamp.newt.ScreenImpl; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.Point; - -import com.jogamp.nativewindow.awt.AWTGraphicsDevice; -import com.jogamp.nativewindow.awt.AWTGraphicsScreen; - -public class AWTScreen extends ScreenImpl { - public AWTScreen() { - } - - protected void createNativeImpl() { - aScreen = new AWTGraphicsScreen((AWTGraphicsDevice)display.getGraphicsDevice()); - } - - protected void setAWTGraphicsScreen(AWTGraphicsScreen s) { - aScreen = s; - } - - /** - * Used by AWTWindow .. - */ - @Override - protected void updateVirtualScreenOriginAndSize() { - super.updateVirtualScreenOriginAndSize(); - } - - protected void closeNativeImpl() { } - - protected int validateScreenIndex(int idx) { - return idx; // pass through ... - } - - protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { - final DisplayMode mode = ((AWTGraphicsDevice)getDisplay().getGraphicsDevice()).getGraphicsDevice().getDisplayMode(); - if(null != mode) { - virtualOrigin.setX(0); - virtualOrigin.setY(0); - virtualSize.setWidth(mode.getWidth()); - virtualSize.setHeight(mode.getHeight()); - } - } - -} diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java b/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java deleted file mode 100644 index 2b2fed545..000000000 --- a/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.awt; - -import java.awt.BorderLayout; -import java.awt.Container; -import java.awt.Frame; -import java.awt.Insets; - -import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.util.Point; - -import jogamp.newt.WindowImpl; - -import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration; -import com.jogamp.nativewindow.awt.AWTGraphicsDevice; -import com.jogamp.nativewindow.awt.AWTGraphicsScreen; -import com.jogamp.newt.event.awt.AWTKeyAdapter; -import com.jogamp.newt.event.awt.AWTMouseAdapter; -import com.jogamp.newt.event.awt.AWTWindowAdapter; - -/** An implementation of the Newt Window class built using the - AWT. This is provided for convenience of porting to platforms - supporting Java SE. */ - -public class AWTWindow extends WindowImpl { - - public AWTWindow() { - this(null); - } - - public static Class[] getCustomConstructorArgumentTypes() { - return new Class[] { Container.class } ; - } - - public AWTWindow(Container container) { - super(); - this.container = container; - if(container instanceof Frame) { - frame = (Frame) container; - } - } - - private boolean owningFrame; - private Container container = null; - private Frame frame = null; // same instance as container, just for impl. convenience - private AWTCanvas canvas; - - protected void requestFocusImpl(boolean reparented) { - container.requestFocus(); - } - - @Override - protected void setTitleImpl(final String title) { - if (frame != null) { - frame.setTitle(title); - } - } - - protected void createNativeImpl() { - if(0!=getParentWindowHandle()) { - throw new RuntimeException("Window parenting not supported in AWT, use AWTWindow(Frame) cstr for wrapping instead"); - } - - if(null==container) { - frame = new Frame(); - container = frame; - owningFrame=true; - } else { - owningFrame=false; - defineSize(container.getWidth(), container.getHeight()); - definePosition(container.getX(), container.getY()); - } - if(null!=frame) { - frame.setTitle(getTitle()); - } - container.setLayout(new BorderLayout()); - canvas = new AWTCanvas(capsRequested, AWTWindow.this.capabilitiesChooser); - - addWindowListener(new LocalWindowListener()); - - new AWTMouseAdapter(this).addTo(canvas); // fwd all AWT Mouse events to here - new AWTKeyAdapter(this).addTo(canvas); // fwd all AWT Key events to here - - // canvas.addComponentListener(listener); - container.add(canvas, BorderLayout.CENTER); - container.setSize(getWidth(), getHeight()); - container.setLocation(getX(), getY()); - new AWTWindowAdapter(this).addTo(container); // fwd all AWT Window events to here - - reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureFlags(FLAG_CHANGE_VISIBILITY | FLAG_CHANGE_DECORATION, true)); - // throws exception if failed .. - - setWindowHandle(1); // just a marker .. - } - - protected void closeNativeImpl() { - setWindowHandle(0); // just a marker .. - if(null!=container) { - container.setVisible(false); - container.remove(canvas); - container.setEnabled(false); - canvas.setEnabled(false); - } - if(owningFrame && null!=frame) { - frame.dispose(); - owningFrame=false; - frame = null; - } - } - - @Override - public boolean hasDeviceChanged() { - boolean res = canvas.hasDeviceChanged(); - if(res) { - final AWTGraphicsConfiguration cfg = canvas.getAWTGraphicsConfiguration(); - if (null == cfg) { - throw new NativeWindowException("Error Device change null GraphicsConfiguration: "+this); - } - setGraphicsConfiguration(cfg); - - // propagate new info .. - ((AWTScreen)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)cfg.getScreen()); - ((AWTDisplay)getScreen().getDisplay()).setAWTGraphicsDevice((AWTGraphicsDevice)cfg.getScreen().getDevice()); - - ((AWTScreen)getScreen()).updateVirtualScreenOriginAndSize(); - } - return res; - } - - protected void updateInsetsImpl(javax.media.nativewindow.util.Insets insets) { - Insets contInsets = container.getInsets(); - insets.setLeftWidth(contInsets.left); - insets.setRightWidth(contInsets.right); - insets.setTopHeight(contInsets.top); - insets.setBottomHeight(contInsets.bottom); - } - - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { - if(0 != ( FLAG_CHANGE_DECORATION & flags) && null!=frame) { - if(!container.isDisplayable()) { - frame.setUndecorated(isUndecorated()); - } else { - if(DEBUG_IMPLEMENTATION) { - System.err.println("AWTWindow can't undecorate already created frame"); - } - } - } - - if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { - container.setVisible(0 != ( FLAG_IS_VISIBLE & flags)); - } - - container.setLocation(x, y); - Insets insets = container.getInsets(); - container.setSize(width + insets.left + insets.right, - height + insets.top + insets.bottom); - - if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { - if( 0 != ( FLAG_IS_VISIBLE & flags ) ) { - if( !hasDeviceChanged() ) { - // oops ?? - final AWTGraphicsConfiguration cfg = canvas.getAWTGraphicsConfiguration(); - if(null == cfg) { - throw new NativeWindowException("Error: !hasDeviceChanged && null == GraphicsConfiguration: "+this); - } - setGraphicsConfiguration(cfg); - } - } - visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); - } - - return true; - } - - protected Point getLocationOnScreenImpl(int x, int y) { - java.awt.Point ap = canvas.getLocationOnScreen(); - ap.translate(x, y); - return new Point((int)(ap.getX()+0.5),(int)(ap.getY()+0.5)); - } - - @Override - public Object getWrappedWindow() { - return canvas; - } - - class LocalWindowListener extends com.jogamp.newt.event.WindowAdapter { - @Override - public void windowMoved(com.jogamp.newt.event.WindowEvent e) { - if(null!=container) { - definePosition(container.getX(), container.getY()); - } - } - @Override - public void windowResized(com.jogamp.newt.event.WindowEvent e) { - if(null!=canvas) { - defineSize(canvas.getWidth(), canvas.getHeight()); - } - } - } -} diff --git a/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java new file mode 100644 index 000000000..39d96585b --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.awt; + +import com.jogamp.nativewindow.awt.AWTGraphicsDevice; +import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.util.EDTUtil; + +import jogamp.newt.DisplayImpl; + +public class DisplayDriver extends DisplayImpl { + public DisplayDriver() { + } + + protected void createNativeImpl() { + aDevice = AWTGraphicsDevice.createDefault(); + } + + protected void setAWTGraphicsDevice(AWTGraphicsDevice d) { + aDevice = d; + } + + protected void closeNativeImpl() { } + + @Override + protected EDTUtil createEDTUtil() { + final EDTUtil def; + if(NewtFactory.useEDT()) { + def = AWTEDTUtil.getSingleton(); + if(DEBUG) { + System.err.println("AWTDisplay.createNative("+getFQName()+") Create EDTUtil: "+def.getClass().getName()); + } + } else { + def = null; + } + return def; + } + + protected void dispatchMessagesNative() { /* nop */ } +} + diff --git a/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java new file mode 100644 index 000000000..6b1283a00 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.awt; + +import java.awt.DisplayMode; + +import jogamp.newt.ScreenImpl; +import javax.media.nativewindow.util.Dimension; +import javax.media.nativewindow.util.Point; + +import com.jogamp.nativewindow.awt.AWTGraphicsDevice; +import com.jogamp.nativewindow.awt.AWTGraphicsScreen; + +public class ScreenDriver extends ScreenImpl { + public ScreenDriver() { + } + + protected void createNativeImpl() { + aScreen = new AWTGraphicsScreen((AWTGraphicsDevice)display.getGraphicsDevice()); + } + + protected void setAWTGraphicsScreen(AWTGraphicsScreen s) { + aScreen = s; + } + + /** + * Used by AWTWindow .. + */ + @Override + protected void updateVirtualScreenOriginAndSize() { + super.updateVirtualScreenOriginAndSize(); + } + + protected void closeNativeImpl() { } + + protected int validateScreenIndex(int idx) { + return idx; // pass through ... + } + + protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { + final DisplayMode mode = ((AWTGraphicsDevice)getDisplay().getGraphicsDevice()).getGraphicsDevice().getDisplayMode(); + if(null != mode) { + virtualOrigin.setX(0); + virtualOrigin.setY(0); + virtualSize.setWidth(mode.getWidth()); + virtualSize.setHeight(mode.getHeight()); + } + } + +} diff --git a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java new file mode 100644 index 000000000..1723ffee5 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.awt; + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Frame; +import java.awt.Insets; + +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.util.Point; + +import jogamp.newt.WindowImpl; + +import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration; +import com.jogamp.nativewindow.awt.AWTGraphicsDevice; +import com.jogamp.nativewindow.awt.AWTGraphicsScreen; +import com.jogamp.newt.event.awt.AWTKeyAdapter; +import com.jogamp.newt.event.awt.AWTMouseAdapter; +import com.jogamp.newt.event.awt.AWTWindowAdapter; + +/** An implementation of the Newt Window class built using the + AWT. This is provided for convenience of porting to platforms + supporting Java SE. */ + +public class WindowDriver extends WindowImpl { + + public WindowDriver() { + this(null); + } + + public static Class[] getCustomConstructorArgumentTypes() { + return new Class[] { Container.class } ; + } + + public WindowDriver(Container container) { + super(); + this.container = container; + if(container instanceof Frame) { + frame = (Frame) container; + } + } + + private boolean owningFrame; + private Container container = null; + private Frame frame = null; // same instance as container, just for impl. convenience + private AWTCanvas canvas; + + protected void requestFocusImpl(boolean reparented) { + container.requestFocus(); + } + + @Override + protected void setTitleImpl(final String title) { + if (frame != null) { + frame.setTitle(title); + } + } + + protected void createNativeImpl() { + if(0!=getParentWindowHandle()) { + throw new RuntimeException("Window parenting not supported in AWT, use AWTWindow(Frame) cstr for wrapping instead"); + } + + if(null==container) { + frame = new Frame(); + container = frame; + owningFrame=true; + } else { + owningFrame=false; + defineSize(container.getWidth(), container.getHeight()); + definePosition(container.getX(), container.getY()); + } + if(null!=frame) { + frame.setTitle(getTitle()); + } + container.setLayout(new BorderLayout()); + canvas = new AWTCanvas(capsRequested, WindowDriver.this.capabilitiesChooser); + + addWindowListener(new LocalWindowListener()); + + new AWTMouseAdapter(this).addTo(canvas); // fwd all AWT Mouse events to here + new AWTKeyAdapter(this).addTo(canvas); // fwd all AWT Key events to here + + // canvas.addComponentListener(listener); + container.add(canvas, BorderLayout.CENTER); + container.setSize(getWidth(), getHeight()); + container.setLocation(getX(), getY()); + new AWTWindowAdapter(this).addTo(container); // fwd all AWT Window events to here + + reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureFlags(FLAG_CHANGE_VISIBILITY | FLAG_CHANGE_DECORATION, true)); + // throws exception if failed .. + + setWindowHandle(1); // just a marker .. + } + + protected void closeNativeImpl() { + setWindowHandle(0); // just a marker .. + if(null!=container) { + container.setVisible(false); + container.remove(canvas); + container.setEnabled(false); + canvas.setEnabled(false); + } + if(owningFrame && null!=frame) { + frame.dispose(); + owningFrame=false; + frame = null; + } + } + + @Override + public boolean hasDeviceChanged() { + boolean res = canvas.hasDeviceChanged(); + if(res) { + final AWTGraphicsConfiguration cfg = canvas.getAWTGraphicsConfiguration(); + if (null == cfg) { + throw new NativeWindowException("Error Device change null GraphicsConfiguration: "+this); + } + setGraphicsConfiguration(cfg); + + // propagate new info .. + ((ScreenDriver)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)cfg.getScreen()); + ((DisplayDriver)getScreen().getDisplay()).setAWTGraphicsDevice((AWTGraphicsDevice)cfg.getScreen().getDevice()); + + ((ScreenDriver)getScreen()).updateVirtualScreenOriginAndSize(); + } + return res; + } + + protected void updateInsetsImpl(javax.media.nativewindow.util.Insets insets) { + Insets contInsets = container.getInsets(); + insets.setLeftWidth(contInsets.left); + insets.setRightWidth(contInsets.right); + insets.setTopHeight(contInsets.top); + insets.setBottomHeight(contInsets.bottom); + } + + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + if(0 != ( FLAG_CHANGE_DECORATION & flags) && null!=frame) { + if(!container.isDisplayable()) { + frame.setUndecorated(isUndecorated()); + } else { + if(DEBUG_IMPLEMENTATION) { + System.err.println("AWTWindow can't undecorate already created frame"); + } + } + } + + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + container.setVisible(0 != ( FLAG_IS_VISIBLE & flags)); + } + + container.setLocation(x, y); + Insets insets = container.getInsets(); + container.setSize(width + insets.left + insets.right, + height + insets.top + insets.bottom); + + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + if( 0 != ( FLAG_IS_VISIBLE & flags ) ) { + if( !hasDeviceChanged() ) { + // oops ?? + final AWTGraphicsConfiguration cfg = canvas.getAWTGraphicsConfiguration(); + if(null == cfg) { + throw new NativeWindowException("Error: !hasDeviceChanged && null == GraphicsConfiguration: "+this); + } + setGraphicsConfiguration(cfg); + } + } + visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); + } + + return true; + } + + protected Point getLocationOnScreenImpl(int x, int y) { + java.awt.Point ap = canvas.getLocationOnScreen(); + ap.translate(x, y); + return new Point((int)(ap.getX()+0.5),(int)(ap.getY()+0.5)); + } + + @Override + public Object getWrappedWindow() { + return canvas; + } + + class LocalWindowListener extends com.jogamp.newt.event.WindowAdapter { + @Override + public void windowMoved(com.jogamp.newt.event.WindowEvent e) { + if(null!=container) { + definePosition(container.getX(), container.getY()); + } + } + @Override + public void windowResized(com.jogamp.newt.event.WindowEvent e) { + if(null!=canvas) { + defineSize(canvas.getWidth(), canvas.getHeight()); + } + } + } +} diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/Display.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/Display.java deleted file mode 100644 index f08890da6..000000000 --- a/src/newt/classes/jogamp/newt/driver/bcm/egl/Display.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2012 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.bcm.egl; - -import javax.media.nativewindow.AbstractGraphicsDevice; -import javax.media.nativewindow.NativeWindowException; - -import jogamp.newt.NEWTJNILibLoader; -import jogamp.opengl.egl.EGL; - -import com.jogamp.nativewindow.egl.EGLGraphicsDevice; - -public class Display extends jogamp.newt.DisplayImpl { - - static { - NEWTJNILibLoader.loadNEWT(); - - if (!Window.initIDs()) { - throw new NativeWindowException("Failed to initialize BCEGL Window jmethodIDs"); - } - } - - public static void initSingleton() { - // just exist to ensure static init has been run - } - - - public Display() { - } - - protected void createNativeImpl() { - final long handle = CreateDisplay(Screen.fixedWidth, Screen.fixedHeight); - if (handle == EGL.EGL_NO_DISPLAY) { - throw new NativeWindowException("BC EGL CreateDisplay failed"); - } - aDevice = new EGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, handle, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT, null); - } - - protected void closeNativeImpl() { - if (aDevice.getHandle() != EGL.EGL_NO_DISPLAY) { - DestroyDisplay(aDevice.getHandle()); - } - } - - protected void dispatchMessagesNative() { - // n/a .. DispatchMessages(); - } - - private native long CreateDisplay(int width, int height); - private native void DestroyDisplay(long dpy); - private native void DispatchMessages(); -} - diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java new file mode 100644 index 000000000..65ca63eec --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.bcm.egl; + +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.NativeWindowException; + +import jogamp.newt.NEWTJNILibLoader; +import jogamp.opengl.egl.EGL; + +import com.jogamp.nativewindow.egl.EGLGraphicsDevice; + +public class DisplayDriver extends jogamp.newt.DisplayImpl { + + static { + NEWTJNILibLoader.loadNEWT(); + + if (!WindowDriver.initIDs()) { + throw new NativeWindowException("Failed to initialize BCEGL Window jmethodIDs"); + } + } + + public static void initSingleton() { + // just exist to ensure static init has been run + } + + + public DisplayDriver() { + } + + protected void createNativeImpl() { + final long handle = CreateDisplay(ScreenDriver.fixedWidth, ScreenDriver.fixedHeight); + if (handle == EGL.EGL_NO_DISPLAY) { + throw new NativeWindowException("BC EGL CreateDisplay failed"); + } + aDevice = new EGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, handle, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT, null); + } + + protected void closeNativeImpl() { + if (aDevice.getHandle() != EGL.EGL_NO_DISPLAY) { + DestroyDisplay(aDevice.getHandle()); + } + } + + protected void dispatchMessagesNative() { + // n/a .. DispatchMessages(); + } + + private native long CreateDisplay(int width, int height); + private native void DestroyDisplay(long dpy); + private native void DispatchMessages(); +} + diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/Screen.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/Screen.java deleted file mode 100644 index 909444d24..000000000 --- a/src/newt/classes/jogamp/newt/driver/bcm/egl/Screen.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2012 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.bcm.egl; - -import javax.media.nativewindow.DefaultGraphicsScreen; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.Point; - -public class Screen extends jogamp.newt.ScreenImpl { - - static { - Display.initSingleton(); - } - - - public Screen() { - } - - protected void createNativeImpl() { - aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx); - } - - protected void closeNativeImpl() { } - - protected int validateScreenIndex(int idx) { - return 0; // only one screen available - } - - protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { - virtualOrigin.setX(0); - virtualOrigin.setY(0); - virtualSize.setWidth(fixedWidth); // FIXME - virtualSize.setHeight(fixedHeight); // FIXME - } - - //---------------------------------------------------------------------- - // Internals only - // - - static final int fixedWidth = 1920; // FIXME - static final int fixedHeight = 1080; // FIXME -} - diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java new file mode 100644 index 000000000..deb2a534b --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.bcm.egl; + +import javax.media.nativewindow.DefaultGraphicsScreen; +import javax.media.nativewindow.util.Dimension; +import javax.media.nativewindow.util.Point; + +public class ScreenDriver extends jogamp.newt.ScreenImpl { + + static { + DisplayDriver.initSingleton(); + } + + + public ScreenDriver() { + } + + protected void createNativeImpl() { + aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx); + } + + protected void closeNativeImpl() { } + + protected int validateScreenIndex(int idx) { + return 0; // only one screen available + } + + protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { + virtualOrigin.setX(0); + virtualOrigin.setY(0); + virtualSize.setWidth(fixedWidth); // FIXME + virtualSize.setHeight(fixedHeight); // FIXME + } + + //---------------------------------------------------------------------- + // Internals only + // + + static final int fixedWidth = 1920; // FIXME + static final int fixedHeight = 1080; // FIXME +} + diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/Window.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/Window.java deleted file mode 100644 index 87170e4ab..000000000 --- a/src/newt/classes/jogamp/newt/driver/bcm/egl/Window.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2012 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.bcm.egl; - -import javax.media.nativewindow.AbstractGraphicsConfiguration; -import javax.media.nativewindow.GraphicsConfigurationFactory; -import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.VisualIDHolder; -import javax.media.nativewindow.util.Insets; -import javax.media.nativewindow.util.Point; -import javax.media.opengl.GLCapabilitiesImmutable; - -import jogamp.opengl.egl.EGLGraphicsConfiguration; - -public class Window extends jogamp.newt.WindowImpl { - static { - Display.initSingleton(); - } - - public Window() { - } - - protected void createNativeImpl() { - if(0!=getParentWindowHandle()) { - throw new RuntimeException("Window parenting not supported (yet)"); - } - // query a good configuration, however chose the final one by the native queried egl-cfg-id - // after creation at {@link #windowCreated(int, int, int)}. - final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration( - capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED); - if (null == cfg) { - throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); - } - setGraphicsConfiguration(cfg); - setSizeImpl(getScreen().getWidth(), getScreen().getHeight()); - - setWindowHandle(realizeWindow(true, getWidth(), getHeight())); - if (0 == getWindowHandle()) { - throw new NativeWindowException("Error native Window Handle is null"); - } - } - - protected void closeNativeImpl() { - if(0!=windowHandleClose) { - CloseWindow(getDisplayHandle(), windowHandleClose); - } - } - - protected void requestFocusImpl(boolean reparented) { } - - protected void setSizeImpl(int width, int height) { - if(0!=getWindowHandle()) { - // n/a in BroadcomEGL - System.err.println("BCEGL Window.setSizeImpl n/a in BroadcomEGL with realized window"); - } else { - defineSize(width, height); - } - } - - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { - if(0!=getWindowHandle()) { - if(0 != ( FLAG_CHANGE_FULLSCREEN & flags)) { - if( 0 != ( FLAG_IS_FULLSCREEN & flags) ) { - // n/a in BroadcomEGL - System.err.println("setFullscreen n/a in BroadcomEGL"); - return false; - } - } - } - if(width>0 || height>0) { - if(0!=getWindowHandle()) { - // n/a in BroadcomEGL - System.err.println("BCEGL Window.setSizeImpl n/a in BroadcomEGL with realized window"); - } else { - defineSize((width>0)?width:getWidth(), (height>0)?height:getHeight()); - } - } - if(x>=0 || y>=0) { - System.err.println("BCEGL Window.setPositionImpl n/a in BroadcomEGL"); - } - - if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { - visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); - } - return true; - } - - protected Point getLocationOnScreenImpl(int x, int y) { - return new Point(x,y); - } - - protected void updateInsetsImpl(Insets insets) { - // nop .. - } - - @Override - public boolean surfaceSwap() { - SwapWindow(getDisplayHandle(), getWindowHandle()); - return true; - } - - //---------------------------------------------------------------------- - // Internals only - // - - protected static native boolean initIDs(); - private native long CreateWindow(long eglDisplayHandle, boolean chromaKey, int width, int height); - private native void CloseWindow(long eglDisplayHandle, long eglWindowHandle); - private native void SwapWindow(long eglDisplayHandle, long eglWindowHandle); - - - private long realizeWindow(boolean chromaKey, int width, int height) { - if(DEBUG_IMPLEMENTATION) { - System.err.println("BCEGL Window.realizeWindow() with: chroma "+chromaKey+", "+width+"x"+height+", "+getGraphicsConfiguration()); - } - long handle = CreateWindow(getDisplayHandle(), chromaKey, width, height); - if (0 == handle) { - throw new NativeWindowException("Error native Window Handle is null"); - } - windowHandleClose = handle; - return handle; - } - - private void windowCreated(int cfgID, int width, int height) { - defineSize(width, height); - GLCapabilitiesImmutable capsReq = (GLCapabilitiesImmutable) getGraphicsConfiguration().getRequestedCapabilities(); - final AbstractGraphicsConfiguration cfg = EGLGraphicsConfiguration.create(capsReq, getScreen().getGraphicsScreen(), cfgID); - if (null == cfg) { - throw new NativeWindowException("Error creating EGLGraphicsConfiguration from id: "+cfgID+", "+this); - } - setGraphicsConfiguration(cfg); - if(DEBUG_IMPLEMENTATION) { - System.err.println("BCEGL Window.windowCreated(): "+toHexString(cfgID)+", "+width+"x"+height+", "+cfg); - } - } - - private long windowHandleClose; -} diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/WindowDriver.java new file mode 100644 index 000000000..49d3d98ba --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/WindowDriver.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.bcm.egl; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.GraphicsConfigurationFactory; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.VisualIDHolder; +import javax.media.nativewindow.util.Insets; +import javax.media.nativewindow.util.Point; +import javax.media.opengl.GLCapabilitiesImmutable; + +import jogamp.opengl.egl.EGLGraphicsConfiguration; + +public class WindowDriver extends jogamp.newt.WindowImpl { + static { + DisplayDriver.initSingleton(); + } + + public WindowDriver() { + } + + protected void createNativeImpl() { + if(0!=getParentWindowHandle()) { + throw new RuntimeException("Window parenting not supported (yet)"); + } + // query a good configuration, however chose the final one by the native queried egl-cfg-id + // after creation at {@link #windowCreated(int, int, int)}. + final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration( + capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED); + if (null == cfg) { + throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); + } + setGraphicsConfiguration(cfg); + setSizeImpl(getScreen().getWidth(), getScreen().getHeight()); + + setWindowHandle(realizeWindow(true, getWidth(), getHeight())); + if (0 == getWindowHandle()) { + throw new NativeWindowException("Error native Window Handle is null"); + } + } + + protected void closeNativeImpl() { + if(0!=windowHandleClose) { + CloseWindow(getDisplayHandle(), windowHandleClose); + } + } + + protected void requestFocusImpl(boolean reparented) { } + + protected void setSizeImpl(int width, int height) { + if(0!=getWindowHandle()) { + // n/a in BroadcomEGL + System.err.println("BCEGL Window.setSizeImpl n/a in BroadcomEGL with realized window"); + } else { + defineSize(width, height); + } + } + + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + if(0!=getWindowHandle()) { + if(0 != ( FLAG_CHANGE_FULLSCREEN & flags)) { + if( 0 != ( FLAG_IS_FULLSCREEN & flags) ) { + // n/a in BroadcomEGL + System.err.println("setFullscreen n/a in BroadcomEGL"); + return false; + } + } + } + if(width>0 || height>0) { + if(0!=getWindowHandle()) { + // n/a in BroadcomEGL + System.err.println("BCEGL Window.setSizeImpl n/a in BroadcomEGL with realized window"); + } else { + defineSize((width>0)?width:getWidth(), (height>0)?height:getHeight()); + } + } + if(x>=0 || y>=0) { + System.err.println("BCEGL Window.setPositionImpl n/a in BroadcomEGL"); + } + + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); + } + return true; + } + + protected Point getLocationOnScreenImpl(int x, int y) { + return new Point(x,y); + } + + protected void updateInsetsImpl(Insets insets) { + // nop .. + } + + @Override + public boolean surfaceSwap() { + SwapWindow(getDisplayHandle(), getWindowHandle()); + return true; + } + + //---------------------------------------------------------------------- + // Internals only + // + + protected static native boolean initIDs(); + private native long CreateWindow(long eglDisplayHandle, boolean chromaKey, int width, int height); + private native void CloseWindow(long eglDisplayHandle, long eglWindowHandle); + private native void SwapWindow(long eglDisplayHandle, long eglWindowHandle); + + + private long realizeWindow(boolean chromaKey, int width, int height) { + if(DEBUG_IMPLEMENTATION) { + System.err.println("BCEGL Window.realizeWindow() with: chroma "+chromaKey+", "+width+"x"+height+", "+getGraphicsConfiguration()); + } + long handle = CreateWindow(getDisplayHandle(), chromaKey, width, height); + if (0 == handle) { + throw new NativeWindowException("Error native Window Handle is null"); + } + windowHandleClose = handle; + return handle; + } + + private void windowCreated(int cfgID, int width, int height) { + defineSize(width, height); + GLCapabilitiesImmutable capsReq = (GLCapabilitiesImmutable) getGraphicsConfiguration().getRequestedCapabilities(); + final AbstractGraphicsConfiguration cfg = EGLGraphicsConfiguration.create(capsReq, getScreen().getGraphicsScreen(), cfgID); + if (null == cfg) { + throw new NativeWindowException("Error creating EGLGraphicsConfiguration from id: "+cfgID+", "+this); + } + setGraphicsConfiguration(cfg); + if(DEBUG_IMPLEMENTATION) { + System.err.println("BCEGL Window.windowCreated(): "+toHexString(cfgID)+", "+width+"x"+height+", "+cfg); + } + } + + private long windowHandleClose; +} diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/Display.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/Display.java deleted file mode 100644 index 62af02abb..000000000 --- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/Display.java +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Copyright 2012 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ - -package jogamp.newt.driver.bcm.vc.iv; - -import javax.media.nativewindow.AbstractGraphicsDevice; -import javax.media.nativewindow.NativeWindowException; - -import jogamp.newt.DisplayImpl; -import jogamp.newt.NEWTJNILibLoader; -import jogamp.opengl.egl.EGL; -import jogamp.opengl.egl.EGLDisplayUtil; - -public class Display extends DisplayImpl { - static { - NEWTJNILibLoader.loadNEWT(); - - if (!Display.initIDs()) { - throw new NativeWindowException("Failed to initialize bcm.vc.iv Display jmethodIDs"); - } - if (!Screen.initIDs()) { - throw new NativeWindowException("Failed to initialize bcm.vc.iv Screen jmethodIDs"); - } - if (!Window.initIDs()) { - throw new NativeWindowException("Failed to initialize bcm.vc.iv Window jmethodIDs"); - } - } - - public static void initSingleton() { - // just exist to ensure static init has been run - } - - - public Display() { - } - - protected void createNativeImpl() { - // FIXME: map name to EGL_*_DISPLAY - aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); - } - - protected void closeNativeImpl() { - aDevice.close(); - } - - protected void dispatchMessagesNative() { - DispatchMessages(); - } - - protected static native boolean initIDs(); - private native void DispatchMessages(); -} - diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java new file mode 100644 index 000000000..08c5c573c --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java @@ -0,0 +1,78 @@ +/** + * Copyright 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.newt.driver.bcm.vc.iv; + +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.NativeWindowException; + +import jogamp.newt.DisplayImpl; +import jogamp.newt.NEWTJNILibLoader; +import jogamp.opengl.egl.EGL; +import jogamp.opengl.egl.EGLDisplayUtil; + +public class DisplayDriver extends DisplayImpl { + static { + NEWTJNILibLoader.loadNEWT(); + + if (!DisplayDriver.initIDs()) { + throw new NativeWindowException("Failed to initialize bcm.vc.iv Display jmethodIDs"); + } + if (!ScreenDriver.initIDs()) { + throw new NativeWindowException("Failed to initialize bcm.vc.iv Screen jmethodIDs"); + } + if (!WindowDriver.initIDs()) { + throw new NativeWindowException("Failed to initialize bcm.vc.iv Window jmethodIDs"); + } + } + + public static void initSingleton() { + // just exist to ensure static init has been run + } + + + public DisplayDriver() { + } + + protected void createNativeImpl() { + // FIXME: map name to EGL_*_DISPLAY + aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); + } + + protected void closeNativeImpl() { + aDevice.close(); + } + + protected void dispatchMessagesNative() { + DispatchMessages(); + } + + protected static native boolean initIDs(); + private native void DispatchMessages(); +} + diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/Screen.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/Screen.java deleted file mode 100644 index 484d4bf81..000000000 --- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/Screen.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright 2012 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ - -package jogamp.newt.driver.bcm.vc.iv; - -import javax.media.nativewindow.DefaultGraphicsScreen; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.Point; - -import jogamp.newt.ScreenImpl; - -public class Screen extends ScreenImpl { - static { - Display.initSingleton(); - } - - public Screen() { - } - - protected void createNativeImpl() { - aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx); - initNative(); - } - - protected void closeNativeImpl() { } - - protected int validateScreenIndex(int idx) { - return 0; // only one screen available - } - - protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { - virtualOrigin.setX(0); - virtualOrigin.setY(0); - virtualSize.setWidth(cachedWidth); - virtualSize.setHeight(cachedHeight); - } - - protected void setScreenSize(int width, int height) { - cachedWidth = width; - cachedHeight = height; - } - - private static int cachedWidth = 0; - private static int cachedHeight = 0; - - protected static native boolean initIDs(); - protected native void initNative(); -} diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java new file mode 100644 index 000000000..787d1a1b4 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java @@ -0,0 +1,73 @@ +/** + * Copyright 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.newt.driver.bcm.vc.iv; + +import javax.media.nativewindow.DefaultGraphicsScreen; +import javax.media.nativewindow.util.Dimension; +import javax.media.nativewindow.util.Point; + +import jogamp.newt.ScreenImpl; + +public class ScreenDriver extends ScreenImpl { + static { + DisplayDriver.initSingleton(); + } + + public ScreenDriver() { + } + + protected void createNativeImpl() { + aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx); + initNative(); + } + + protected void closeNativeImpl() { } + + protected int validateScreenIndex(int idx) { + return 0; // only one screen available + } + + protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { + virtualOrigin.setX(0); + virtualOrigin.setY(0); + virtualSize.setWidth(cachedWidth); + virtualSize.setHeight(cachedHeight); + } + + protected void setScreenSize(int width, int height) { + cachedWidth = width; + cachedHeight = height; + } + + private static int cachedWidth = 0; + private static int cachedHeight = 0; + + protected static native boolean initIDs(); + protected native void initNative(); +} diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/Window.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/Window.java deleted file mode 100644 index 3d00949de..000000000 --- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/Window.java +++ /dev/null @@ -1,149 +0,0 @@ -/** - * Copyright 2012 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ - -package jogamp.newt.driver.bcm.vc.iv; - -import javax.media.nativewindow.AbstractGraphicsConfiguration; -import javax.media.nativewindow.GraphicsConfigurationFactory; -import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.VisualIDHolder; -import javax.media.nativewindow.util.Insets; -import javax.media.nativewindow.util.Point; - -import jogamp.newt.WindowImpl; -import jogamp.newt.driver.linux.LinuxMouseTracker; - -public class Window extends WindowImpl { - private static final String WINDOW_CLASS_NAME = "NewtWindow"; - - static { - Display.initSingleton(); - } - - public Window() { - } - - protected void createNativeImpl() { - if(0!=getParentWindowHandle()) { - throw new RuntimeException("Window parenting not supported (yet)"); - } - final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration( - capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED); - if (null == cfg) { - throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); - } - setGraphicsConfiguration(cfg); - - nativeWindowHandle = CreateWindow(getWidth(), getHeight()); - if (nativeWindowHandle == 0) { - throw new NativeWindowException("Error creating egl window: "+cfg); - } - setVisible0(nativeWindowHandle, false); - setWindowHandle(nativeWindowHandle); - if (0 == getWindowHandle()) { - throw new NativeWindowException("Error native Window Handle is null"); - } - windowHandleClose = nativeWindowHandle; - addWindowListener(LinuxMouseTracker.getSingleton()); - focusChanged(false, true); - } - - protected void closeNativeImpl() { - removeWindowListener(LinuxMouseTracker.getSingleton()); - - if(0!=windowHandleClose) { - CloseWindow(windowHandleClose, windowUserData); - windowUserData=0; - } - } - - protected void requestFocusImpl(boolean reparented) { - focusChanged(false, true); - } - - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { - if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { - setVisible0(nativeWindowHandle, 0 != ( FLAG_IS_VISIBLE & flags)); - visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); - } - - if(0!=nativeWindowHandle) { - if(0 != ( FLAG_CHANGE_FULLSCREEN & flags)) { - final boolean fs = 0 != ( FLAG_IS_FULLSCREEN & flags) ; - setFullScreen0(nativeWindowHandle, fs); - if(fs) { - return true; - } - } - // int _x=(x>=0)?x:this.x; - // int _y=(x>=0)?y:this.y; - width=(width>0)?width:getWidth(); - height=(height>0)?height:getHeight(); - if(width>0 || height>0) { - setSize0(nativeWindowHandle, width, height); - } - if(x>=0 || y>=0) { - System.err.println("setPosition n/a in KD"); - } - } - - if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { - visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); - } - - return true; - } - - protected Point getLocationOnScreenImpl(int x, int y) { - return new Point(x,y); - } - - protected void updateInsetsImpl(Insets insets) { - // nop .. - } - - //---------------------------------------------------------------------- - // Internals only - // - - protected static native boolean initIDs(); - private native long CreateWindow(int width, int height); - private native long RealizeWindow(long eglWindowHandle); - private native int CloseWindow(long eglWindowHandle, long userData); - private native void setVisible0(long eglWindowHandle, boolean visible); - private native void setSize0(long eglWindowHandle, int width, int height); - private native void setFullScreen0(long eglWindowHandle, boolean fullscreen); - - private void windowCreated(long userData) { - windowUserData=userData; - } - - private long nativeWindowHandle; - private long windowHandleClose; - private long windowUserData; -} diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java new file mode 100644 index 000000000..6d4f36964 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java @@ -0,0 +1,149 @@ +/** + * Copyright 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.newt.driver.bcm.vc.iv; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.GraphicsConfigurationFactory; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.VisualIDHolder; +import javax.media.nativewindow.util.Insets; +import javax.media.nativewindow.util.Point; + +import jogamp.newt.WindowImpl; +import jogamp.newt.driver.linux.LinuxMouseTracker; + +public class WindowDriver extends WindowImpl { + private static final String WINDOW_CLASS_NAME = "NewtWindow"; + + static { + DisplayDriver.initSingleton(); + } + + public WindowDriver() { + } + + protected void createNativeImpl() { + if(0!=getParentWindowHandle()) { + throw new RuntimeException("Window parenting not supported (yet)"); + } + final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration( + capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED); + if (null == cfg) { + throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); + } + setGraphicsConfiguration(cfg); + + nativeWindowHandle = CreateWindow(getWidth(), getHeight()); + if (nativeWindowHandle == 0) { + throw new NativeWindowException("Error creating egl window: "+cfg); + } + setVisible0(nativeWindowHandle, false); + setWindowHandle(nativeWindowHandle); + if (0 == getWindowHandle()) { + throw new NativeWindowException("Error native Window Handle is null"); + } + windowHandleClose = nativeWindowHandle; + addWindowListener(LinuxMouseTracker.getSingleton()); + focusChanged(false, true); + } + + protected void closeNativeImpl() { + removeWindowListener(LinuxMouseTracker.getSingleton()); + + if(0!=windowHandleClose) { + CloseWindow(windowHandleClose, windowUserData); + windowUserData=0; + } + } + + protected void requestFocusImpl(boolean reparented) { + focusChanged(false, true); + } + + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + setVisible0(nativeWindowHandle, 0 != ( FLAG_IS_VISIBLE & flags)); + visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); + } + + if(0!=nativeWindowHandle) { + if(0 != ( FLAG_CHANGE_FULLSCREEN & flags)) { + final boolean fs = 0 != ( FLAG_IS_FULLSCREEN & flags) ; + setFullScreen0(nativeWindowHandle, fs); + if(fs) { + return true; + } + } + // int _x=(x>=0)?x:this.x; + // int _y=(x>=0)?y:this.y; + width=(width>0)?width:getWidth(); + height=(height>0)?height:getHeight(); + if(width>0 || height>0) { + setSize0(nativeWindowHandle, width, height); + } + if(x>=0 || y>=0) { + System.err.println("setPosition n/a in KD"); + } + } + + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); + } + + return true; + } + + protected Point getLocationOnScreenImpl(int x, int y) { + return new Point(x,y); + } + + protected void updateInsetsImpl(Insets insets) { + // nop .. + } + + //---------------------------------------------------------------------- + // Internals only + // + + protected static native boolean initIDs(); + private native long CreateWindow(int width, int height); + private native long RealizeWindow(long eglWindowHandle); + private native int CloseWindow(long eglWindowHandle, long userData); + private native void setVisible0(long eglWindowHandle, boolean visible); + private native void setSize0(long eglWindowHandle, int width, int height); + private native void setFullScreen0(long eglWindowHandle, boolean fullscreen); + + private void windowCreated(long userData) { + windowUserData=userData; + } + + private long nativeWindowHandle; + private long windowHandleClose; + private long windowUserData; +} diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/Display.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/Display.java deleted file mode 100644 index 20e151eb3..000000000 --- a/src/newt/classes/jogamp/newt/driver/intel/gdl/Display.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.intel.gdl; - -import jogamp.newt.*; -import javax.media.nativewindow.*; - -public class Display extends jogamp.newt.DisplayImpl { - static int initCounter = 0; - - static { - NEWTJNILibLoader.loadNEWT(); - - if (!Screen.initIDs()) { - throw new NativeWindowException("Failed to initialize GDL Screen jmethodIDs"); - } - if (!Window.initIDs()) { - throw new NativeWindowException("Failed to initialize GDL Window jmethodIDs"); - } - } - - public static void initSingleton() { - // just exist to ensure static init has been run - } - - - public Display() { - } - - protected void createNativeImpl() { - synchronized(Display.class) { - if(0==initCounter) { - displayHandle = CreateDisplay(); - if(0==displayHandle) { - throw new NativeWindowException("Couldn't initialize GDL Display"); - } - } - initCounter++; - } - aDevice = new DefaultGraphicsDevice(NativeWindowFactory.TYPE_DEFAULT, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT, displayHandle); - } - - protected void closeNativeImpl() { - if(0==displayHandle) { - throw new NativeWindowException("displayHandle null; initCnt "+initCounter); - } - synchronized(Display.class) { - if(initCounter>0) { - initCounter--; - if(0==initCounter) { - DestroyDisplay(displayHandle); - } - } - } - } - - protected void dispatchMessagesNative() { - if(0!=displayHandle) { - DispatchMessages(displayHandle, focusedWindow); - } - } - - protected void setFocus(Window focus) { - focusedWindow = focus; - } - - private long displayHandle = 0; - private Window focusedWindow = null; - private native long CreateDisplay(); - private native void DestroyDisplay(long displayHandle); - private native void DispatchMessages(long displayHandle, Window focusedWindow); -} - diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java new file mode 100644 index 000000000..97c384d33 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.intel.gdl; + +import jogamp.newt.*; +import javax.media.nativewindow.*; + +public class DisplayDriver extends jogamp.newt.DisplayImpl { + static int initCounter = 0; + + static { + NEWTJNILibLoader.loadNEWT(); + + if (!ScreenDriver.initIDs()) { + throw new NativeWindowException("Failed to initialize GDL Screen jmethodIDs"); + } + if (!WindowDriver.initIDs()) { + throw new NativeWindowException("Failed to initialize GDL Window jmethodIDs"); + } + } + + public static void initSingleton() { + // just exist to ensure static init has been run + } + + + public DisplayDriver() { + } + + protected void createNativeImpl() { + synchronized(DisplayDriver.class) { + if(0==initCounter) { + displayHandle = CreateDisplay(); + if(0==displayHandle) { + throw new NativeWindowException("Couldn't initialize GDL Display"); + } + } + initCounter++; + } + aDevice = new DefaultGraphicsDevice(NativeWindowFactory.TYPE_DEFAULT, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT, displayHandle); + } + + protected void closeNativeImpl() { + if(0==displayHandle) { + throw new NativeWindowException("displayHandle null; initCnt "+initCounter); + } + synchronized(DisplayDriver.class) { + if(initCounter>0) { + initCounter--; + if(0==initCounter) { + DestroyDisplay(displayHandle); + } + } + } + } + + protected void dispatchMessagesNative() { + if(0!=displayHandle) { + DispatchMessages(displayHandle, focusedWindow); + } + } + + protected void setFocus(WindowDriver focus) { + focusedWindow = focus; + } + + private long displayHandle = 0; + private WindowDriver focusedWindow = null; + private native long CreateDisplay(); + private native void DestroyDisplay(long displayHandle); + private native void DispatchMessages(long displayHandle, WindowDriver focusedWindow); +} + diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java deleted file mode 100644 index 66ad1c691..000000000 --- a/src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.intel.gdl; - -import javax.media.nativewindow.AbstractGraphicsDevice; -import javax.media.nativewindow.DefaultGraphicsScreen; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.Point; - -public class Screen extends jogamp.newt.ScreenImpl { - - static { - Display.initSingleton(); - } - - public Screen() { - } - - protected void createNativeImpl() { - AbstractGraphicsDevice adevice = getDisplay().getGraphicsDevice(); - GetScreenInfo(adevice.getHandle(), screen_idx); - aScreen = new DefaultGraphicsScreen(adevice, screen_idx); - } - - protected void closeNativeImpl() { } - - protected int validateScreenIndex(int idx) { - return 0; // only one screen available - } - - protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { - virtualOrigin.setX(0); - virtualOrigin.setY(0); - virtualSize.setWidth(cachedWidth); - virtualSize.setHeight(cachedHeight); - } - - //---------------------------------------------------------------------- - // Internals only - // - - protected static native boolean initIDs(); - private native void GetScreenInfo(long displayHandle, int screen_idx); - - // called by GetScreenInfo() .. - private void screenCreated(int width, int height) { - cachedWidth = width; - cachedHeight = height; - } - - private static int cachedWidth = 0; - private static int cachedHeight = 0; -} - diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java new file mode 100644 index 000000000..8eed14dde --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.intel.gdl; + +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.DefaultGraphicsScreen; +import javax.media.nativewindow.util.Dimension; +import javax.media.nativewindow.util.Point; + +public class ScreenDriver extends jogamp.newt.ScreenImpl { + + static { + DisplayDriver.initSingleton(); + } + + public ScreenDriver() { + } + + protected void createNativeImpl() { + AbstractGraphicsDevice adevice = getDisplay().getGraphicsDevice(); + GetScreenInfo(adevice.getHandle(), screen_idx); + aScreen = new DefaultGraphicsScreen(adevice, screen_idx); + } + + protected void closeNativeImpl() { } + + protected int validateScreenIndex(int idx) { + return 0; // only one screen available + } + + protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { + virtualOrigin.setX(0); + virtualOrigin.setY(0); + virtualSize.setWidth(cachedWidth); + virtualSize.setHeight(cachedHeight); + } + + //---------------------------------------------------------------------- + // Internals only + // + + protected static native boolean initIDs(); + private native void GetScreenInfo(long displayHandle, int screen_idx); + + // called by GetScreenInfo() .. + private void screenCreated(int width, int height) { + cachedWidth = width; + cachedHeight = height; + } + + private static int cachedWidth = 0; + private static int cachedHeight = 0; +} + diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java deleted file mode 100644 index d5c75abd4..000000000 --- a/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.intel.gdl; - -import javax.media.nativewindow.*; -import javax.media.nativewindow.util.Insets; -import javax.media.nativewindow.util.Point; - -public class Window extends jogamp.newt.WindowImpl { - static { - Display.initSingleton(); - } - - public Window() { - } - - static long nextWindowHandle = 1; - - protected void createNativeImpl() { - if(0!=getParentWindowHandle()) { - throw new NativeWindowException("GDL Window does not support window parenting"); - } - final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen(); - final AbstractGraphicsDevice aDevice = getScreen().getDisplay().getGraphicsDevice(); - - final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aDevice, capsRequested).chooseGraphicsConfiguration( - capsRequested, capsRequested, capabilitiesChooser, aScreen, VisualIDHolder.VID_UNDEFINED); - if (null == cfg) { - throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); - } - setGraphicsConfiguration(cfg); - - synchronized(Window.class) { - setWindowHandle(nextWindowHandle++); // just a marker - - surfaceHandle = CreateSurface(aDevice.getHandle(), getScreen().getWidth(), getScreen().getHeight(), getX(), getY(), getWidth(), getHeight()); - if (surfaceHandle == 0) { - throw new NativeWindowException("Error creating window"); - } - } - } - - protected void closeNativeImpl() { - if(0!=surfaceHandle) { - synchronized(Window.class) { - CloseSurface(getDisplayHandle(), surfaceHandle); - } - surfaceHandle = 0; - ((Display)getScreen().getDisplay()).setFocus(null); - } - } - - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { - Screen screen = (Screen) getScreen(); - - if(width>screen.getWidth()) { - width=screen.getWidth(); - } - if(height>screen.getHeight()) { - height=screen.getHeight(); - } - if((x+width)>screen.getWidth()) { - x=screen.getWidth()-width; - } - if((y+height)>screen.getHeight()) { - y=screen.getHeight()-height; - } - - if(0!=surfaceHandle) { - SetBounds0(surfaceHandle, getScreen().getWidth(), getScreen().getHeight(), x, y, width, height); - } - - if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { - if(0 != ( FLAG_IS_VISIBLE & flags)) { - ((Display)getScreen().getDisplay()).setFocus(this); - } - visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); - } - - return true; - } - - protected void requestFocusImpl(boolean reparented) { - ((Display)getScreen().getDisplay()).setFocus(this); - } - - @Override - public final long getSurfaceHandle() { - return surfaceHandle; - } - - protected Point getLocationOnScreenImpl(int x, int y) { - return new Point(x,y); - } - - protected void updateInsetsImpl(Insets insets) { - // nop .. - } - - //---------------------------------------------------------------------- - // Internals only - // - - protected static native boolean initIDs(); - private native long CreateSurface(long displayHandle, int scrn_width, int scrn_height, int x, int y, int width, int height); - private native void CloseSurface(long displayHandle, long surfaceHandle); - private native void SetBounds0(long surfaceHandle, int scrn_width, int scrn_height, int x, int y, int width, int height); - - private void updateBounds(int x, int y, int width, int height) { - definePosition(x, y); - defineSize(width, height); - } - - private long surfaceHandle; -} diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/WindowDriver.java new file mode 100644 index 000000000..98335f192 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/WindowDriver.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.intel.gdl; + +import javax.media.nativewindow.*; +import javax.media.nativewindow.util.Insets; +import javax.media.nativewindow.util.Point; + +public class WindowDriver extends jogamp.newt.WindowImpl { + static { + DisplayDriver.initSingleton(); + } + + public WindowDriver() { + } + + static long nextWindowHandle = 1; + + protected void createNativeImpl() { + if(0!=getParentWindowHandle()) { + throw new NativeWindowException("GDL Window does not support window parenting"); + } + final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen(); + final AbstractGraphicsDevice aDevice = getScreen().getDisplay().getGraphicsDevice(); + + final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aDevice, capsRequested).chooseGraphicsConfiguration( + capsRequested, capsRequested, capabilitiesChooser, aScreen, VisualIDHolder.VID_UNDEFINED); + if (null == cfg) { + throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); + } + setGraphicsConfiguration(cfg); + + synchronized(WindowDriver.class) { + setWindowHandle(nextWindowHandle++); // just a marker + + surfaceHandle = CreateSurface(aDevice.getHandle(), getScreen().getWidth(), getScreen().getHeight(), getX(), getY(), getWidth(), getHeight()); + if (surfaceHandle == 0) { + throw new NativeWindowException("Error creating window"); + } + } + } + + protected void closeNativeImpl() { + if(0!=surfaceHandle) { + synchronized(WindowDriver.class) { + CloseSurface(getDisplayHandle(), surfaceHandle); + } + surfaceHandle = 0; + ((DisplayDriver)getScreen().getDisplay()).setFocus(null); + } + } + + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + ScreenDriver screen = (ScreenDriver) getScreen(); + + if(width>screen.getWidth()) { + width=screen.getWidth(); + } + if(height>screen.getHeight()) { + height=screen.getHeight(); + } + if((x+width)>screen.getWidth()) { + x=screen.getWidth()-width; + } + if((y+height)>screen.getHeight()) { + y=screen.getHeight()-height; + } + + if(0!=surfaceHandle) { + SetBounds0(surfaceHandle, getScreen().getWidth(), getScreen().getHeight(), x, y, width, height); + } + + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + if(0 != ( FLAG_IS_VISIBLE & flags)) { + ((DisplayDriver)getScreen().getDisplay()).setFocus(this); + } + visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); + } + + return true; + } + + protected void requestFocusImpl(boolean reparented) { + ((DisplayDriver)getScreen().getDisplay()).setFocus(this); + } + + @Override + public final long getSurfaceHandle() { + return surfaceHandle; + } + + protected Point getLocationOnScreenImpl(int x, int y) { + return new Point(x,y); + } + + protected void updateInsetsImpl(Insets insets) { + // nop .. + } + + //---------------------------------------------------------------------- + // Internals only + // + + protected static native boolean initIDs(); + private native long CreateSurface(long displayHandle, int scrn_width, int scrn_height, int x, int y, int width, int height); + private native void CloseSurface(long displayHandle, long surfaceHandle); + private native void SetBounds0(long surfaceHandle, int scrn_width, int scrn_height, int x, int y, int width, int height); + + private void updateBounds(int x, int y, int width, int height) { + definePosition(x, y); + defineSize(width, height); + } + + private long surfaceHandle; +} diff --git a/src/newt/classes/jogamp/newt/driver/kd/Display.java b/src/newt/classes/jogamp/newt/driver/kd/Display.java deleted file mode 100644 index a58ad477a..000000000 --- a/src/newt/classes/jogamp/newt/driver/kd/Display.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2012 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.kd; - -import javax.media.nativewindow.AbstractGraphicsDevice; -import javax.media.nativewindow.NativeWindowException; - -import jogamp.newt.DisplayImpl; -import jogamp.newt.NEWTJNILibLoader; -import jogamp.opengl.egl.EGL; -import jogamp.opengl.egl.EGLDisplayUtil; - -public class Display extends DisplayImpl { - static { - NEWTJNILibLoader.loadNEWT(); - - if (!Window.initIDs()) { - throw new NativeWindowException("Failed to initialize kd.Window jmethodIDs"); - } - } - - public static void initSingleton() { - // just exist to ensure static init has been run - } - - - public Display() { - } - - protected void createNativeImpl() { - // FIXME: map name to EGL_*_DISPLAY - aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); - } - - protected void closeNativeImpl() { - aDevice.close(); - } - - protected void dispatchMessagesNative() { - DispatchMessages(); - } - - private native void DispatchMessages(); -} - diff --git a/src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java new file mode 100644 index 000000000..745be5dae --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.kd; + +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.NativeWindowException; + +import jogamp.newt.DisplayImpl; +import jogamp.newt.NEWTJNILibLoader; +import jogamp.opengl.egl.EGL; +import jogamp.opengl.egl.EGLDisplayUtil; + +public class DisplayDriver extends DisplayImpl { + static { + NEWTJNILibLoader.loadNEWT(); + + if (!WindowDriver.initIDs()) { + throw new NativeWindowException("Failed to initialize kd.Window jmethodIDs"); + } + } + + public static void initSingleton() { + // just exist to ensure static init has been run + } + + + public DisplayDriver() { + } + + protected void createNativeImpl() { + // FIXME: map name to EGL_*_DISPLAY + aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); + } + + protected void closeNativeImpl() { + aDevice.close(); + } + + protected void dispatchMessagesNative() { + DispatchMessages(); + } + + private native void DispatchMessages(); +} + diff --git a/src/newt/classes/jogamp/newt/driver/kd/Screen.java b/src/newt/classes/jogamp/newt/driver/kd/Screen.java deleted file mode 100644 index 53f5890b2..000000000 --- a/src/newt/classes/jogamp/newt/driver/kd/Screen.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2012 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.kd; - -import javax.media.nativewindow.DefaultGraphicsScreen; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.Point; - -import jogamp.newt.ScreenImpl; - -public class Screen extends ScreenImpl { - static { - Display.initSingleton(); - } - - public Screen() { - } - - protected void createNativeImpl() { - aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx); - } - - protected void closeNativeImpl() { } - - protected int validateScreenIndex(int idx) { - return 0; // only one screen available - } - - protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { - virtualOrigin.setX(0); - virtualOrigin.setY(0); - virtualSize.setWidth(cachedWidth); - virtualSize.setHeight(cachedHeight); - } - - protected void sizeChanged(int w, int h) { - cachedWidth = w; - cachedHeight = h; - } - - private static int cachedWidth = 0; - private static int cachedHeight = 0; -} diff --git a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java new file mode 100644 index 000000000..656bcf5c9 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.kd; + +import javax.media.nativewindow.DefaultGraphicsScreen; +import javax.media.nativewindow.util.Dimension; +import javax.media.nativewindow.util.Point; + +import jogamp.newt.ScreenImpl; + +public class ScreenDriver extends ScreenImpl { + static { + DisplayDriver.initSingleton(); + } + + public ScreenDriver() { + } + + protected void createNativeImpl() { + aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx); + } + + protected void closeNativeImpl() { } + + protected int validateScreenIndex(int idx) { + return 0; // only one screen available + } + + protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { + virtualOrigin.setX(0); + virtualOrigin.setY(0); + virtualSize.setWidth(cachedWidth); + virtualSize.setHeight(cachedHeight); + } + + protected void sizeChanged(int w, int h) { + cachedWidth = w; + cachedHeight = h; + } + + private static int cachedWidth = 0; + private static int cachedHeight = 0; +} diff --git a/src/newt/classes/jogamp/newt/driver/kd/Window.java b/src/newt/classes/jogamp/newt/driver/kd/Window.java deleted file mode 100644 index ce65040c3..000000000 --- a/src/newt/classes/jogamp/newt/driver/kd/Window.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2012 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.kd; - -import javax.media.nativewindow.AbstractGraphicsConfiguration; -import javax.media.nativewindow.GraphicsConfigurationFactory; -import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.VisualIDHolder; -import javax.media.nativewindow.VisualIDHolder.VIDType; -import javax.media.nativewindow.util.Insets; -import javax.media.nativewindow.util.Point; -import javax.media.opengl.GLCapabilitiesImmutable; - -import jogamp.newt.WindowImpl; -import jogamp.opengl.egl.EGLGraphicsConfiguration; - -public class Window extends WindowImpl { - private static final String WINDOW_CLASS_NAME = "NewtWindow"; - - static { - Display.initSingleton(); - } - - public Window() { - } - - protected void createNativeImpl() { - if(0!=getParentWindowHandle()) { - throw new RuntimeException("Window parenting not supported (yet)"); - } - final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration( - capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED); - if (null == cfg) { - throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); - } - setGraphicsConfiguration(cfg); - - GLCapabilitiesImmutable eglCaps = (GLCapabilitiesImmutable) cfg.getChosenCapabilities(); - int eglConfigID = eglCaps.getVisualID(VIDType.EGL_CONFIG); - long eglConfig = EGLGraphicsConfiguration.EGLConfigId2EGLConfig(getDisplayHandle(), eglConfigID); - - eglWindowHandle = CreateWindow(getDisplayHandle(), eglConfig); - if (eglWindowHandle == 0) { - throw new NativeWindowException("Error creating egl window: "+cfg+", eglConfigID "+eglConfigID+", eglConfig 0x"+Long.toHexString(eglConfig)); - } - setVisible0(eglWindowHandle, false); - setWindowHandle(RealizeWindow(eglWindowHandle)); - if (0 == getWindowHandle()) { - throw new NativeWindowException("Error native Window Handle is null"); - } - windowHandleClose = eglWindowHandle; - } - - protected void closeNativeImpl() { - if(0!=windowHandleClose) { - CloseWindow(windowHandleClose, windowUserData); - windowUserData=0; - } - } - - protected void requestFocusImpl(boolean reparented) { } - - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { - if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { - setVisible0(eglWindowHandle, 0 != ( FLAG_IS_VISIBLE & flags)); - visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); - } - - if(0!=eglWindowHandle) { - if(0 != ( FLAG_CHANGE_FULLSCREEN & flags)) { - final boolean fs = 0 != ( FLAG_IS_FULLSCREEN & flags) ; - setFullScreen0(eglWindowHandle, fs); - if(fs) { - return true; - } - } - // int _x=(x>=0)?x:this.x; - // int _y=(x>=0)?y:this.y; - width=(width>0)?width:getWidth(); - height=(height>0)?height:getHeight(); - if(width>0 || height>0) { - setSize0(eglWindowHandle, width, height); - } - if(x>=0 || y>=0) { - System.err.println("setPosition n/a in KD"); - } - } - - if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { - visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); - } - - return true; - } - - protected Point getLocationOnScreenImpl(int x, int y) { - return new Point(x,y); - } - - protected void updateInsetsImpl(Insets insets) { - // nop .. - } - - //---------------------------------------------------------------------- - // Internals only - // - - protected static native boolean initIDs(); - private native long CreateWindow(long displayHandle, long eglConfig); - private native long RealizeWindow(long eglWindowHandle); - private native int CloseWindow(long eglWindowHandle, long userData); - private native void setVisible0(long eglWindowHandle, boolean visible); - private native void setSize0(long eglWindowHandle, int width, int height); - private native void setFullScreen0(long eglWindowHandle, boolean fullscreen); - - private void windowCreated(long userData) { - windowUserData=userData; - } - - @Override - protected void sizeChanged(boolean defer, int newWidth, int newHeight, boolean force) { - if(isFullscreen()) { - ((Screen)getScreen()).sizeChanged(getWidth(), getHeight()); - } - super.sizeChanged(defer, newWidth, newHeight, force); - } - - private long eglWindowHandle; - private long windowHandleClose; - private long windowUserData; -} diff --git a/src/newt/classes/jogamp/newt/driver/kd/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/kd/WindowDriver.java new file mode 100644 index 000000000..c733a3e94 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/kd/WindowDriver.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.kd; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.GraphicsConfigurationFactory; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.VisualIDHolder; +import javax.media.nativewindow.VisualIDHolder.VIDType; +import javax.media.nativewindow.util.Insets; +import javax.media.nativewindow.util.Point; +import javax.media.opengl.GLCapabilitiesImmutable; + +import jogamp.newt.WindowImpl; +import jogamp.opengl.egl.EGLGraphicsConfiguration; + +public class WindowDriver extends WindowImpl { + private static final String WINDOW_CLASS_NAME = "NewtWindow"; + + static { + DisplayDriver.initSingleton(); + } + + public WindowDriver() { + } + + protected void createNativeImpl() { + if(0!=getParentWindowHandle()) { + throw new RuntimeException("Window parenting not supported (yet)"); + } + final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration( + capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED); + if (null == cfg) { + throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); + } + setGraphicsConfiguration(cfg); + + GLCapabilitiesImmutable eglCaps = (GLCapabilitiesImmutable) cfg.getChosenCapabilities(); + int eglConfigID = eglCaps.getVisualID(VIDType.EGL_CONFIG); + long eglConfig = EGLGraphicsConfiguration.EGLConfigId2EGLConfig(getDisplayHandle(), eglConfigID); + + eglWindowHandle = CreateWindow(getDisplayHandle(), eglConfig); + if (eglWindowHandle == 0) { + throw new NativeWindowException("Error creating egl window: "+cfg+", eglConfigID "+eglConfigID+", eglConfig 0x"+Long.toHexString(eglConfig)); + } + setVisible0(eglWindowHandle, false); + setWindowHandle(RealizeWindow(eglWindowHandle)); + if (0 == getWindowHandle()) { + throw new NativeWindowException("Error native Window Handle is null"); + } + windowHandleClose = eglWindowHandle; + } + + protected void closeNativeImpl() { + if(0!=windowHandleClose) { + CloseWindow(windowHandleClose, windowUserData); + windowUserData=0; + } + } + + protected void requestFocusImpl(boolean reparented) { } + + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + setVisible0(eglWindowHandle, 0 != ( FLAG_IS_VISIBLE & flags)); + visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); + } + + if(0!=eglWindowHandle) { + if(0 != ( FLAG_CHANGE_FULLSCREEN & flags)) { + final boolean fs = 0 != ( FLAG_IS_FULLSCREEN & flags) ; + setFullScreen0(eglWindowHandle, fs); + if(fs) { + return true; + } + } + // int _x=(x>=0)?x:this.x; + // int _y=(x>=0)?y:this.y; + width=(width>0)?width:getWidth(); + height=(height>0)?height:getHeight(); + if(width>0 || height>0) { + setSize0(eglWindowHandle, width, height); + } + if(x>=0 || y>=0) { + System.err.println("setPosition n/a in KD"); + } + } + + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); + } + + return true; + } + + protected Point getLocationOnScreenImpl(int x, int y) { + return new Point(x,y); + } + + protected void updateInsetsImpl(Insets insets) { + // nop .. + } + + //---------------------------------------------------------------------- + // Internals only + // + + protected static native boolean initIDs(); + private native long CreateWindow(long displayHandle, long eglConfig); + private native long RealizeWindow(long eglWindowHandle); + private native int CloseWindow(long eglWindowHandle, long userData); + private native void setVisible0(long eglWindowHandle, boolean visible); + private native void setSize0(long eglWindowHandle, int width, int height); + private native void setFullScreen0(long eglWindowHandle, boolean fullscreen); + + private void windowCreated(long userData) { + windowUserData=userData; + } + + @Override + protected void sizeChanged(boolean defer, int newWidth, int newHeight, boolean force) { + if(isFullscreen()) { + ((ScreenDriver)getScreen()).sizeChanged(getWidth(), getHeight()); + } + super.sizeChanged(defer, newWidth, newHeight, force); + } + + private long eglWindowHandle; + private long windowHandleClose; + private long windowUserData; +} diff --git a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java new file mode 100644 index 000000000..1a3f14859 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.macosx; + +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.NativeWindowException; + +import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice; + +import jogamp.newt.DisplayImpl; +import jogamp.newt.NEWTJNILibLoader; + +public class DisplayDriver extends DisplayImpl { + static { + NEWTJNILibLoader.loadNEWT(); + + if(!initNSApplication0()) { + throw new NativeWindowException("Failed to initialize native Application hook"); + } + if(!WindowDriver.initIDs0()) { + throw new NativeWindowException("Failed to initialize jmethodIDs"); + } + if(DEBUG) { + System.err.println("MacDisplay.init App and IDs OK "+Thread.currentThread().getName()); + } + } + + public static void initSingleton() { + // just exist to ensure static init has been run + } + + public DisplayDriver() { + } + + protected void dispatchMessagesNative() { + // nop + } + + protected void createNativeImpl() { + aDevice = new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); + } + + protected void closeNativeImpl() { } + + public static void runNSApplication() { + runNSApplication0(); + } + public static void stopNSApplication() { + stopNSApplication0(); + } + + private static native boolean initNSApplication0(); + private static native void runNSApplication0(); + private static native void stopNSApplication0(); +} + diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java b/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java deleted file mode 100644 index 18f8d9538..000000000 --- a/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.macosx; - -import javax.media.nativewindow.AbstractGraphicsDevice; -import javax.media.nativewindow.NativeWindowException; - -import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice; - -import jogamp.newt.DisplayImpl; -import jogamp.newt.NEWTJNILibLoader; - -public class MacDisplay extends DisplayImpl { - static { - NEWTJNILibLoader.loadNEWT(); - - if(!initNSApplication0()) { - throw new NativeWindowException("Failed to initialize native Application hook"); - } - if(!MacWindow.initIDs0()) { - throw new NativeWindowException("Failed to initialize jmethodIDs"); - } - if(DEBUG) { - System.err.println("MacDisplay.init App and IDs OK "+Thread.currentThread().getName()); - } - } - - public static void initSingleton() { - // just exist to ensure static init has been run - } - - public MacDisplay() { - } - - protected void dispatchMessagesNative() { - // nop - } - - protected void createNativeImpl() { - aDevice = new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); - } - - protected void closeNativeImpl() { } - - public static void runNSApplication() { - runNSApplication0(); - } - public static void stopNSApplication() { - stopNSApplication0(); - } - - private static native boolean initNSApplication0(); - private static native void runNSApplication0(); - private static native void stopNSApplication0(); -} - diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java b/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java index 46625f7a9..d39e0027b 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java @@ -1,3 +1,30 @@ +/** + * Copyright 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ package jogamp.newt.driver.macosx; import com.jogamp.newt.event.KeyEvent; diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java b/src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java deleted file mode 100644 index b9c725fd4..000000000 --- a/src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2011 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.macosx; - -import java.util.List; - -import javax.media.nativewindow.DefaultGraphicsScreen; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.DimensionImmutable; -import javax.media.nativewindow.util.Point; - -import jogamp.newt.ScreenImpl; - -import com.jogamp.common.util.IntObjectHashMap; -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.util.ScreenModeUtil; - -public class MacScreen extends ScreenImpl { - - // caching native CGDisplayScreenSize() results, since it's ridiculous slow (~6 ms each call) - private static IntObjectHashMap/**/ scrnIdx2Dimension; - - static { - MacDisplay.initSingleton(); - scrnIdx2Dimension = new IntObjectHashMap(); - scrnIdx2Dimension.setKeyNotFoundValue(null); - } - - public MacScreen() { - } - - protected void createNativeImpl() { - aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx); - } - - protected void closeNativeImpl() { } - - private static native int getWidthImpl0(int scrn_idx); - private static native int getHeightImpl0(int scrn_idx); - - private int[] getScreenModeIdx(int idx) { - // caching native CGDisplayScreenSize() results, since it's ridiculous slow (~6 ms each call) - DimensionImmutable dim = (DimensionImmutable) scrnIdx2Dimension.get(screen_idx); - if(null == dim) { - int[] res = getScreenSizeMM0(screen_idx); - if(null == res || 0 == res.length) { - return null; - } - dim = new Dimension(res[0], res[1]); - scrnIdx2Dimension.put(screen_idx, dim); - } - - int[] modeProps = getScreenMode0(screen_idx, idx, dim.getWidth(), dim.getHeight()); - if (null == modeProps || 0 == modeProps.length) { - return null; - } - if(modeProps.length < ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL) { - throw new RuntimeException("properties array too short, should be >= "+ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+modeProps.length); - } - return modeProps; - } - - private int nativeModeIdx; - - protected int[] getScreenModeFirstImpl() { - nativeModeIdx = 0; - return getScreenModeNextImpl(); - } - - protected int[] getScreenModeNextImpl() { - int[] modeProps = getScreenModeIdx(nativeModeIdx); - if (null != modeProps && 0 < modeProps.length) { - nativeModeIdx++; - return modeProps; - } - return null; - } - - protected ScreenMode getCurrentScreenModeImpl() { - int[] modeProps = getScreenModeIdx(-1); - if (null != modeProps && 0 < modeProps.length) { - return ScreenModeUtil.streamIn(modeProps, 0); - } - return null; - } - - protected boolean setCurrentScreenModeImpl(final ScreenMode screenMode) { - final List screenModes = this.getScreenModesOrig(); - final int screenModeIdx = screenModes.indexOf(screenMode); - if(0>screenModeIdx) { - throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode); - } - final int nativeModeIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx); - return setScreenMode0(screen_idx, nativeModeIdx); - } - - protected int validateScreenIndex(int idx) { - return idx; - } - - protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { - virtualOrigin.setX(0); - virtualOrigin.setY(0); - virtualSize.setWidth(getWidthImpl0(screen_idx)); - virtualSize.setHeight(getHeightImpl0(screen_idx)); - } - - private native int[] getScreenSizeMM0(int screen_idx); - private native int[] getScreenMode0(int screen_index, int mode_index, int widthMM, int heightMM); - private native boolean setScreenMode0(int screen_index, int mode_idx); -} diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java deleted file mode 100644 index 27d7a1679..000000000 --- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.macosx; - -import javax.media.nativewindow.AbstractGraphicsConfiguration; -import javax.media.nativewindow.GraphicsConfigurationFactory; -import javax.media.nativewindow.NativeWindow; -import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.MutableSurface; -import javax.media.nativewindow.VisualIDHolder; -import javax.media.nativewindow.util.Insets; -import javax.media.nativewindow.util.InsetsImmutable; -import javax.media.nativewindow.util.Point; -import javax.media.nativewindow.util.PointImmutable; - -import jogamp.newt.WindowImpl; -import jogamp.newt.driver.DriverClearFocus; -import jogamp.newt.driver.DriverUpdatePosition; - -import com.jogamp.newt.event.KeyEvent; - -public class MacWindow extends WindowImpl implements MutableSurface, DriverClearFocus, DriverUpdatePosition { - - static { - MacDisplay.initSingleton(); - } - - public MacWindow() { - } - - @Override - protected void createNativeImpl() { - final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration( - capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED); - if (null == cfg) { - throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); - } - setGraphicsConfiguration(cfg); - reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureFlags(FLAG_CHANGE_VISIBILITY, true)); - if (0 == getWindowHandle()) { - throw new NativeWindowException("Error creating window"); - } - } - - @Override - protected void closeNativeImpl() { - try { - if(DEBUG_IMPLEMENTATION) { System.err.println("MacWindow.CloseAction "+Thread.currentThread().getName()); } - final long handle = getWindowHandle(); - setWindowHandle(0); - surfaceHandle = 0; - sscSurfaceHandle = 0; - isOffscreenInstance = false; - if (0 != handle) { - close0(handle); - } - } catch (Throwable t) { - if(DEBUG_IMPLEMENTATION) { - Exception e = new Exception("Warning: closeNative failed - "+Thread.currentThread().getName(), t); - e.printStackTrace(); - } - } - } - - @Override - protected int lockSurfaceImpl() { - if(!isOffscreenInstance) { - return lockSurface0(getWindowHandle()) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY; - } - return LOCK_SUCCESS; - } - - @Override - protected void unlockSurfaceImpl() { - if(!isOffscreenInstance) { - final long h = getWindowHandle(); - if(0 != h) { - unlockSurface0(h); - } - } - } - - @Override - public final long getSurfaceHandle() { - return 0 != sscSurfaceHandle ? sscSurfaceHandle : surfaceHandle; - } - - public void setSurfaceHandle(long surfaceHandle) { - if(DEBUG_IMPLEMENTATION) { - System.err.println("MacWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle)); - } - sscSurfaceHandle = surfaceHandle; - if (isNativeValid()) { - if (0 != sscSurfaceHandle) { - orderOut0( 0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() ); - } /** this is done by recreation! - else if (isVisible()){ - orderFront0( 0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() ); - } */ - } - } - - @Override - protected void setTitleImpl(final String title) { - setTitle0(getWindowHandle(), title); - } - - protected void requestFocusImpl(boolean force) { - if(!isOffscreenInstance) { - requestFocus0(getWindowHandle(), force); - } else { - focusChanged(false, true); - } - } - - public final void clearFocus() { - if(DEBUG_IMPLEMENTATION) { - System.err.println("MacWindow: clearFocus() - requestFocusParent, isOffscreenInstance "+isOffscreenInstance); - } - if(!isOffscreenInstance) { - resignFocus0(getWindowHandle()); - } else { - focusChanged(false, false); - } - } - - public void updatePosition() { - final Point pS = getTopLevelLocationOnScreen(getX(), getY()); - if(DEBUG_IMPLEMENTATION) { - System.err.println("MacWindow: updatePosition() - isOffscreenInstance "+isOffscreenInstance+", new abs pos: pS "+pS); - } - if( !isOffscreenInstance ) { - setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), pS.getX(), pS.getY()); - } // else no offscreen position - // no native event (fullscreen, some reparenting) - super.positionChanged(true, getX(), getY()); - } - - - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { - final Point pS = getTopLevelLocationOnScreen(x, y); - isOffscreenInstance = 0 != sscSurfaceHandle || isOffscreenInstance(this, this.getParent()); - - if(DEBUG_IMPLEMENTATION) { - System.err.println("MacWindow reconfig: "+x+"/"+y+" -> "+pS+" - "+width+"x"+height+ - ", offscreenInstance "+isOffscreenInstance+ - ", "+getReconfigureFlagsAsString(null, flags)); - } - - if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 == ( FLAG_IS_VISIBLE & flags) ) { - if ( !isOffscreenInstance ) { - orderOut0(getWindowHandle()); - } - // no native event .. - visibleChanged(true, false); - } - if( 0 == getWindowHandle() && 0 != ( FLAG_IS_VISIBLE & flags) || - 0 != ( FLAG_CHANGE_DECORATION & flags) || - 0 != ( FLAG_CHANGE_PARENTING & flags) || - 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) { - createWindow(isOffscreenInstance, 0 != getWindowHandle(), pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags)); - if(isVisible()) { flags |= FLAG_CHANGE_VISIBILITY; } - } - if(x>=0 && y>=0) { - if( !isOffscreenInstance ) { - setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), pS.getX(), pS.getY()); - } // else no offscreen position - // no native event (fullscreen, some reparenting) - super.positionChanged(true, x, y); - } - if(width>0 && height>0) { - if( !isOffscreenInstance ) { - setContentSize0(getWindowHandle(), width, height); - } // else offscreen size is realized via recreation - // no native event (fullscreen, some reparenting) - sizeChanged(true, width, height, false); // incl. validation (incl. repositioning) - } - if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 != ( FLAG_IS_VISIBLE & flags) ) { - if( !isOffscreenInstance ) { - orderFront0(getWindowHandle()); - } - // no native event .. - visibleChanged(true, true); - } - if( !isOffscreenInstance ) { - setAlwaysOnTop0(getWindowHandle(), 0 != ( FLAG_IS_ALWAYSONTOP & flags)); - } - return true; - } - - protected Point getLocationOnScreenImpl(int x, int y) { - Point p = new Point(x, y); - // min val is 0 - p.setX(Math.max(p.getX(), 0)); - p.setY(Math.max(p.getY(), 0)); - - final NativeWindow parent = getParent(); - if( null != parent && 0 != parent.getWindowHandle() ) { - p.translate(parent.getLocationOnScreen(null)); - } - return p; - } - - private Point getTopLevelLocationOnScreen(int x, int y) { - final InsetsImmutable _insets = getInsets(); // zero if undecorated - // client position -> top-level window position - x -= _insets.getLeftWidth() ; - y -= _insets.getTopHeight() ; - return getLocationOnScreenImpl(x, y); - } - - protected void updateInsetsImpl(Insets insets) { - // nop - using event driven insetsChange(..) - } - - @Override - protected void sizeChanged(boolean defer, int newWidth, int newHeight, boolean force) { - if(getWidth() != newWidth || getHeight() != newHeight) { - final Point p0S = getTopLevelLocationOnScreen(getX(), getY()); - setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), p0S.getX(), p0S.getY()); - } - super.sizeChanged(defer, newWidth, newHeight, force); - } - - @Override - protected void positionChanged(boolean defer, int newX, int newY) { - // passed coordinates are in screen position of the client area - if(getWindowHandle()!=0) { - // screen position -> window position - Point absPos = new Point(newX, newY); - final NativeWindow parent = getParent(); - if(null != parent) { - absPos.translate( parent.getLocationOnScreen(null).scale(-1, -1) ); - } - super.positionChanged(defer, absPos.getX(), absPos.getY()); - } - } - - @Override - protected boolean setPointerVisibleImpl(final boolean pointerVisible) { - if( !isOffscreenInstance ) { - return setPointerVisible0(getWindowHandle(), hasFocus(), pointerVisible); - } // else may need offscreen solution ? FIXME - return false; - } - - @Override - protected boolean confinePointerImpl(final boolean confine) { - if( !isOffscreenInstance ) { - return confinePointer0(getWindowHandle(), confine); - } // else may need offscreen solution ? FIXME - return false; - } - - @Override - protected void warpPointerImpl(final int x, final int y) { - if( !isOffscreenInstance ) { - warpPointer0(getWindowHandle(), x, y); - } // else may need offscreen solution ? FIXME - } - - @Override - public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { - // Note that we send the key char for the key code on this - // platform -- we do not get any useful key codes out of the system - final int keyCode2 = MacKeyUtil.validateKeyCode(keyCode, keyChar); - final boolean valid = validateKeyEvent(eventType, modifiers, keyCode); - if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.sendKeyEvent "+Thread.currentThread().getName()+" char: 0x"+Integer.toHexString(keyChar)+", code 0x"+Integer.toHexString(keyCode)+" -> 0x"+Integer.toHexString(keyCode2)+", valid "+valid); - if(valid) { - // only deliver keyChar on key Typed events, harmonizing platform behavior - keyChar = KeyEvent.EVENT_KEY_TYPED == eventType ? keyChar : (char)-1; - super.sendKeyEvent(eventType, modifiers, keyCode2, keyChar); - } - } - - @Override - public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) { - // Note that we send the key char for the key code on this - // platform -- we do not get any useful key codes out of the system - final int keyCode2 = MacKeyUtil.validateKeyCode(keyCode, keyChar); - final boolean valid = validateKeyEvent(eventType, modifiers, keyCode); - if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.enqueueKeyEvent "+Thread.currentThread().getName()+" char: 0x"+Integer.toHexString(keyChar)+", code 0x"+Integer.toHexString(keyCode)+" -> 0x"+Integer.toHexString(keyCode2)+", valid "+valid); - if(valid) { - // only deliver keyChar on key Typed events, harmonizing platform behavior - keyChar = KeyEvent.EVENT_KEY_TYPED == eventType ? keyChar : (char)-1; - super.enqueueKeyEvent(wait, eventType, modifiers, keyCode2, keyChar); - } - } - - private int keyDownModifiers = 0; - private int keyDownCode = 0; - - private boolean validateKeyEvent(int eventType, int modifiers, int keyCode) { - switch(eventType) { - case KeyEvent.EVENT_KEY_PRESSED: - keyDownModifiers = modifiers; - keyDownCode = keyCode; - return true; - case KeyEvent.EVENT_KEY_RELEASED: - return keyDownModifiers == modifiers && keyDownCode == keyCode; - case KeyEvent.EVENT_KEY_TYPED: - final boolean matchKeyDown = keyDownModifiers == modifiers && keyDownCode == keyCode; - keyDownModifiers = 0; - keyDownCode = 0; - return matchKeyDown; - default: - throw new NativeWindowException("Unexpected key event type " + eventType); - } - } - - - //---------------------------------------------------------------------- - // Internals only - // - - private void createWindow(final boolean offscreenInstance, final boolean recreate, - final PointImmutable pS, final int width, final int height, - final boolean fullscreen) { - - if(0!=getWindowHandle() && !recreate) { - return; - } - - try { - if(0!=getWindowHandle()) { - // save the view .. close the window - surfaceHandle = changeContentView0(getParentWindowHandle(), getWindowHandle(), 0); - if(recreate && 0==surfaceHandle) { - throw new NativeWindowException("Internal Error - recreate, window but no view"); - } - close0(getWindowHandle()); - setWindowHandle(0); - } else { - surfaceHandle = 0; - } - setWindowHandle(createWindow0(getParentWindowHandle(), - pS.getX(), pS.getY(), width, height, - (getGraphicsConfiguration().getChosenCapabilities().isBackgroundOpaque() && !offscreenInstance), - fullscreen, - ((isUndecorated() || offscreenInstance) ? - NSBorderlessWindowMask : - NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask), - NSBackingStoreBuffered, - getScreen().getIndex(), surfaceHandle)); - if (getWindowHandle() == 0) { - throw new NativeWindowException("Could create native window "+Thread.currentThread().getName()+" "+this); - } - surfaceHandle = contentView0(getWindowHandle()); - if( offscreenInstance ) { - orderOut0(0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle()); - } else { - setTitle0(getWindowHandle(), getTitle()); - } - } catch (Exception ie) { - ie.printStackTrace(); - } - } - - protected static native boolean initIDs0(); - private native long createWindow0(long parentWindowHandle, int x, int y, int w, int h, - boolean opaque, boolean fullscreen, int windowStyle, - int backingStoreType, - int screen_idx, long view); - private native boolean lockSurface0(long window); - private native void unlockSurface0(long window); - private native void requestFocus0(long window, boolean force); - private native void resignFocus0(long window); - /** in case of a child window, it actually only issues orderBack(..) */ - private native void orderOut0(long window); - private native void orderFront0(long window); - private native void close0(long window); - private native void setTitle0(long window, String title); - private native long contentView0(long window); - private native long changeContentView0(long parentWindowOrViewHandle, long window, long view); - private native void setContentSize0(long window, int w, int h); - private native void setFrameTopLeftPoint0(long parentWindowHandle, long window, int x, int y); - private native void setAlwaysOnTop0(long window, boolean atop); - private static native Object getLocationOnScreen0(long windowHandle, int src_x, int src_y); - private static native boolean setPointerVisible0(long windowHandle, boolean hasFocus, boolean visible); - private static native boolean confinePointer0(long windowHandle, boolean confine); - private static native void warpPointer0(long windowHandle, int x, int y); - - // Window styles - private static final int NSBorderlessWindowMask = 0; - private static final int NSTitledWindowMask = 1 << 0; - private static final int NSClosableWindowMask = 1 << 1; - private static final int NSMiniaturizableWindowMask = 1 << 2; - private static final int NSResizableWindowMask = 1 << 3; - - // Window backing store types - private static final int NSBackingStoreRetained = 0; - private static final int NSBackingStoreNonretained = 1; - private static final int NSBackingStoreBuffered = 2; - - private volatile long surfaceHandle = 0; - private long sscSurfaceHandle = 0; - private boolean isOffscreenInstance = false; - -} diff --git a/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java new file mode 100644 index 000000000..24e60ba0a --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.macosx; + +import java.util.List; + +import javax.media.nativewindow.DefaultGraphicsScreen; +import javax.media.nativewindow.util.Dimension; +import javax.media.nativewindow.util.DimensionImmutable; +import javax.media.nativewindow.util.Point; + +import jogamp.newt.ScreenImpl; + +import com.jogamp.common.util.IntObjectHashMap; +import com.jogamp.newt.ScreenMode; +import com.jogamp.newt.util.ScreenModeUtil; + +public class ScreenDriver extends ScreenImpl { + + // caching native CGDisplayScreenSize() results, since it's ridiculous slow (~6 ms each call) + private static IntObjectHashMap/**/ scrnIdx2Dimension; + + static { + DisplayDriver.initSingleton(); + scrnIdx2Dimension = new IntObjectHashMap(); + scrnIdx2Dimension.setKeyNotFoundValue(null); + } + + public ScreenDriver() { + } + + protected void createNativeImpl() { + aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx); + } + + protected void closeNativeImpl() { } + + private static native int getWidthImpl0(int scrn_idx); + private static native int getHeightImpl0(int scrn_idx); + + private int[] getScreenModeIdx(int idx) { + // caching native CGDisplayScreenSize() results, since it's ridiculous slow (~6 ms each call) + DimensionImmutable dim = (DimensionImmutable) scrnIdx2Dimension.get(screen_idx); + if(null == dim) { + int[] res = getScreenSizeMM0(screen_idx); + if(null == res || 0 == res.length) { + return null; + } + dim = new Dimension(res[0], res[1]); + scrnIdx2Dimension.put(screen_idx, dim); + } + + int[] modeProps = getScreenMode0(screen_idx, idx, dim.getWidth(), dim.getHeight()); + if (null == modeProps || 0 == modeProps.length) { + return null; + } + if(modeProps.length < ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL) { + throw new RuntimeException("properties array too short, should be >= "+ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+modeProps.length); + } + return modeProps; + } + + private int nativeModeIdx; + + protected int[] getScreenModeFirstImpl() { + nativeModeIdx = 0; + return getScreenModeNextImpl(); + } + + protected int[] getScreenModeNextImpl() { + int[] modeProps = getScreenModeIdx(nativeModeIdx); + if (null != modeProps && 0 < modeProps.length) { + nativeModeIdx++; + return modeProps; + } + return null; + } + + protected ScreenMode getCurrentScreenModeImpl() { + int[] modeProps = getScreenModeIdx(-1); + if (null != modeProps && 0 < modeProps.length) { + return ScreenModeUtil.streamIn(modeProps, 0); + } + return null; + } + + protected boolean setCurrentScreenModeImpl(final ScreenMode screenMode) { + final List screenModes = this.getScreenModesOrig(); + final int screenModeIdx = screenModes.indexOf(screenMode); + if(0>screenModeIdx) { + throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode); + } + final int nativeModeIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx); + return setScreenMode0(screen_idx, nativeModeIdx); + } + + protected int validateScreenIndex(int idx) { + return idx; + } + + protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { + virtualOrigin.setX(0); + virtualOrigin.setY(0); + virtualSize.setWidth(getWidthImpl0(screen_idx)); + virtualSize.setHeight(getHeightImpl0(screen_idx)); + } + + private native int[] getScreenSizeMM0(int screen_idx); + private native int[] getScreenMode0(int screen_index, int mode_index, int widthMM, int heightMM); + private native boolean setScreenMode0(int screen_index, int mode_idx); +} diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java new file mode 100644 index 000000000..ea48569bf --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.macosx; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.GraphicsConfigurationFactory; +import javax.media.nativewindow.NativeWindow; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.MutableSurface; +import javax.media.nativewindow.VisualIDHolder; +import javax.media.nativewindow.util.Insets; +import javax.media.nativewindow.util.InsetsImmutable; +import javax.media.nativewindow.util.Point; +import javax.media.nativewindow.util.PointImmutable; + +import jogamp.newt.WindowImpl; +import jogamp.newt.driver.DriverClearFocus; +import jogamp.newt.driver.DriverUpdatePosition; + +import com.jogamp.newt.event.KeyEvent; + +public class WindowDriver extends WindowImpl implements MutableSurface, DriverClearFocus, DriverUpdatePosition { + + static { + DisplayDriver.initSingleton(); + } + + public WindowDriver() { + } + + @Override + protected void createNativeImpl() { + final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration( + capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED); + if (null == cfg) { + throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); + } + setGraphicsConfiguration(cfg); + reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureFlags(FLAG_CHANGE_VISIBILITY, true)); + if (0 == getWindowHandle()) { + throw new NativeWindowException("Error creating window"); + } + } + + @Override + protected void closeNativeImpl() { + try { + if(DEBUG_IMPLEMENTATION) { System.err.println("MacWindow.CloseAction "+Thread.currentThread().getName()); } + final long handle = getWindowHandle(); + setWindowHandle(0); + surfaceHandle = 0; + sscSurfaceHandle = 0; + isOffscreenInstance = false; + if (0 != handle) { + close0(handle); + } + } catch (Throwable t) { + if(DEBUG_IMPLEMENTATION) { + Exception e = new Exception("Warning: closeNative failed - "+Thread.currentThread().getName(), t); + e.printStackTrace(); + } + } + } + + @Override + protected int lockSurfaceImpl() { + if(!isOffscreenInstance) { + return lockSurface0(getWindowHandle()) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY; + } + return LOCK_SUCCESS; + } + + @Override + protected void unlockSurfaceImpl() { + if(!isOffscreenInstance) { + final long h = getWindowHandle(); + if(0 != h) { + unlockSurface0(h); + } + } + } + + @Override + public final long getSurfaceHandle() { + return 0 != sscSurfaceHandle ? sscSurfaceHandle : surfaceHandle; + } + + public void setSurfaceHandle(long surfaceHandle) { + if(DEBUG_IMPLEMENTATION) { + System.err.println("MacWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle)); + } + sscSurfaceHandle = surfaceHandle; + if (isNativeValid()) { + if (0 != sscSurfaceHandle) { + orderOut0( 0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() ); + } /** this is done by recreation! + else if (isVisible()){ + orderFront0( 0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() ); + } */ + } + } + + @Override + protected void setTitleImpl(final String title) { + setTitle0(getWindowHandle(), title); + } + + protected void requestFocusImpl(boolean force) { + if(!isOffscreenInstance) { + requestFocus0(getWindowHandle(), force); + } else { + focusChanged(false, true); + } + } + + public final void clearFocus() { + if(DEBUG_IMPLEMENTATION) { + System.err.println("MacWindow: clearFocus() - requestFocusParent, isOffscreenInstance "+isOffscreenInstance); + } + if(!isOffscreenInstance) { + resignFocus0(getWindowHandle()); + } else { + focusChanged(false, false); + } + } + + public void updatePosition() { + final Point pS = getTopLevelLocationOnScreen(getX(), getY()); + if(DEBUG_IMPLEMENTATION) { + System.err.println("MacWindow: updatePosition() - isOffscreenInstance "+isOffscreenInstance+", new abs pos: pS "+pS); + } + if( !isOffscreenInstance ) { + setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), pS.getX(), pS.getY()); + } // else no offscreen position + // no native event (fullscreen, some reparenting) + super.positionChanged(true, getX(), getY()); + } + + + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + final Point pS = getTopLevelLocationOnScreen(x, y); + isOffscreenInstance = 0 != sscSurfaceHandle || isOffscreenInstance(this, this.getParent()); + + if(DEBUG_IMPLEMENTATION) { + System.err.println("MacWindow reconfig: "+x+"/"+y+" -> "+pS+" - "+width+"x"+height+ + ", offscreenInstance "+isOffscreenInstance+ + ", "+getReconfigureFlagsAsString(null, flags)); + } + + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 == ( FLAG_IS_VISIBLE & flags) ) { + if ( !isOffscreenInstance ) { + orderOut0(getWindowHandle()); + } + // no native event .. + visibleChanged(true, false); + } + if( 0 == getWindowHandle() && 0 != ( FLAG_IS_VISIBLE & flags) || + 0 != ( FLAG_CHANGE_DECORATION & flags) || + 0 != ( FLAG_CHANGE_PARENTING & flags) || + 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) { + createWindow(isOffscreenInstance, 0 != getWindowHandle(), pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags)); + if(isVisible()) { flags |= FLAG_CHANGE_VISIBILITY; } + } + if(x>=0 && y>=0) { + if( !isOffscreenInstance ) { + setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), pS.getX(), pS.getY()); + } // else no offscreen position + // no native event (fullscreen, some reparenting) + super.positionChanged(true, x, y); + } + if(width>0 && height>0) { + if( !isOffscreenInstance ) { + setContentSize0(getWindowHandle(), width, height); + } // else offscreen size is realized via recreation + // no native event (fullscreen, some reparenting) + sizeChanged(true, width, height, false); // incl. validation (incl. repositioning) + } + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 != ( FLAG_IS_VISIBLE & flags) ) { + if( !isOffscreenInstance ) { + orderFront0(getWindowHandle()); + } + // no native event .. + visibleChanged(true, true); + } + if( !isOffscreenInstance ) { + setAlwaysOnTop0(getWindowHandle(), 0 != ( FLAG_IS_ALWAYSONTOP & flags)); + } + return true; + } + + protected Point getLocationOnScreenImpl(int x, int y) { + Point p = new Point(x, y); + // min val is 0 + p.setX(Math.max(p.getX(), 0)); + p.setY(Math.max(p.getY(), 0)); + + final NativeWindow parent = getParent(); + if( null != parent && 0 != parent.getWindowHandle() ) { + p.translate(parent.getLocationOnScreen(null)); + } + return p; + } + + private Point getTopLevelLocationOnScreen(int x, int y) { + final InsetsImmutable _insets = getInsets(); // zero if undecorated + // client position -> top-level window position + x -= _insets.getLeftWidth() ; + y -= _insets.getTopHeight() ; + return getLocationOnScreenImpl(x, y); + } + + protected void updateInsetsImpl(Insets insets) { + // nop - using event driven insetsChange(..) + } + + @Override + protected void sizeChanged(boolean defer, int newWidth, int newHeight, boolean force) { + if(getWidth() != newWidth || getHeight() != newHeight) { + final Point p0S = getTopLevelLocationOnScreen(getX(), getY()); + setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), p0S.getX(), p0S.getY()); + } + super.sizeChanged(defer, newWidth, newHeight, force); + } + + @Override + protected void positionChanged(boolean defer, int newX, int newY) { + // passed coordinates are in screen position of the client area + if(getWindowHandle()!=0) { + // screen position -> window position + Point absPos = new Point(newX, newY); + final NativeWindow parent = getParent(); + if(null != parent) { + absPos.translate( parent.getLocationOnScreen(null).scale(-1, -1) ); + } + super.positionChanged(defer, absPos.getX(), absPos.getY()); + } + } + + @Override + protected boolean setPointerVisibleImpl(final boolean pointerVisible) { + if( !isOffscreenInstance ) { + return setPointerVisible0(getWindowHandle(), hasFocus(), pointerVisible); + } // else may need offscreen solution ? FIXME + return false; + } + + @Override + protected boolean confinePointerImpl(final boolean confine) { + if( !isOffscreenInstance ) { + return confinePointer0(getWindowHandle(), confine); + } // else may need offscreen solution ? FIXME + return false; + } + + @Override + protected void warpPointerImpl(final int x, final int y) { + if( !isOffscreenInstance ) { + warpPointer0(getWindowHandle(), x, y); + } // else may need offscreen solution ? FIXME + } + + @Override + public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { + // Note that we send the key char for the key code on this + // platform -- we do not get any useful key codes out of the system + final int keyCode2 = MacKeyUtil.validateKeyCode(keyCode, keyChar); + final boolean valid = validateKeyEvent(eventType, modifiers, keyCode); + if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.sendKeyEvent "+Thread.currentThread().getName()+" char: 0x"+Integer.toHexString(keyChar)+", code 0x"+Integer.toHexString(keyCode)+" -> 0x"+Integer.toHexString(keyCode2)+", valid "+valid); + if(valid) { + // only deliver keyChar on key Typed events, harmonizing platform behavior + keyChar = KeyEvent.EVENT_KEY_TYPED == eventType ? keyChar : (char)-1; + super.sendKeyEvent(eventType, modifiers, keyCode2, keyChar); + } + } + + @Override + public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) { + // Note that we send the key char for the key code on this + // platform -- we do not get any useful key codes out of the system + final int keyCode2 = MacKeyUtil.validateKeyCode(keyCode, keyChar); + final boolean valid = validateKeyEvent(eventType, modifiers, keyCode); + if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.enqueueKeyEvent "+Thread.currentThread().getName()+" char: 0x"+Integer.toHexString(keyChar)+", code 0x"+Integer.toHexString(keyCode)+" -> 0x"+Integer.toHexString(keyCode2)+", valid "+valid); + if(valid) { + // only deliver keyChar on key Typed events, harmonizing platform behavior + keyChar = KeyEvent.EVENT_KEY_TYPED == eventType ? keyChar : (char)-1; + super.enqueueKeyEvent(wait, eventType, modifiers, keyCode2, keyChar); + } + } + + private int keyDownModifiers = 0; + private int keyDownCode = 0; + + private boolean validateKeyEvent(int eventType, int modifiers, int keyCode) { + switch(eventType) { + case KeyEvent.EVENT_KEY_PRESSED: + keyDownModifiers = modifiers; + keyDownCode = keyCode; + return true; + case KeyEvent.EVENT_KEY_RELEASED: + return keyDownModifiers == modifiers && keyDownCode == keyCode; + case KeyEvent.EVENT_KEY_TYPED: + final boolean matchKeyDown = keyDownModifiers == modifiers && keyDownCode == keyCode; + keyDownModifiers = 0; + keyDownCode = 0; + return matchKeyDown; + default: + throw new NativeWindowException("Unexpected key event type " + eventType); + } + } + + + //---------------------------------------------------------------------- + // Internals only + // + + private void createWindow(final boolean offscreenInstance, final boolean recreate, + final PointImmutable pS, final int width, final int height, + final boolean fullscreen) { + + if(0!=getWindowHandle() && !recreate) { + return; + } + + try { + if(0!=getWindowHandle()) { + // save the view .. close the window + surfaceHandle = changeContentView0(getParentWindowHandle(), getWindowHandle(), 0); + if(recreate && 0==surfaceHandle) { + throw new NativeWindowException("Internal Error - recreate, window but no view"); + } + close0(getWindowHandle()); + setWindowHandle(0); + } else { + surfaceHandle = 0; + } + setWindowHandle(createWindow0(getParentWindowHandle(), + pS.getX(), pS.getY(), width, height, + (getGraphicsConfiguration().getChosenCapabilities().isBackgroundOpaque() && !offscreenInstance), + fullscreen, + ((isUndecorated() || offscreenInstance) ? + NSBorderlessWindowMask : + NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask), + NSBackingStoreBuffered, + getScreen().getIndex(), surfaceHandle)); + if (getWindowHandle() == 0) { + throw new NativeWindowException("Could create native window "+Thread.currentThread().getName()+" "+this); + } + surfaceHandle = contentView0(getWindowHandle()); + if( offscreenInstance ) { + orderOut0(0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle()); + } else { + setTitle0(getWindowHandle(), getTitle()); + } + } catch (Exception ie) { + ie.printStackTrace(); + } + } + + protected static native boolean initIDs0(); + private native long createWindow0(long parentWindowHandle, int x, int y, int w, int h, + boolean opaque, boolean fullscreen, int windowStyle, + int backingStoreType, + int screen_idx, long view); + private native boolean lockSurface0(long window); + private native void unlockSurface0(long window); + private native void requestFocus0(long window, boolean force); + private native void resignFocus0(long window); + /** in case of a child window, it actually only issues orderBack(..) */ + private native void orderOut0(long window); + private native void orderFront0(long window); + private native void close0(long window); + private native void setTitle0(long window, String title); + private native long contentView0(long window); + private native long changeContentView0(long parentWindowOrViewHandle, long window, long view); + private native void setContentSize0(long window, int w, int h); + private native void setFrameTopLeftPoint0(long parentWindowHandle, long window, int x, int y); + private native void setAlwaysOnTop0(long window, boolean atop); + private static native Object getLocationOnScreen0(long windowHandle, int src_x, int src_y); + private static native boolean setPointerVisible0(long windowHandle, boolean hasFocus, boolean visible); + private static native boolean confinePointer0(long windowHandle, boolean confine); + private static native void warpPointer0(long windowHandle, int x, int y); + + // Window styles + private static final int NSBorderlessWindowMask = 0; + private static final int NSTitledWindowMask = 1 << 0; + private static final int NSClosableWindowMask = 1 << 1; + private static final int NSMiniaturizableWindowMask = 1 << 2; + private static final int NSResizableWindowMask = 1 << 3; + + // Window backing store types + private static final int NSBackingStoreRetained = 0; + private static final int NSBackingStoreNonretained = 1; + private static final int NSBackingStoreBuffered = 2; + + private volatile long surfaceHandle = 0; + private long sscSurfaceHandle = 0; + private boolean isOffscreenInstance = false; + +} diff --git a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java new file mode 100644 index 000000000..579ec5be8 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.windows; + +import jogamp.nativewindow.windows.RegisteredClass; +import jogamp.nativewindow.windows.RegisteredClassFactory; +import jogamp.newt.DisplayImpl; +import jogamp.newt.NEWTJNILibLoader; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.NativeWindowException; + +import com.jogamp.nativewindow.windows.WindowsGraphicsDevice; + +public class DisplayDriver extends DisplayImpl { + + private static final String newtClassBaseName = "_newt_clazz" ; + private static RegisteredClassFactory sharedClassFactory; + + static { + NEWTJNILibLoader.loadNEWT(); + + if (!WindowDriver.initIDs0()) { + throw new NativeWindowException("Failed to initialize WindowsWindow jmethodIDs"); + } + sharedClassFactory = new RegisteredClassFactory(newtClassBaseName, WindowDriver.getNewtWndProc0()); + } + + public static void initSingleton() { + // just exist to ensure static init has been run + } + + private RegisteredClass sharedClass; + + public DisplayDriver() { + } + + protected void createNativeImpl() { + sharedClass = sharedClassFactory.getSharedClass(); + aDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); + } + + protected void closeNativeImpl() { + sharedClassFactory.releaseSharedClass(); + } + + protected void dispatchMessagesNative() { + DispatchMessages0(); + } + + protected long getHInstance() { + return sharedClass.getHandle(); + } + + protected String getWindowClassName() { + return sharedClass.getName(); + } + + //---------------------------------------------------------------------- + // Internals only + // + private static native void DispatchMessages0(); +} + diff --git a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java new file mode 100644 index 000000000..948b29460 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package jogamp.newt.driver.windows; + +import javax.media.nativewindow.DefaultGraphicsScreen; +import javax.media.nativewindow.util.Dimension; +import javax.media.nativewindow.util.Point; + +import jogamp.newt.ScreenImpl; + +import com.jogamp.newt.ScreenMode; +import com.jogamp.newt.util.ScreenModeUtil; + +public class ScreenDriver extends ScreenImpl { + + static { + DisplayDriver.initSingleton(); + } + + public ScreenDriver() { + } + + protected void createNativeImpl() { + aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx); + } + + protected void closeNativeImpl() { + } + + private int[] getScreenModeIdx(int idx) { + int[] modeProps = getScreenMode0(screen_idx, idx); + if (null == modeProps || 0 == modeProps.length) { + return null; + } + if(modeProps.length < ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL) { + throw new RuntimeException("properties array too short, should be >= "+ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+modeProps.length); + } + return modeProps; + } + + private int nativeModeIdx; + + protected int[] getScreenModeFirstImpl() { + nativeModeIdx = 0; + return getScreenModeNextImpl(); + } + + protected int[] getScreenModeNextImpl() { + int[] modeProps = getScreenModeIdx(nativeModeIdx); + if (null != modeProps && 0 < modeProps.length) { + nativeModeIdx++; + return modeProps; + } + return null; + } + + protected ScreenMode getCurrentScreenModeImpl() { + int[] modeProps = getScreenModeIdx(-1); + if (null != modeProps && 0 < modeProps.length) { + return ScreenModeUtil.streamIn(modeProps, 0); + } + return null; + } + + protected boolean setCurrentScreenModeImpl(ScreenMode sm) { + return setScreenMode0(screen_idx, + sm.getMonitorMode().getSurfaceSize().getResolution().getWidth(), + sm.getMonitorMode().getSurfaceSize().getResolution().getHeight(), + sm.getMonitorMode().getSurfaceSize().getBitsPerPixel(), + sm.getMonitorMode().getRefreshRate(), + sm.getRotation()); + } + + protected int validateScreenIndex(int idx) { + return 0; // big-desktop, only one screen available + } + + protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { + virtualOrigin.setX(getOriginX0(screen_idx)); + virtualOrigin.setY(getOriginY0(screen_idx)); + virtualSize.setWidth(getWidthImpl0(screen_idx)); + virtualSize.setHeight(getHeightImpl0(screen_idx)); + } + + // Native calls + private native int getOriginX0(int screen_idx); + private native int getOriginY0(int screen_idx); + private native int getWidthImpl0(int scrn_idx); + private native int getHeightImpl0(int scrn_idx); + + private native int[] getScreenMode0(int screen_index, int mode_index); + private native boolean setScreenMode0(int screen_index, int width, int height, int bits, int freq, int rot); +} diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java new file mode 100644 index 000000000..39ea54575 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.windows; + +import jogamp.nativewindow.windows.GDI; +import jogamp.nativewindow.windows.GDIUtil; +import jogamp.newt.WindowImpl; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.GraphicsConfigurationFactory; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.VisualIDHolder; +import javax.media.nativewindow.util.Insets; +import javax.media.nativewindow.util.InsetsImmutable; +import javax.media.nativewindow.util.Point; + +import com.jogamp.newt.event.KeyEvent; +import com.jogamp.newt.event.MouseAdapter; +import com.jogamp.newt.event.MouseEvent; + +public class WindowDriver extends WindowImpl { + + private long hmon; + private long hdc; + private long hdc_old; + private long windowHandleClose; + + static { + DisplayDriver.initSingleton(); + } + + public WindowDriver() { + } + + @Override + protected int lockSurfaceImpl() { + if (0 != hdc) { + throw new InternalError("surface not released"); + } + hdc = GDI.GetDC(getWindowHandle()); + hmon = MonitorFromWindow0(getWindowHandle()); + + // return ( 0 == hdc ) ? LOCK_SURFACE_NOT_READY : ( hdc_old != hdc ) ? LOCK_SURFACE_CHANGED : LOCK_SUCCESS ; + if( 0 == hdc ) { + return LOCK_SURFACE_NOT_READY; + } + if( hdc_old == hdc ) { + return LOCK_SUCCESS; + } + if(DEBUG_IMPLEMENTATION) { + System.err.println("WindowsWindow: surface change "+toHexString(hdc_old)+" -> "+toHexString(hdc)); + // Thread.dumpStack(); + } + return LOCK_SURFACE_CHANGED; + } + + @Override + protected void unlockSurfaceImpl() { + if (0 != hdc) { + GDI.ReleaseDC(getWindowHandle(), hdc); + hdc_old = hdc; + hdc=0; + } + } + + @Override + public final long getSurfaceHandle() { + return hdc; + } + + @Override + public boolean hasDeviceChanged() { + if(0!=getWindowHandle()) { + long _hmon = MonitorFromWindow0(getWindowHandle()); + if (hmon != _hmon) { + if(DEBUG_IMPLEMENTATION) { + System.err.println("Info: Window Device Changed "+Thread.currentThread().getName()+ + ", HMON "+toHexString(hmon)+" -> "+toHexString(_hmon)); + // Thread.dumpStack(); + } + hmon = _hmon; + return true; + } + } + return false; + } + + protected void createNativeImpl() { + final ScreenDriver screen = (ScreenDriver) getScreen(); + final DisplayDriver display = (DisplayDriver) screen.getDisplay(); + final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration( + capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED); + if (null == cfg) { + throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); + } + setGraphicsConfiguration(cfg); + final int flags = getReconfigureFlags(0, true) & + ( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ; + setWindowHandle(CreateWindow0(display.getHInstance(), display.getWindowClassName(), display.getWindowClassName(), + getParentWindowHandle(), getX(), getY(), getWidth(), getHeight(), autoPosition(), flags)); + if (getWindowHandle() == 0) { + throw new NativeWindowException("Error creating window"); + } + windowHandleClose = getWindowHandle(); + addMouseListener(new MouseTracker()); + + if(DEBUG_IMPLEMENTATION) { + Exception e = new Exception("Info: Window new window handle "+Thread.currentThread().getName()+ + " (Parent HWND "+toHexString(getParentWindowHandle())+ + ") : HWND "+toHexString(getWindowHandle())+", "+Thread.currentThread()); + e.printStackTrace(); + } + } + + class MouseTracker extends MouseAdapter { + public void mouseEntered(MouseEvent e) { + WindowDriver.trackPointerLeave0(WindowDriver.this.getWindowHandle()); + } + } + + protected void closeNativeImpl() { + if(windowHandleClose != 0) { + if (hdc != 0) { + try { + GDI.ReleaseDC(windowHandleClose, hdc); + } catch (Throwable t) { + if(DEBUG_IMPLEMENTATION) { + Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t); + e.printStackTrace(); + } + } + } + try { + GDI.SetParent(windowHandleClose, 0); // detach first, experience hang w/ SWT parent + GDI.DestroyWindow(windowHandleClose); + } catch (Throwable t) { + if(DEBUG_IMPLEMENTATION) { + Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t); + e.printStackTrace(); + } + } finally { + windowHandleClose = 0; + } + } + hdc = 0; + hdc_old = 0; + } + + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + if(DEBUG_IMPLEMENTATION) { + System.err.println("WindowsWindow reconfig: "+x+"/"+y+" "+width+"x"+height+", "+ + getReconfigureFlagsAsString(null, flags)); + } + + if(0 == ( FLAG_IS_UNDECORATED & flags)) { + final InsetsImmutable i = getInsets(); + + // client position -> top-level window position + x -= i.getLeftWidth() ; + y -= i.getTopHeight() ; + + if(0 top-level window size + width += i.getTotalWidth(); + height += i.getTotalHeight(); + } + } + reconfigureWindow0( getParentWindowHandle(), getWindowHandle(), x, y, width, height, flags); + + if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { + visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); + } + return true; + } + + protected void requestFocusImpl(boolean force) { + requestFocus0(getWindowHandle(), force); + } + + @Override + protected void setTitleImpl(final String title) { + setTitle0(getWindowHandle(), title); + } + + @Override + protected boolean setPointerVisibleImpl(final boolean pointerVisible) { + final Boolean[] res = new Boolean[] { Boolean.FALSE }; + + this.runOnEDTIfAvail(true, new Runnable() { + public void run() { + res[0] = Boolean.valueOf(setPointerVisible0(getWindowHandle(), pointerVisible)); + } + }); + return res[0].booleanValue(); + } + + @Override + protected boolean confinePointerImpl(final boolean confine) { + final Boolean[] res = new Boolean[] { Boolean.FALSE }; + + this.runOnEDTIfAvail(true, new Runnable() { + public void run() { + final Point p0 = getLocationOnScreenImpl(0, 0); + res[0] = Boolean.valueOf(confinePointer0(getWindowHandle(), confine, + p0.getX(), p0.getY(), p0.getX()+getWidth(), p0.getY()+getHeight())); + } + }); + return res[0].booleanValue(); + } + + @Override + protected void warpPointerImpl(final int x, final int y) { + this.runOnEDTIfAvail(true, new Runnable() { + public void run() { + final Point sPos = getLocationOnScreenImpl(x, y); + warpPointer0(getWindowHandle(), sPos.getX(), sPos.getY()); + } + }); + return; + } + + protected Point getLocationOnScreenImpl(int x, int y) { + return GDIUtil.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y); + } + + protected void updateInsetsImpl(Insets insets) { + // nop - using event driven insetsChange(..) + } + + private final int validateKeyCode(int eventType, int keyCode) { + switch(eventType) { + case KeyEvent.EVENT_KEY_PRESSED: + lastPressedKeyCode = keyCode; + break; + case KeyEvent.EVENT_KEY_TYPED: + if(-1==keyCode) { + keyCode = lastPressedKeyCode; + } + lastPressedKeyCode = -1; + break; + } + return keyCode; + } + private int lastPressedKeyCode = 0; + + @Override + public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { + // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform + keyCode = validateKeyCode(eventType, keyCode); + super.sendKeyEvent(eventType, modifiers, keyCode, keyChar); + } + + @Override + public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) { + // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform + keyCode = validateKeyCode(eventType, keyCode); + super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar); + } + + //---------------------------------------------------------------------- + // Internals only + // + protected static native boolean initIDs0(); + protected static native long getNewtWndProc0(); + + private native long CreateWindow0(long hInstance, String wndClassName, String wndName, + long parentWindowHandle, + int x, int y, int width, int height, boolean autoPosition, int flags); + private native long MonitorFromWindow0(long windowHandle); + private native void reconfigureWindow0(long parentWindowHandle, long windowHandle, + int x, int y, int width, int height, int flags); + private static native void setTitle0(long windowHandle, String title); + private native void requestFocus0(long windowHandle, boolean force); + + private static native boolean setPointerVisible0(long windowHandle, boolean visible); + private static native boolean confinePointer0(long windowHandle, boolean grab, int l, int t, int r, int b); + private static native void warpPointer0(long windowHandle, int x, int y); + private static native void trackPointerLeave0(long windowHandle); +} diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsDisplay.java b/src/newt/classes/jogamp/newt/driver/windows/WindowsDisplay.java deleted file mode 100644 index 225b115e4..000000000 --- a/src/newt/classes/jogamp/newt/driver/windows/WindowsDisplay.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.windows; - -import jogamp.nativewindow.windows.RegisteredClass; -import jogamp.nativewindow.windows.RegisteredClassFactory; -import jogamp.newt.DisplayImpl; -import jogamp.newt.NEWTJNILibLoader; -import javax.media.nativewindow.AbstractGraphicsDevice; -import javax.media.nativewindow.NativeWindowException; - -import com.jogamp.nativewindow.windows.WindowsGraphicsDevice; - -public class WindowsDisplay extends DisplayImpl { - - private static final String newtClassBaseName = "_newt_clazz" ; - private static RegisteredClassFactory sharedClassFactory; - - static { - NEWTJNILibLoader.loadNEWT(); - - if (!WindowsWindow.initIDs0()) { - throw new NativeWindowException("Failed to initialize WindowsWindow jmethodIDs"); - } - sharedClassFactory = new RegisteredClassFactory(newtClassBaseName, WindowsWindow.getNewtWndProc0()); - } - - public static void initSingleton() { - // just exist to ensure static init has been run - } - - private RegisteredClass sharedClass; - - public WindowsDisplay() { - } - - protected void createNativeImpl() { - sharedClass = sharedClassFactory.getSharedClass(); - aDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); - } - - protected void closeNativeImpl() { - sharedClassFactory.releaseSharedClass(); - } - - protected void dispatchMessagesNative() { - DispatchMessages0(); - } - - protected long getHInstance() { - return sharedClass.getHandle(); - } - - protected String getWindowClassName() { - return sharedClass.getName(); - } - - //---------------------------------------------------------------------- - // Internals only - // - private static native void DispatchMessages0(); -} - diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java b/src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java deleted file mode 100644 index f8bce9da3..000000000 --- a/src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ -package jogamp.newt.driver.windows; - -import javax.media.nativewindow.DefaultGraphicsScreen; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.Point; - -import jogamp.newt.ScreenImpl; - -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.util.ScreenModeUtil; - -public class WindowsScreen extends ScreenImpl { - - static { - WindowsDisplay.initSingleton(); - } - - public WindowsScreen() { - } - - protected void createNativeImpl() { - aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx); - } - - protected void closeNativeImpl() { - } - - private int[] getScreenModeIdx(int idx) { - int[] modeProps = getScreenMode0(screen_idx, idx); - if (null == modeProps || 0 == modeProps.length) { - return null; - } - if(modeProps.length < ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL) { - throw new RuntimeException("properties array too short, should be >= "+ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+modeProps.length); - } - return modeProps; - } - - private int nativeModeIdx; - - protected int[] getScreenModeFirstImpl() { - nativeModeIdx = 0; - return getScreenModeNextImpl(); - } - - protected int[] getScreenModeNextImpl() { - int[] modeProps = getScreenModeIdx(nativeModeIdx); - if (null != modeProps && 0 < modeProps.length) { - nativeModeIdx++; - return modeProps; - } - return null; - } - - protected ScreenMode getCurrentScreenModeImpl() { - int[] modeProps = getScreenModeIdx(-1); - if (null != modeProps && 0 < modeProps.length) { - return ScreenModeUtil.streamIn(modeProps, 0); - } - return null; - } - - protected boolean setCurrentScreenModeImpl(ScreenMode sm) { - return setScreenMode0(screen_idx, - sm.getMonitorMode().getSurfaceSize().getResolution().getWidth(), - sm.getMonitorMode().getSurfaceSize().getResolution().getHeight(), - sm.getMonitorMode().getSurfaceSize().getBitsPerPixel(), - sm.getMonitorMode().getRefreshRate(), - sm.getRotation()); - } - - protected int validateScreenIndex(int idx) { - return 0; // big-desktop, only one screen available - } - - protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { - virtualOrigin.setX(getOriginX0(screen_idx)); - virtualOrigin.setY(getOriginY0(screen_idx)); - virtualSize.setWidth(getWidthImpl0(screen_idx)); - virtualSize.setHeight(getHeightImpl0(screen_idx)); - } - - // Native calls - private native int getOriginX0(int screen_idx); - private native int getOriginY0(int screen_idx); - private native int getWidthImpl0(int scrn_idx); - private native int getHeightImpl0(int scrn_idx); - - private native int[] getScreenMode0(int screen_index, int mode_index); - private native boolean setScreenMode0(int screen_index, int width, int height, int bits, int freq, int rot); -} diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java b/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java deleted file mode 100644 index 6a8c81f3d..000000000 --- a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.windows; - -import jogamp.nativewindow.windows.GDI; -import jogamp.nativewindow.windows.GDIUtil; -import jogamp.newt.WindowImpl; - -import javax.media.nativewindow.AbstractGraphicsConfiguration; -import javax.media.nativewindow.GraphicsConfigurationFactory; -import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.VisualIDHolder; -import javax.media.nativewindow.util.Insets; -import javax.media.nativewindow.util.InsetsImmutable; -import javax.media.nativewindow.util.Point; - -import com.jogamp.newt.event.KeyEvent; -import com.jogamp.newt.event.MouseAdapter; -import com.jogamp.newt.event.MouseEvent; - -public class WindowsWindow extends WindowImpl { - - private long hmon; - private long hdc; - private long hdc_old; - private long windowHandleClose; - - static { - WindowsDisplay.initSingleton(); - } - - public WindowsWindow() { - } - - @Override - protected int lockSurfaceImpl() { - if (0 != hdc) { - throw new InternalError("surface not released"); - } - hdc = GDI.GetDC(getWindowHandle()); - hmon = MonitorFromWindow0(getWindowHandle()); - - // return ( 0 == hdc ) ? LOCK_SURFACE_NOT_READY : ( hdc_old != hdc ) ? LOCK_SURFACE_CHANGED : LOCK_SUCCESS ; - if( 0 == hdc ) { - return LOCK_SURFACE_NOT_READY; - } - if( hdc_old == hdc ) { - return LOCK_SUCCESS; - } - if(DEBUG_IMPLEMENTATION) { - System.err.println("WindowsWindow: surface change "+toHexString(hdc_old)+" -> "+toHexString(hdc)); - // Thread.dumpStack(); - } - return LOCK_SURFACE_CHANGED; - } - - @Override - protected void unlockSurfaceImpl() { - if (0 != hdc) { - GDI.ReleaseDC(getWindowHandle(), hdc); - hdc_old = hdc; - hdc=0; - } - } - - @Override - public final long getSurfaceHandle() { - return hdc; - } - - @Override - public boolean hasDeviceChanged() { - if(0!=getWindowHandle()) { - long _hmon = MonitorFromWindow0(getWindowHandle()); - if (hmon != _hmon) { - if(DEBUG_IMPLEMENTATION) { - System.err.println("Info: Window Device Changed "+Thread.currentThread().getName()+ - ", HMON "+toHexString(hmon)+" -> "+toHexString(_hmon)); - // Thread.dumpStack(); - } - hmon = _hmon; - return true; - } - } - return false; - } - - protected void createNativeImpl() { - final WindowsScreen screen = (WindowsScreen) getScreen(); - final WindowsDisplay display = (WindowsDisplay) screen.getDisplay(); - final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration( - capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED); - if (null == cfg) { - throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); - } - setGraphicsConfiguration(cfg); - final int flags = getReconfigureFlags(0, true) & - ( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ; - setWindowHandle(CreateWindow0(display.getHInstance(), display.getWindowClassName(), display.getWindowClassName(), - getParentWindowHandle(), getX(), getY(), getWidth(), getHeight(), autoPosition(), flags)); - if (getWindowHandle() == 0) { - throw new NativeWindowException("Error creating window"); - } - windowHandleClose = getWindowHandle(); - addMouseListener(new MouseTracker()); - - if(DEBUG_IMPLEMENTATION) { - Exception e = new Exception("Info: Window new window handle "+Thread.currentThread().getName()+ - " (Parent HWND "+toHexString(getParentWindowHandle())+ - ") : HWND "+toHexString(getWindowHandle())+", "+Thread.currentThread()); - e.printStackTrace(); - } - } - - class MouseTracker extends MouseAdapter { - public void mouseEntered(MouseEvent e) { - WindowsWindow.trackPointerLeave0(WindowsWindow.this.getWindowHandle()); - } - } - - protected void closeNativeImpl() { - if(windowHandleClose != 0) { - if (hdc != 0) { - try { - GDI.ReleaseDC(windowHandleClose, hdc); - } catch (Throwable t) { - if(DEBUG_IMPLEMENTATION) { - Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t); - e.printStackTrace(); - } - } - } - try { - GDI.SetParent(windowHandleClose, 0); // detach first, experience hang w/ SWT parent - GDI.DestroyWindow(windowHandleClose); - } catch (Throwable t) { - if(DEBUG_IMPLEMENTATION) { - Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t); - e.printStackTrace(); - } - } finally { - windowHandleClose = 0; - } - } - hdc = 0; - hdc_old = 0; - } - - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { - if(DEBUG_IMPLEMENTATION) { - System.err.println("WindowsWindow reconfig: "+x+"/"+y+" "+width+"x"+height+", "+ - getReconfigureFlagsAsString(null, flags)); - } - - if(0 == ( FLAG_IS_UNDECORATED & flags)) { - final InsetsImmutable i = getInsets(); - - // client position -> top-level window position - x -= i.getLeftWidth() ; - y -= i.getTopHeight() ; - - if(0 top-level window size - width += i.getTotalWidth(); - height += i.getTotalHeight(); - } - } - reconfigureWindow0( getParentWindowHandle(), getWindowHandle(), x, y, width, height, flags); - - if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { - visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags)); - } - return true; - } - - protected void requestFocusImpl(boolean force) { - requestFocus0(getWindowHandle(), force); - } - - @Override - protected void setTitleImpl(final String title) { - setTitle0(getWindowHandle(), title); - } - - @Override - protected boolean setPointerVisibleImpl(final boolean pointerVisible) { - final Boolean[] res = new Boolean[] { Boolean.FALSE }; - - this.runOnEDTIfAvail(true, new Runnable() { - public void run() { - res[0] = Boolean.valueOf(setPointerVisible0(getWindowHandle(), pointerVisible)); - } - }); - return res[0].booleanValue(); - } - - @Override - protected boolean confinePointerImpl(final boolean confine) { - final Boolean[] res = new Boolean[] { Boolean.FALSE }; - - this.runOnEDTIfAvail(true, new Runnable() { - public void run() { - final Point p0 = getLocationOnScreenImpl(0, 0); - res[0] = Boolean.valueOf(confinePointer0(getWindowHandle(), confine, - p0.getX(), p0.getY(), p0.getX()+getWidth(), p0.getY()+getHeight())); - } - }); - return res[0].booleanValue(); - } - - @Override - protected void warpPointerImpl(final int x, final int y) { - this.runOnEDTIfAvail(true, new Runnable() { - public void run() { - final Point sPos = getLocationOnScreenImpl(x, y); - warpPointer0(getWindowHandle(), sPos.getX(), sPos.getY()); - } - }); - return; - } - - protected Point getLocationOnScreenImpl(int x, int y) { - return GDIUtil.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y); - } - - protected void updateInsetsImpl(Insets insets) { - // nop - using event driven insetsChange(..) - } - - private final int validateKeyCode(int eventType, int keyCode) { - switch(eventType) { - case KeyEvent.EVENT_KEY_PRESSED: - lastPressedKeyCode = keyCode; - break; - case KeyEvent.EVENT_KEY_TYPED: - if(-1==keyCode) { - keyCode = lastPressedKeyCode; - } - lastPressedKeyCode = -1; - break; - } - return keyCode; - } - private int lastPressedKeyCode = 0; - - @Override - public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { - // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform - keyCode = validateKeyCode(eventType, keyCode); - super.sendKeyEvent(eventType, modifiers, keyCode, keyChar); - } - - @Override - public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) { - // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform - keyCode = validateKeyCode(eventType, keyCode); - super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar); - } - - //---------------------------------------------------------------------- - // Internals only - // - protected static native boolean initIDs0(); - protected static native long getNewtWndProc0(); - - private native long CreateWindow0(long hInstance, String wndClassName, String wndName, - long parentWindowHandle, - int x, int y, int width, int height, boolean autoPosition, int flags); - private native long MonitorFromWindow0(long windowHandle); - private native void reconfigureWindow0(long parentWindowHandle, long windowHandle, - int x, int y, int width, int height, int flags); - private static native void setTitle0(long windowHandle, String title); - private native void requestFocus0(long windowHandle, boolean force); - - private static native boolean setPointerVisible0(long windowHandle, boolean visible); - private static native boolean confinePointer0(long windowHandle, boolean grab, int l, int t, int r, int b); - private static native void warpPointer0(long windowHandle, int x, int y); - private static native void trackPointerLeave0(long windowHandle); -} diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java new file mode 100644 index 000000000..714324d63 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.x11; + +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.NativeWindowFactory; + +import com.jogamp.nativewindow.x11.X11GraphicsDevice; + +import jogamp.nativewindow.x11.X11Util; +import jogamp.newt.DisplayImpl; +import jogamp.newt.NEWTJNILibLoader; + +public class DisplayDriver extends DisplayImpl { + + static { + NEWTJNILibLoader.loadNEWT(); + + if ( !initIDs0(X11Util.XERROR_STACKDUMP) ) { + throw new NativeWindowException("Failed to initialize X11Display jmethodIDs"); + } + + if (!WindowDriver.initIDs0()) { + throw new NativeWindowException("Failed to initialize X11Window jmethodIDs"); + } + } + + public static void initSingleton() { + // just exist to ensure static init has been run + } + + + public DisplayDriver() { + } + + public String validateDisplayName(String name, long handle) { + return X11Util.validateDisplayName(name, handle); + } + + /** + * {@inheritDoc} + * + * We use a private non-shared X11 Display instance for EDT window operations and one for exposed animation, eg. OpenGL. + *

+ * In case {@link X11Util#HAS_XLOCKDISPLAY_BUG} and {@link X11Util#XINITTHREADS_ALWAYS_ENABLED}, + * we use null locking. Even though this seems not to be rational, it gives most stable results on all platforms. + *

+ *

+ * Otherwise we use basic locking via the constructor {@link X11GraphicsDevice#X11GraphicsDevice(long, int, boolean)}, + * since it is possible to share this device via {@link com.jogamp.newt.NewtFactory#createDisplay(String, boolean)}. + *

+ */ + @SuppressWarnings("unused") + protected void createNativeImpl() { + long handle = X11Util.openDisplay(name); + if( 0 == handle ) { + throw new RuntimeException("Error creating display(Win): "+name); + } + if(USE_SEPARATE_DISPLAY_FOR_EDT) { + edtDisplayHandle = X11Util.openDisplay(name); + if( 0 == edtDisplayHandle ) { + X11Util.closeDisplay(handle); + throw new RuntimeException("Error creating display(EDT): "+name); + } + } else { + edtDisplayHandle = handle; + } + try { + CompleteDisplay0(edtDisplayHandle); + } catch(RuntimeException e) { + closeNativeImpl(); + throw e; + } + + // see API doc above! + if(X11Util.XINITTHREADS_ALWAYS_ENABLED && X11Util.HAS_XLOCKDISPLAY_BUG) { + aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock(), false); + } else { + aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, false); + } + } + + protected void closeNativeImpl() { + DisplayRelease0(edtDisplayHandle, javaObjectAtom, windowDeleteAtom); + javaObjectAtom = 0; + windowDeleteAtom = 0; + // closing using ATI driver bug 'same order' + final long handle = getHandle(); + X11Util.closeDisplay(handle); + if(handle != edtDisplayHandle) { + X11Util.closeDisplay(edtDisplayHandle); + } + edtDisplayHandle = 0; + } + + protected void dispatchMessagesNative() { + if(0 != edtDisplayHandle) { + DispatchMessages0(edtDisplayHandle, javaObjectAtom, windowDeleteAtom); + } + } + + protected long getEDTHandle() { return edtDisplayHandle; } + protected long getJavaObjectAtom() { return javaObjectAtom; } + protected long getWindowDeleteAtom() { return windowDeleteAtom; } + + //---------------------------------------------------------------------- + // Internals only + // + private static native boolean initIDs0(boolean debug); + + private native void CompleteDisplay0(long handle); + + private void displayCompleted(long javaObjectAtom, long windowDeleteAtom) { + this.javaObjectAtom=javaObjectAtom; + this.windowDeleteAtom=windowDeleteAtom; + } + private native void DisplayRelease0(long handle, long javaObjectAtom, long windowDeleteAtom); + + private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom); + + /** + * 2011/06/14 libX11 1.4.2 and libxcb 1.7 bug 20708 - Multithreading Issues w/ OpenGL, .. + * https://bugs.freedesktop.org/show_bug.cgi?id=20708 + * https://jogamp.org/bugzilla/show_bug.cgi?id=502 + * Affects: Ubuntu 11.04, OpenSuSE 11, .. + * Workaround: Using a separate X11 Display connection for event dispatching (EDT) + */ + private final boolean USE_SEPARATE_DISPLAY_FOR_EDT = true; + + private long edtDisplayHandle; + + /** X11 Window delete atom marker used on EDT */ + private long windowDeleteAtom; + + /** X11 Window java object property used on EDT */ + private long javaObjectAtom; +} + diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java new file mode 100644 index 000000000..10f6b84da --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package jogamp.newt.driver.x11; + +import java.util.List; + +import javax.media.nativewindow.util.Dimension; +import javax.media.nativewindow.util.Point; + +import jogamp.nativewindow.x11.X11Util; +import jogamp.newt.DisplayImpl; +import jogamp.newt.DisplayImpl.DisplayRunnable; +import jogamp.newt.ScreenImpl; + +import com.jogamp.nativewindow.x11.X11GraphicsDevice; +import com.jogamp.nativewindow.x11.X11GraphicsScreen; +import com.jogamp.newt.ScreenMode; +import com.jogamp.newt.util.ScreenModeUtil; + +public class ScreenDriver extends ScreenImpl { + + static { + DisplayDriver.initSingleton(); + } + + public ScreenDriver() { + } + + protected void createNativeImpl() { + // validate screen index + Long handle = display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + public Long run(long dpy) { + return new Long(GetScreen0(dpy, screen_idx)); + } } ); + if (handle.longValue() == 0) { + throw new RuntimeException("Error creating screen: " + screen_idx); + } + aScreen = new X11GraphicsScreen((X11GraphicsDevice) getDisplay().getGraphicsDevice(), screen_idx); + } + + protected void closeNativeImpl() { + } + + private int[] nrotations; + private int nrotation_index; + private int nres_number; + private int nres_index; + private int[] nrates; + private int nrate_index; + private int nmode_number; + + protected int[] getScreenModeFirstImpl() { + return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + public int[] run(long dpy) { + // initialize iterators and static data + nrotations = getAvailableScreenModeRotations0(dpy, screen_idx); + if(null==nrotations || 0==nrotations.length) { + return null; + } + nrotation_index = 0; + + nres_number = getNumScreenModeResolutions0(dpy, screen_idx); + if(0==nres_number) { + return null; + } + nres_index = 0; + + nrates = getScreenModeRates0(dpy, screen_idx, nres_index); + if(null==nrates || 0==nrates.length) { + return null; + } + nrate_index = 0; + + nmode_number = 0; + + return getScreenModeNextImpl(); + } } ); + } + + protected int[] getScreenModeNextImpl() { + // assemble: w x h x bpp x f x r + return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + public int[] run(long dpy) { + /** + System.err.println("******** mode: "+nmode_number); + System.err.println("rot "+nrotation_index); + System.err.println("rate "+nrate_index); + System.err.println("res "+nres_index); */ + + int[] res = getScreenModeResolution0(dpy, screen_idx, nres_index); + if(null==res || 0==res.length) { + return null; + } + if(0>=res[0] || 0>=res[1]) { + throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_index+"/"+nres_number); + } + int rate = nrates[nrate_index]; + if(0>=rate) { + rate = default_sm_rate; + if(DEBUG) { + System.err.println("Invalid rate: "+rate+" at index "+nrate_index+"/"+nrates.length+", using default: "+default_sm_rate); + } + } + int rotation = nrotations[nrotation_index]; + + int[] props = new int[ 1 + ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL ]; + int i = 0; + props[i++] = nres_index; // use resolution index, not unique for native -> ScreenMode + props[i++] = 0; // set later for verification of iterator + props[i++] = res[0]; // width + props[i++] = res[1]; // height + props[i++] = default_sm_bpp; // FIXME + props[i++] = res[2]; // widthmm + props[i++] = res[3]; // heightmm + props[i++] = rate; // rate + props[i++] = rotation; + props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i - 1; // count without extra element + + nmode_number++; + + // iteration: r -> f -> bpp -> [w x h] + nrotation_index++; + if(nrotation_index == nrotations.length) { + nrotation_index=0; + nrate_index++; + if(null == nrates || nrate_index == nrates.length){ + nres_index++; + if(nres_index == nres_number) { + // done + nrates=null; + nrotations=null; + return null; + } + + nrates = getScreenModeRates0(dpy, screen_idx, nres_index); + if(null==nrates || 0==nrates.length) { + return null; + } + nrate_index = 0; + } + } + + return props; + } } ); + } + + protected ScreenMode getCurrentScreenModeImpl() { + return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + public ScreenMode run(long dpy) { + long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx); + if(0 == screenConfigHandle) { + return null; + } + int[] res; + int rate, rot; + try { + int resNumber = getNumScreenModeResolutions0(dpy, screen_idx); + if(0==resNumber) { + return null; + } + + int resIdx = getCurrentScreenResolutionIndex0(screenConfigHandle); + if(0>resIdx) { + return null; + } + if(resIdx>=resNumber) { + throw new RuntimeException("Invalid resolution index: ! "+resIdx+" < "+resNumber); + } + res = getScreenModeResolution0(dpy, screen_idx, resIdx); + if(null==res || 0==res.length) { + return null; + } + if(0>=res[0] || 0>=res[1]) { + throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+resIdx+"/"+resNumber); + } + rate = getCurrentScreenRate0(screenConfigHandle); + if(0>rate) { + return null; + } + rot = getCurrentScreenRotation0(screenConfigHandle); + if(0>rot) { + return null; + } + } finally { + freeScreenConfiguration0(screenConfigHandle); + } + int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL]; + int i = 0; + props[i++] = 0; // set later for verification of iterator + props[i++] = res[0]; // width + props[i++] = res[1]; // height + props[i++] = default_sm_bpp; // FIXME + props[i++] = res[2]; // widthmm + props[i++] = res[3]; // heightmm + props[i++] = rate; // rate + props[i++] = rot; + props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i; // count + return ScreenModeUtil.streamIn(props, 0); + } } ); + } + + protected boolean setCurrentScreenModeImpl(final ScreenMode screenMode) { + final List screenModes = this.getScreenModesOrig(); + final int screenModeIdx = screenModes.indexOf(screenMode); + if(0>screenModeIdx) { + throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode); + } + final long t0 = System.currentTimeMillis(); + boolean done = runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + public Boolean run(long dpy) { + boolean done = false; + long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx); + if(0 == screenConfigHandle) { + return Boolean.valueOf(done); + } + try { + int resNumber = getNumScreenModeResolutions0(dpy, screen_idx); + int resIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx); + if(0>resIdx || resIdx>=resNumber) { + throw new RuntimeException("Invalid resolution index: ! 0 < "+resIdx+" < "+resNumber+", screenMode["+screenModeIdx+"] "+screenMode); + } + + final int f = screenMode.getMonitorMode().getRefreshRate(); + final int r = screenMode.getRotation(); + + if( setCurrentScreenModeStart0(dpy, screen_idx, screenConfigHandle, resIdx, f, r) ) { + while(!done && System.currentTimeMillis()-t0 < SCREEN_MODE_CHANGE_TIMEOUT) { + done = setCurrentScreenModePollEnd0(dpy, screen_idx, resIdx, f, r); + if(!done) { + try { Thread.sleep(10); } catch (InterruptedException e) { } + } + } + } + } finally { + freeScreenConfiguration0(screenConfigHandle); + } + return Boolean.valueOf(done); + } + }).booleanValue(); + + if(DEBUG || !done) { + System.err.println("X11Screen.setCurrentScreenModeImpl: TO ("+SCREEN_MODE_CHANGE_TIMEOUT+") reached: "+ + (System.currentTimeMillis()-t0)+"ms; Current: "+getCurrentScreenMode()+"; Desired: "+screenMode); + } + return done; + } + + private class XineramaEnabledQuery implements DisplayImpl.DisplayRunnable { + public Boolean run(long dpy) { + return new Boolean(X11Util.XineramaIsEnabled(dpy)); + } + } + private XineramaEnabledQuery xineramaEnabledQuery = new XineramaEnabledQuery(); + + protected int validateScreenIndex(final int idx) { + if(getDisplay().isNativeValid()) { + return runWithLockedDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx; + } else { + return runWithTempDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx; + } + } + + protected void getVirtualScreenOriginAndSize(final Point virtualOrigin, final Dimension virtualSize) { + display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + public Object run(long dpy) { + virtualOrigin.setX(0); + virtualOrigin.setY(0); + virtualSize.setWidth(getWidth0(dpy, screen_idx)); + virtualSize.setHeight(getHeight0(dpy, screen_idx)); + return null; + } } ); + } + + //---------------------------------------------------------------------- + // Internals only + // + private final T runWithLockedDisplayHandle(DisplayRunnable action) { + return display.runWithLockedDisplayHandle(action); + // return runWithTempDisplayHandle(action); + // return runWithoutLock(action); + } + + private final T runWithTempDisplayHandle(DisplayRunnable action) { + final long displayHandle = X11Util.openDisplay(display.getName()); + if(0 == displayHandle) { + throw new RuntimeException("null device"); + } + T res; + try { + res = action.run(displayHandle); + } finally { + X11Util.closeDisplay(displayHandle); + } + return res; + } + private final T runWithoutLock(DisplayRunnable action) { + return action.run(display.getHandle()); + } + + private static native long GetScreen0(long dpy, int scrn_idx); + + private static native int getWidth0(long display, int scrn_idx); + + private static native int getHeight0(long display, int scrn_idx); + + /** @return int[] { rot1, .. } */ + private static native int[] getAvailableScreenModeRotations0(long display, int screen_index); + + private static native int getNumScreenModeResolutions0(long display, int screen_index); + + /** @return int[] { width, height, widthmm, heightmm } */ + private static native int[] getScreenModeResolution0(long display, int screen_index, int mode_index); + + private static native int[] getScreenModeRates0(long display, int screen_index, int mode_index); + + private static native long getScreenConfiguration0(long display, int screen_index); + private static native void freeScreenConfiguration0(long screenConfiguration); + + private static native int getCurrentScreenResolutionIndex0(long screenConfiguration); + private static native int getCurrentScreenRate0(long screenConfiguration); + private static native int getCurrentScreenRotation0(long screenConfiguration); + + /** needs own Display connection for XRANDR event handling */ + private static native boolean setCurrentScreenModeStart0(long display, int screen_index, long screenConfiguration, int mode_index, int freq, int rot); + private static native boolean setCurrentScreenModePollEnd0(long display, int screen_index, int mode_index, int freq, int rot); +} diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java new file mode 100644 index 000000000..97d1ae3db --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package jogamp.newt.driver.x11; + +import jogamp.nativewindow.x11.X11Lib; +import jogamp.newt.DisplayImpl; +import jogamp.newt.DisplayImpl.DisplayRunnable; +import jogamp.newt.WindowImpl; +import javax.media.nativewindow.*; +import javax.media.nativewindow.VisualIDHolder.VIDType; +import javax.media.nativewindow.util.Insets; +import javax.media.nativewindow.util.InsetsImmutable; +import javax.media.nativewindow.util.Point; + +import com.jogamp.newt.event.MouseEvent; + +public class WindowDriver extends WindowImpl { + private static final String WINDOW_CLASS_NAME = "NewtWindow"; + private static final int X11_WHEEL_ONE_UP_BUTTON = 4; + private static final int X11_WHEEL_ONE_DOWN_BUTTON = 5; + private static final int X11_WHEEL_TWO_UP_BUTTON = 6; + private static final int X11_WHEEL_TWO_DOWN_BUTTON = 7; + + static { + DisplayDriver.initSingleton(); + } + + public WindowDriver() { + } + + protected void createNativeImpl() { + final ScreenDriver screen = (ScreenDriver) getScreen(); + final DisplayDriver display = (DisplayDriver) screen.getDisplay(); + final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice(), capsRequested); + final AbstractGraphicsConfiguration cfg = factory.chooseGraphicsConfiguration( + capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED); + if(DEBUG_IMPLEMENTATION) { + System.err.println("X11Window.createNativeImpl() factory: "+factory+", chosen config: "+cfg); + } + if (null == cfg) { + throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); + } + final int visualID = cfg.getVisualID(VIDType.NATIVE); + if(VisualIDHolder.VID_UNDEFINED == visualID) { + throw new NativeWindowException("Chosen Configuration w/o native visual ID: "+cfg); + } + setGraphicsConfiguration(cfg); + final int flags = getReconfigureFlags(0, true) & + ( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ; + setWindowHandle(CreateWindow0(getParentWindowHandle(), + display.getEDTHandle(), screen.getIndex(), visualID, + display.getJavaObjectAtom(), display.getWindowDeleteAtom(), + getX(), getY(), getWidth(), getHeight(), autoPosition(), flags)); + windowHandleClose = getWindowHandle(); + if (0 == windowHandleClose) { + throw new NativeWindowException("Error creating window"); + } + } + + protected void closeNativeImpl() { + if(0!=windowHandleClose && null!=getScreen() ) { + DisplayDriver display = (DisplayDriver) getScreen().getDisplay(); + try { + CloseWindow0(display.getEDTHandle(), windowHandleClose, + display.getJavaObjectAtom(), display.getWindowDeleteAtom()); + } catch (Throwable t) { + if(DEBUG_IMPLEMENTATION) { + Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t); + e.printStackTrace(); + } + } finally { + windowHandleClose = 0; + } + } + } + + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + if(DEBUG_IMPLEMENTATION) { + System.err.println("X11Window reconfig: "+x+"/"+y+" "+width+"x"+height+", "+ + getReconfigureFlagsAsString(null, flags)); + } + if(0 == ( FLAG_IS_UNDECORATED & flags)) { + final InsetsImmutable i = getInsets(); + + // client position -> top-level window position + x -= i.getLeftWidth() ; + y -= i.getTopHeight() ; + } + final DisplayDriver display = (DisplayDriver) getScreen().getDisplay(); + reconfigureWindow0( getDisplayEDTHandle(), getScreenIndex(), + getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(), + x, y, width, height, flags); + + return true; + } + + protected void reparentNotify(long newParentWindowHandle) { + if(DEBUG_IMPLEMENTATION) { + final long p0 = getParentWindowHandle(); + System.err.println("Window.reparentNotify ("+getThreadName()+"): "+toHexString(p0)+" -> "+toHexString(newParentWindowHandle)); + } + } + + protected void requestFocusImpl(boolean force) { + requestFocus0(getDisplayEDTHandle(), getWindowHandle(), force); + } + + @Override + protected void setTitleImpl(final String title) { + runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + public Object run(long dpy) { + setTitle0(dpy, getWindowHandle(), title); + return null; + } + }); + } + + @Override + protected boolean setPointerVisibleImpl(final boolean pointerVisible) { + return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + public Boolean run(long dpy) { + return Boolean.valueOf(setPointerVisible0(getDisplayEDTHandle(), getWindowHandle(), pointerVisible)); + } + }).booleanValue(); + } + + @Override + protected boolean confinePointerImpl(final boolean confine) { + return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + public Boolean run(long dpy) { + return Boolean.valueOf(confinePointer0(getDisplayEDTHandle(), getWindowHandle(), confine)); + } + }).booleanValue(); + } + + @Override + protected void warpPointerImpl(final int x, final int y) { + runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + public Object run(long dpy) { + warpPointer0(getDisplayEDTHandle(), getWindowHandle(), x, y); + return null; + } + }); + } + + protected Point getLocationOnScreenImpl(final int x, final int y) { + // X11Util.GetRelativeLocation: locks display already ! + return X11Lib.GetRelativeLocation( getScreen().getDisplay().getHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y); + } + + protected void updateInsetsImpl(Insets insets) { + // nop - using event driven insetsChange(..) + } + + protected void doMouseEvent(boolean enqueue, boolean wait, int eventType, int modifiers, + int x, int y, int button, int rotation) { + switch(eventType) { + case MouseEvent.EVENT_MOUSE_PRESSED: + switch(button) { + case X11_WHEEL_ONE_UP_BUTTON: + case X11_WHEEL_ONE_DOWN_BUTTON: + case X11_WHEEL_TWO_UP_BUTTON: + case X11_WHEEL_TWO_DOWN_BUTTON: + // ignore wheel pressed ! + return; + } + break; + case MouseEvent.EVENT_MOUSE_RELEASED: + switch(button) { + case X11_WHEEL_ONE_UP_BUTTON: + eventType = MouseEvent.EVENT_MOUSE_WHEEL_MOVED; + button = 1; + rotation = 1; + break; + case X11_WHEEL_ONE_DOWN_BUTTON: + eventType = MouseEvent.EVENT_MOUSE_WHEEL_MOVED; + button = 1; + rotation = -1; + break; + case X11_WHEEL_TWO_UP_BUTTON: + eventType = MouseEvent.EVENT_MOUSE_WHEEL_MOVED; + button = 2; + rotation = 1; + break; + case X11_WHEEL_TWO_DOWN_BUTTON: + eventType = MouseEvent.EVENT_MOUSE_WHEEL_MOVED; + button = 2; + rotation = -1; + break; + } + break; + } + super.doMouseEvent(enqueue, wait, eventType, modifiers, x, y, button, rotation); + } + + + //---------------------------------------------------------------------- + // Internals only + // + + private static final String getCurrentThreadName() { return Thread.currentThread().getName(); } // Callback for JNI + private static final void dumpStack() { Thread.dumpStack(); } // Callback for JNI + + private final long getDisplayEDTHandle() { + return ((DisplayDriver) getScreen().getDisplay()).getEDTHandle(); + } + private final T runWithLockedDisplayHandle(DisplayRunnable action) { + return ((DisplayImpl) getScreen().getDisplay()).runWithLockedDisplayHandle(action); + // return runWithTempDisplayHandle(action); + } + + protected static native boolean initIDs0(); + + private native long CreateWindow0(long parentWindowHandle, long display, int screen_index, + int visualID, long javaObjectAtom, long windowDeleteAtom, + int x, int y, int width, int height, boolean autoPosition, int flags); + private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom); + private native void reconfigureWindow0(long display, int screen_index, long parentWindowHandle, long windowHandle, + long windowDeleteAtom, int x, int y, int width, int height, int flags); + private native void requestFocus0(long display, long windowHandle, boolean force); + + private static native void setTitle0(long display, long windowHandle, String title); + private static native long getParentWindow0(long display, long windowHandle); + private static native boolean setPointerVisible0(long display, long windowHandle, boolean visible); + private static native boolean confinePointer0(long display, long windowHandle, boolean grab); + private static native void warpPointer0(long display, long windowHandle, int x, int y); + + private long windowHandleClose; +} diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Display.java b/src/newt/classes/jogamp/newt/driver/x11/X11Display.java deleted file mode 100644 index 8243fcf9d..000000000 --- a/src/newt/classes/jogamp/newt/driver/x11/X11Display.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.x11; - -import javax.media.nativewindow.AbstractGraphicsDevice; -import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.NativeWindowFactory; - -import com.jogamp.nativewindow.x11.X11GraphicsDevice; - -import jogamp.nativewindow.x11.X11Util; -import jogamp.newt.DisplayImpl; -import jogamp.newt.NEWTJNILibLoader; - -public class X11Display extends DisplayImpl { - - static { - NEWTJNILibLoader.loadNEWT(); - - if ( !initIDs0(X11Util.XERROR_STACKDUMP) ) { - throw new NativeWindowException("Failed to initialize X11Display jmethodIDs"); - } - - if (!X11Window.initIDs0()) { - throw new NativeWindowException("Failed to initialize X11Window jmethodIDs"); - } - } - - public static void initSingleton() { - // just exist to ensure static init has been run - } - - - public X11Display() { - } - - public String validateDisplayName(String name, long handle) { - return X11Util.validateDisplayName(name, handle); - } - - /** - * {@inheritDoc} - * - * We use a private non-shared X11 Display instance for EDT window operations and one for exposed animation, eg. OpenGL. - *

- * In case {@link X11Util#HAS_XLOCKDISPLAY_BUG} and {@link X11Util#XINITTHREADS_ALWAYS_ENABLED}, - * we use null locking. Even though this seems not to be rational, it gives most stable results on all platforms. - *

- *

- * Otherwise we use basic locking via the constructor {@link X11GraphicsDevice#X11GraphicsDevice(long, int, boolean)}, - * since it is possible to share this device via {@link com.jogamp.newt.NewtFactory#createDisplay(String, boolean)}. - *

- */ - @SuppressWarnings("unused") - protected void createNativeImpl() { - long handle = X11Util.openDisplay(name); - if( 0 == handle ) { - throw new RuntimeException("Error creating display(Win): "+name); - } - if(USE_SEPARATE_DISPLAY_FOR_EDT) { - edtDisplayHandle = X11Util.openDisplay(name); - if( 0 == edtDisplayHandle ) { - X11Util.closeDisplay(handle); - throw new RuntimeException("Error creating display(EDT): "+name); - } - } else { - edtDisplayHandle = handle; - } - try { - CompleteDisplay0(edtDisplayHandle); - } catch(RuntimeException e) { - closeNativeImpl(); - throw e; - } - - // see API doc above! - if(X11Util.XINITTHREADS_ALWAYS_ENABLED && X11Util.HAS_XLOCKDISPLAY_BUG) { - aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock(), false); - } else { - aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, false); - } - } - - protected void closeNativeImpl() { - DisplayRelease0(edtDisplayHandle, javaObjectAtom, windowDeleteAtom); - javaObjectAtom = 0; - windowDeleteAtom = 0; - // closing using ATI driver bug 'same order' - final long handle = getHandle(); - X11Util.closeDisplay(handle); - if(handle != edtDisplayHandle) { - X11Util.closeDisplay(edtDisplayHandle); - } - edtDisplayHandle = 0; - } - - protected void dispatchMessagesNative() { - if(0 != edtDisplayHandle) { - DispatchMessages0(edtDisplayHandle, javaObjectAtom, windowDeleteAtom); - } - } - - protected long getEDTHandle() { return edtDisplayHandle; } - protected long getJavaObjectAtom() { return javaObjectAtom; } - protected long getWindowDeleteAtom() { return windowDeleteAtom; } - - //---------------------------------------------------------------------- - // Internals only - // - private static native boolean initIDs0(boolean debug); - - private native void CompleteDisplay0(long handle); - - private void displayCompleted(long javaObjectAtom, long windowDeleteAtom) { - this.javaObjectAtom=javaObjectAtom; - this.windowDeleteAtom=windowDeleteAtom; - } - private native void DisplayRelease0(long handle, long javaObjectAtom, long windowDeleteAtom); - - private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom); - - /** - * 2011/06/14 libX11 1.4.2 and libxcb 1.7 bug 20708 - Multithreading Issues w/ OpenGL, .. - * https://bugs.freedesktop.org/show_bug.cgi?id=20708 - * https://jogamp.org/bugzilla/show_bug.cgi?id=502 - * Affects: Ubuntu 11.04, OpenSuSE 11, .. - * Workaround: Using a separate X11 Display connection for event dispatching (EDT) - */ - private final boolean USE_SEPARATE_DISPLAY_FOR_EDT = true; - - private long edtDisplayHandle; - - /** X11 Window delete atom marker used on EDT */ - private long windowDeleteAtom; - - /** X11 Window java object property used on EDT */ - private long javaObjectAtom; -} - diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java b/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java deleted file mode 100644 index 93db854ac..000000000 --- a/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ -package jogamp.newt.driver.x11; - -import java.util.List; - -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.Point; - -import jogamp.nativewindow.x11.X11Util; -import jogamp.newt.DisplayImpl; -import jogamp.newt.DisplayImpl.DisplayRunnable; -import jogamp.newt.ScreenImpl; - -import com.jogamp.nativewindow.x11.X11GraphicsDevice; -import com.jogamp.nativewindow.x11.X11GraphicsScreen; -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.util.ScreenModeUtil; - -public class X11Screen extends ScreenImpl { - - static { - X11Display.initSingleton(); - } - - public X11Screen() { - } - - protected void createNativeImpl() { - // validate screen index - Long handle = display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { - public Long run(long dpy) { - return new Long(GetScreen0(dpy, screen_idx)); - } } ); - if (handle.longValue() == 0) { - throw new RuntimeException("Error creating screen: " + screen_idx); - } - aScreen = new X11GraphicsScreen((X11GraphicsDevice) getDisplay().getGraphicsDevice(), screen_idx); - } - - protected void closeNativeImpl() { - } - - private int[] nrotations; - private int nrotation_index; - private int nres_number; - private int nres_index; - private int[] nrates; - private int nrate_index; - private int nmode_number; - - protected int[] getScreenModeFirstImpl() { - return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { - public int[] run(long dpy) { - // initialize iterators and static data - nrotations = getAvailableScreenModeRotations0(dpy, screen_idx); - if(null==nrotations || 0==nrotations.length) { - return null; - } - nrotation_index = 0; - - nres_number = getNumScreenModeResolutions0(dpy, screen_idx); - if(0==nres_number) { - return null; - } - nres_index = 0; - - nrates = getScreenModeRates0(dpy, screen_idx, nres_index); - if(null==nrates || 0==nrates.length) { - return null; - } - nrate_index = 0; - - nmode_number = 0; - - return getScreenModeNextImpl(); - } } ); - } - - protected int[] getScreenModeNextImpl() { - // assemble: w x h x bpp x f x r - return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { - public int[] run(long dpy) { - /** - System.err.println("******** mode: "+nmode_number); - System.err.println("rot "+nrotation_index); - System.err.println("rate "+nrate_index); - System.err.println("res "+nres_index); */ - - int[] res = getScreenModeResolution0(dpy, screen_idx, nres_index); - if(null==res || 0==res.length) { - return null; - } - if(0>=res[0] || 0>=res[1]) { - throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_index+"/"+nres_number); - } - int rate = nrates[nrate_index]; - if(0>=rate) { - rate = default_sm_rate; - if(DEBUG) { - System.err.println("Invalid rate: "+rate+" at index "+nrate_index+"/"+nrates.length+", using default: "+default_sm_rate); - } - } - int rotation = nrotations[nrotation_index]; - - int[] props = new int[ 1 + ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL ]; - int i = 0; - props[i++] = nres_index; // use resolution index, not unique for native -> ScreenMode - props[i++] = 0; // set later for verification of iterator - props[i++] = res[0]; // width - props[i++] = res[1]; // height - props[i++] = default_sm_bpp; // FIXME - props[i++] = res[2]; // widthmm - props[i++] = res[3]; // heightmm - props[i++] = rate; // rate - props[i++] = rotation; - props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i - 1; // count without extra element - - nmode_number++; - - // iteration: r -> f -> bpp -> [w x h] - nrotation_index++; - if(nrotation_index == nrotations.length) { - nrotation_index=0; - nrate_index++; - if(null == nrates || nrate_index == nrates.length){ - nres_index++; - if(nres_index == nres_number) { - // done - nrates=null; - nrotations=null; - return null; - } - - nrates = getScreenModeRates0(dpy, screen_idx, nres_index); - if(null==nrates || 0==nrates.length) { - return null; - } - nrate_index = 0; - } - } - - return props; - } } ); - } - - protected ScreenMode getCurrentScreenModeImpl() { - return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { - public ScreenMode run(long dpy) { - long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx); - if(0 == screenConfigHandle) { - return null; - } - int[] res; - int rate, rot; - try { - int resNumber = getNumScreenModeResolutions0(dpy, screen_idx); - if(0==resNumber) { - return null; - } - - int resIdx = getCurrentScreenResolutionIndex0(screenConfigHandle); - if(0>resIdx) { - return null; - } - if(resIdx>=resNumber) { - throw new RuntimeException("Invalid resolution index: ! "+resIdx+" < "+resNumber); - } - res = getScreenModeResolution0(dpy, screen_idx, resIdx); - if(null==res || 0==res.length) { - return null; - } - if(0>=res[0] || 0>=res[1]) { - throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+resIdx+"/"+resNumber); - } - rate = getCurrentScreenRate0(screenConfigHandle); - if(0>rate) { - return null; - } - rot = getCurrentScreenRotation0(screenConfigHandle); - if(0>rot) { - return null; - } - } finally { - freeScreenConfiguration0(screenConfigHandle); - } - int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL]; - int i = 0; - props[i++] = 0; // set later for verification of iterator - props[i++] = res[0]; // width - props[i++] = res[1]; // height - props[i++] = default_sm_bpp; // FIXME - props[i++] = res[2]; // widthmm - props[i++] = res[3]; // heightmm - props[i++] = rate; // rate - props[i++] = rot; - props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i; // count - return ScreenModeUtil.streamIn(props, 0); - } } ); - } - - protected boolean setCurrentScreenModeImpl(final ScreenMode screenMode) { - final List screenModes = this.getScreenModesOrig(); - final int screenModeIdx = screenModes.indexOf(screenMode); - if(0>screenModeIdx) { - throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode); - } - final long t0 = System.currentTimeMillis(); - boolean done = runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { - public Boolean run(long dpy) { - boolean done = false; - long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx); - if(0 == screenConfigHandle) { - return Boolean.valueOf(done); - } - try { - int resNumber = getNumScreenModeResolutions0(dpy, screen_idx); - int resIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx); - if(0>resIdx || resIdx>=resNumber) { - throw new RuntimeException("Invalid resolution index: ! 0 < "+resIdx+" < "+resNumber+", screenMode["+screenModeIdx+"] "+screenMode); - } - - final int f = screenMode.getMonitorMode().getRefreshRate(); - final int r = screenMode.getRotation(); - - if( setCurrentScreenModeStart0(dpy, screen_idx, screenConfigHandle, resIdx, f, r) ) { - while(!done && System.currentTimeMillis()-t0 < SCREEN_MODE_CHANGE_TIMEOUT) { - done = setCurrentScreenModePollEnd0(dpy, screen_idx, resIdx, f, r); - if(!done) { - try { Thread.sleep(10); } catch (InterruptedException e) { } - } - } - } - } finally { - freeScreenConfiguration0(screenConfigHandle); - } - return Boolean.valueOf(done); - } - }).booleanValue(); - - if(DEBUG || !done) { - System.err.println("X11Screen.setCurrentScreenModeImpl: TO ("+SCREEN_MODE_CHANGE_TIMEOUT+") reached: "+ - (System.currentTimeMillis()-t0)+"ms; Current: "+getCurrentScreenMode()+"; Desired: "+screenMode); - } - return done; - } - - private class XineramaEnabledQuery implements DisplayImpl.DisplayRunnable { - public Boolean run(long dpy) { - return new Boolean(X11Util.XineramaIsEnabled(dpy)); - } - } - private XineramaEnabledQuery xineramaEnabledQuery = new XineramaEnabledQuery(); - - protected int validateScreenIndex(final int idx) { - if(getDisplay().isNativeValid()) { - return runWithLockedDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx; - } else { - return runWithTempDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx; - } - } - - protected void getVirtualScreenOriginAndSize(final Point virtualOrigin, final Dimension virtualSize) { - display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { - public Object run(long dpy) { - virtualOrigin.setX(0); - virtualOrigin.setY(0); - virtualSize.setWidth(getWidth0(dpy, screen_idx)); - virtualSize.setHeight(getHeight0(dpy, screen_idx)); - return null; - } } ); - } - - //---------------------------------------------------------------------- - // Internals only - // - private final T runWithLockedDisplayHandle(DisplayRunnable action) { - return display.runWithLockedDisplayHandle(action); - // return runWithTempDisplayHandle(action); - // return runWithoutLock(action); - } - - private final T runWithTempDisplayHandle(DisplayRunnable action) { - final long displayHandle = X11Util.openDisplay(display.getName()); - if(0 == displayHandle) { - throw new RuntimeException("null device"); - } - T res; - try { - res = action.run(displayHandle); - } finally { - X11Util.closeDisplay(displayHandle); - } - return res; - } - private final T runWithoutLock(DisplayRunnable action) { - return action.run(display.getHandle()); - } - - private static native long GetScreen0(long dpy, int scrn_idx); - - private static native int getWidth0(long display, int scrn_idx); - - private static native int getHeight0(long display, int scrn_idx); - - /** @return int[] { rot1, .. } */ - private static native int[] getAvailableScreenModeRotations0(long display, int screen_index); - - private static native int getNumScreenModeResolutions0(long display, int screen_index); - - /** @return int[] { width, height, widthmm, heightmm } */ - private static native int[] getScreenModeResolution0(long display, int screen_index, int mode_index); - - private static native int[] getScreenModeRates0(long display, int screen_index, int mode_index); - - private static native long getScreenConfiguration0(long display, int screen_index); - private static native void freeScreenConfiguration0(long screenConfiguration); - - private static native int getCurrentScreenResolutionIndex0(long screenConfiguration); - private static native int getCurrentScreenRate0(long screenConfiguration); - private static native int getCurrentScreenRotation0(long screenConfiguration); - - /** needs own Display connection for XRANDR event handling */ - private static native boolean setCurrentScreenModeStart0(long display, int screen_index, long screenConfiguration, int mode_index, int freq, int rot); - private static native boolean setCurrentScreenModePollEnd0(long display, int screen_index, int mode_index, int freq, int rot); -} diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Window.java b/src/newt/classes/jogamp/newt/driver/x11/X11Window.java deleted file mode 100644 index 5501f5a3c..000000000 --- a/src/newt/classes/jogamp/newt/driver/x11/X11Window.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (c) 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - */ - -package jogamp.newt.driver.x11; - -import jogamp.nativewindow.x11.X11Lib; -import jogamp.newt.DisplayImpl; -import jogamp.newt.DisplayImpl.DisplayRunnable; -import jogamp.newt.WindowImpl; -import javax.media.nativewindow.*; -import javax.media.nativewindow.VisualIDHolder.VIDType; -import javax.media.nativewindow.util.Insets; -import javax.media.nativewindow.util.InsetsImmutable; -import javax.media.nativewindow.util.Point; - -import com.jogamp.newt.event.MouseEvent; - -public class X11Window extends WindowImpl { - private static final String WINDOW_CLASS_NAME = "NewtWindow"; - private static final int X11_WHEEL_ONE_UP_BUTTON = 4; - private static final int X11_WHEEL_ONE_DOWN_BUTTON = 5; - private static final int X11_WHEEL_TWO_UP_BUTTON = 6; - private static final int X11_WHEEL_TWO_DOWN_BUTTON = 7; - - static { - X11Display.initSingleton(); - } - - public X11Window() { - } - - protected void createNativeImpl() { - final X11Screen screen = (X11Screen) getScreen(); - final X11Display display = (X11Display) screen.getDisplay(); - final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice(), capsRequested); - final AbstractGraphicsConfiguration cfg = factory.chooseGraphicsConfiguration( - capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED); - if(DEBUG_IMPLEMENTATION) { - System.err.println("X11Window.createNativeImpl() factory: "+factory+", chosen config: "+cfg); - } - if (null == cfg) { - throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); - } - final int visualID = cfg.getVisualID(VIDType.NATIVE); - if(VisualIDHolder.VID_UNDEFINED == visualID) { - throw new NativeWindowException("Chosen Configuration w/o native visual ID: "+cfg); - } - setGraphicsConfiguration(cfg); - final int flags = getReconfigureFlags(0, true) & - ( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ; - setWindowHandle(CreateWindow0(getParentWindowHandle(), - display.getEDTHandle(), screen.getIndex(), visualID, - display.getJavaObjectAtom(), display.getWindowDeleteAtom(), - getX(), getY(), getWidth(), getHeight(), autoPosition(), flags)); - windowHandleClose = getWindowHandle(); - if (0 == windowHandleClose) { - throw new NativeWindowException("Error creating window"); - } - } - - protected void closeNativeImpl() { - if(0!=windowHandleClose && null!=getScreen() ) { - X11Display display = (X11Display) getScreen().getDisplay(); - try { - CloseWindow0(display.getEDTHandle(), windowHandleClose, - display.getJavaObjectAtom(), display.getWindowDeleteAtom()); - } catch (Throwable t) { - if(DEBUG_IMPLEMENTATION) { - Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t); - e.printStackTrace(); - } - } finally { - windowHandleClose = 0; - } - } - } - - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { - if(DEBUG_IMPLEMENTATION) { - System.err.println("X11Window reconfig: "+x+"/"+y+" "+width+"x"+height+", "+ - getReconfigureFlagsAsString(null, flags)); - } - if(0 == ( FLAG_IS_UNDECORATED & flags)) { - final InsetsImmutable i = getInsets(); - - // client position -> top-level window position - x -= i.getLeftWidth() ; - y -= i.getTopHeight() ; - } - final X11Display display = (X11Display) getScreen().getDisplay(); - reconfigureWindow0( getDisplayEDTHandle(), getScreenIndex(), - getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(), - x, y, width, height, flags); - - return true; - } - - protected void reparentNotify(long newParentWindowHandle) { - if(DEBUG_IMPLEMENTATION) { - final long p0 = getParentWindowHandle(); - System.err.println("Window.reparentNotify ("+getThreadName()+"): "+toHexString(p0)+" -> "+toHexString(newParentWindowHandle)); - } - } - - protected void requestFocusImpl(boolean force) { - requestFocus0(getDisplayEDTHandle(), getWindowHandle(), force); - } - - @Override - protected void setTitleImpl(final String title) { - runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { - public Object run(long dpy) { - setTitle0(dpy, getWindowHandle(), title); - return null; - } - }); - } - - @Override - protected boolean setPointerVisibleImpl(final boolean pointerVisible) { - return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { - public Boolean run(long dpy) { - return Boolean.valueOf(setPointerVisible0(getDisplayEDTHandle(), getWindowHandle(), pointerVisible)); - } - }).booleanValue(); - } - - @Override - protected boolean confinePointerImpl(final boolean confine) { - return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { - public Boolean run(long dpy) { - return Boolean.valueOf(confinePointer0(getDisplayEDTHandle(), getWindowHandle(), confine)); - } - }).booleanValue(); - } - - @Override - protected void warpPointerImpl(final int x, final int y) { - runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { - public Object run(long dpy) { - warpPointer0(getDisplayEDTHandle(), getWindowHandle(), x, y); - return null; - } - }); - } - - protected Point getLocationOnScreenImpl(final int x, final int y) { - // X11Util.GetRelativeLocation: locks display already ! - return X11Lib.GetRelativeLocation( getScreen().getDisplay().getHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y); - } - - protected void updateInsetsImpl(Insets insets) { - // nop - using event driven insetsChange(..) - } - - protected void doMouseEvent(boolean enqueue, boolean wait, int eventType, int modifiers, - int x, int y, int button, int rotation) { - switch(eventType) { - case MouseEvent.EVENT_MOUSE_PRESSED: - switch(button) { - case X11_WHEEL_ONE_UP_BUTTON: - case X11_WHEEL_ONE_DOWN_BUTTON: - case X11_WHEEL_TWO_UP_BUTTON: - case X11_WHEEL_TWO_DOWN_BUTTON: - // ignore wheel pressed ! - return; - } - break; - case MouseEvent.EVENT_MOUSE_RELEASED: - switch(button) { - case X11_WHEEL_ONE_UP_BUTTON: - eventType = MouseEvent.EVENT_MOUSE_WHEEL_MOVED; - button = 1; - rotation = 1; - break; - case X11_WHEEL_ONE_DOWN_BUTTON: - eventType = MouseEvent.EVENT_MOUSE_WHEEL_MOVED; - button = 1; - rotation = -1; - break; - case X11_WHEEL_TWO_UP_BUTTON: - eventType = MouseEvent.EVENT_MOUSE_WHEEL_MOVED; - button = 2; - rotation = 1; - break; - case X11_WHEEL_TWO_DOWN_BUTTON: - eventType = MouseEvent.EVENT_MOUSE_WHEEL_MOVED; - button = 2; - rotation = -1; - break; - } - break; - } - super.doMouseEvent(enqueue, wait, eventType, modifiers, x, y, button, rotation); - } - - - //---------------------------------------------------------------------- - // Internals only - // - - private static final String getCurrentThreadName() { return Thread.currentThread().getName(); } // Callback for JNI - private static final void dumpStack() { Thread.dumpStack(); } // Callback for JNI - - private final long getDisplayEDTHandle() { - return ((X11Display) getScreen().getDisplay()).getEDTHandle(); - } - private final T runWithLockedDisplayHandle(DisplayRunnable action) { - return ((DisplayImpl) getScreen().getDisplay()).runWithLockedDisplayHandle(action); - // return runWithTempDisplayHandle(action); - } - - protected static native boolean initIDs0(); - - private native long CreateWindow0(long parentWindowHandle, long display, int screen_index, - int visualID, long javaObjectAtom, long windowDeleteAtom, - int x, int y, int width, int height, boolean autoPosition, int flags); - private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom); - private native void reconfigureWindow0(long display, int screen_index, long parentWindowHandle, long windowHandle, - long windowDeleteAtom, int x, int y, int width, int height, int flags); - private native void requestFocus0(long display, long windowHandle, boolean force); - - private static native void setTitle0(long display, long windowHandle, String title); - private static native long getParentWindow0(long display, long windowHandle); - private static native boolean setPointerVisible0(long display, long windowHandle, boolean visible); - private static native boolean confinePointer0(long display, long windowHandle, boolean grab); - private static native void warpPointer0(long display, long windowHandle, int x, int y); - - private long windowHandleClose; -} diff --git a/src/newt/native/AndroidWindow.c b/src/newt/native/AndroidWindow.c index fa5765672..94695e1d3 100644 --- a/src/newt/native/AndroidWindow.c +++ b/src/newt/native/AndroidWindow.c @@ -9,7 +9,7 @@ #include #include -#include "jogamp_newt_driver_android_AndroidWindow.h" +#include "jogamp_newt_driver_android_WindowDriver.h" #include #include @@ -23,56 +23,56 @@ #endif -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_android_AndroidWindow_getSurfaceHandle0 +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_android_WindowDriver_getSurfaceHandle0 (JNIEnv *env, jclass clazz, jobject surface) { ANativeWindow * anw = ANativeWindow_fromSurface(env, surface); return (jlong) (intptr_t) anw; } -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_AndroidWindow_getSurfaceVisualID0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_WindowDriver_getSurfaceVisualID0 (JNIEnv *env, jclass clazz, jlong surfaceHandle) { ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle; return (jint) ANativeWindow_getFormat(anw); } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_AndroidWindow_setSurfaceVisualID0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_WindowDriver_setSurfaceVisualID0 (JNIEnv *env, jclass clazz, jlong surfaceHandle, jint nativeVisualID) { ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle; ANativeWindow_setBuffersGeometry(anw, 0, 0, nativeVisualID); } -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_AndroidWindow_getWidth0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_WindowDriver_getWidth0 (JNIEnv *env, jclass clazz, jlong surfaceHandle) { ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle; return (jint) ANativeWindow_getWidth(anw); } -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_AndroidWindow_getHeight0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_android_WindowDriver_getHeight0 (JNIEnv *env, jclass clazz, jlong surfaceHandle) { ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle; return (jint) ANativeWindow_getHeight(anw); } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_AndroidWindow_acquire0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_WindowDriver_acquire0 (JNIEnv *env, jclass clazz, jlong surfaceHandle) { ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle; ANativeWindow_acquire(anw); } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_AndroidWindow_release0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_android_WindowDriver_release0 (JNIEnv *env, jclass clazz, jlong surfaceHandle) { ANativeWindow * anw = (ANativeWindow *) (intptr_t) surfaceHandle; ANativeWindow_release(anw); } -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_android_AndroidWindow_initIDs0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_android_WindowDriver_initIDs0 (JNIEnv *env, jclass clazz) { DBG_PRINT( "initIDs ok\n" ); diff --git a/src/newt/native/IntelGDL.c b/src/newt/native/IntelGDL.c index 690e1123d..a3bf101c5 100644 --- a/src/newt/native/IntelGDL.c +++ b/src/newt/native/IntelGDL.c @@ -37,9 +37,9 @@ #include #include -#include "jogamp_newt_driver_intel_gdl_Display.h" -#include "jogamp_newt_driver_intel_gdl_Screen.h" -#include "jogamp_newt_driver_intel_gdl_Window.h" +#include "jogamp_newt_driver_intel_gdl_DisplayDriver.h" +#include "jogamp_newt_driver_intel_gdl_ScreenDriver.h" +#include "jogamp_newt_driver_intel_gdl_WindowDriver.h" #include "MouseEvent.h" #include "KeyEvent.h" @@ -122,7 +122,7 @@ static void JNI_ThrowNew(JNIEnv *env, const char *throwable, const char* message * Display */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Display_DispatchMessages +JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_DisplayDriver_DispatchMessages (JNIEnv *env, jobject obj, jlong displayHandle, jobject focusedWindow) { // FIXME: n/a @@ -137,7 +137,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Display_DispatchMessage } */ } -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_Display_CreateDisplay +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_DisplayDriver_CreateDisplay (JNIEnv *env, jobject obj) { gdl_ret_t retval; @@ -170,7 +170,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_Display_CreateDisplay return (jlong) (intptr_t) p_driver_info; } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Display_DestroyDisplay +JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_DisplayDriver_DestroyDisplay (JNIEnv *env, jobject obj, jlong displayHandle) { gdl_driver_info_t * p_driver_info = (gdl_driver_info_t *) (intptr_t) displayHandle; @@ -189,7 +189,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Display_DestroyDisplay * Screen */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_Screen_initIDs +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_ScreenDriver_initIDs (JNIEnv *env, jclass clazz) { screenCreatedID = (*env)->GetMethodID(env, clazz, "screenCreated", "(II)V"); @@ -201,7 +201,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_Screen_initIDs return JNI_TRUE; } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Screen_GetScreenInfo +JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_ScreenDriver_GetScreenInfo (JNIEnv *env, jobject obj, jlong displayHandle, jint idx) { gdl_driver_info_t * p_driver_info = (gdl_driver_info_t *) (intptr_t) displayHandle; @@ -233,7 +233,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Screen_GetScreenInfo * Window */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_Window_initIDs +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_WindowDriver_initIDs (JNIEnv *env, jclass clazz) { updateBoundsID = (*env)->GetMethodID(env, clazz, "updateBounds", "(IIII)V"); @@ -245,7 +245,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_intel_gdl_Window_initIDs return JNI_TRUE; } -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_Window_CreateSurface +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_WindowDriver_CreateSurface (JNIEnv *env, jobject obj, jlong displayHandle, jint scr_width, jint scr_height, jint x, jint y, jint width, jint height) { gdl_driver_info_t * p_driver_info = (gdl_driver_info_t *) (intptr_t) displayHandle; @@ -338,7 +338,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_intel_gdl_Window_CreateSurface return (jlong) (intptr_t) plane; } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Window_CloseSurface +JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_WindowDriver_CloseSurface (JNIEnv *env, jobject obj, jlong display, jlong surface) { gdl_plane_id_t plane = (gdl_plane_id_t) (intptr_t) surface ; @@ -347,7 +347,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Window_CloseSurface DBG_PRINT("[CloseSurface] plane %d\n", plane); } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_Window_SetBounds0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_intel_gdl_WindowDriver_SetBounds0 (JNIEnv *env, jobject obj, jlong surface, jint scr_width, jint scr_height, jint x, jint y, jint width, jint height) { gdl_plane_id_t plane = (gdl_plane_id_t) (intptr_t) surface ; diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c index bceb86a85..f1d6aecdf 100644 --- a/src/newt/native/KDWindow.c +++ b/src/newt/native/KDWindow.c @@ -44,7 +44,7 @@ #include #include -#include "jogamp_newt_driver_kd_Window.h" +#include "jogamp_newt_driver_kd_WindowDriver.h" #include "MouseEvent.h" #include "KeyEvent.h" @@ -82,7 +82,7 @@ static jmethodID sendKeyEventID = NULL; * Display */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_Display_DispatchMessages +JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_DisplayDriver_DispatchMessages (JNIEnv *env, jobject obj) { const KDEvent * evt; @@ -180,7 +180,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_Display_DispatchMessages * Window */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_kd_Window_initIDs +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_kd_WindowDriver_initIDs (JNIEnv *env, jclass clazz) { #ifdef VERBOSE_ON @@ -208,7 +208,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_kd_Window_initIDs return JNI_TRUE; } -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_Window_CreateWindow +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_WindowDriver_CreateWindow (JNIEnv *env, jobject obj, jlong display, jlong jeglConfig) { EGLDisplay dpy = (EGLDisplay)(intptr_t)display; @@ -236,7 +236,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_Window_CreateWindow return (jlong) (intptr_t) window; } -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_Window_RealizeWindow +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_WindowDriver_RealizeWindow (JNIEnv *env, jobject obj, jlong window) { KDWindow *w = (KDWindow*) (intptr_t) window; @@ -251,7 +251,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_Window_RealizeWindow return (jlong) (intptr_t) nativeWindow; } -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_kd_Window_CloseWindow +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_kd_WindowDriver_CloseWindow (JNIEnv *env, jobject obj, jlong window, jlong juserData) { KDWindow *w = (KDWindow*) (intptr_t) window; @@ -265,11 +265,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_kd_Window_CloseWindow } /* - * Class: jogamp_newt_driver_kd_Window + * Class: jogamp_newt_driver_kd_WindowDriver * Method: setVisible0 * Signature: (JJZ)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_Window_setVisible0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_WindowDriver_setVisible0 (JNIEnv *env, jobject obj, jlong window, jboolean visible) { KDWindow *w = (KDWindow*) (intptr_t) window; @@ -279,7 +279,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_Window_setVisible0 (*env)->CallVoidMethod(env, obj, visibleChangedID, JNI_FALSE, visible); // FIXME: or defer=true ? } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_Window_setFullScreen0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_WindowDriver_setFullScreen0 (JNIEnv *env, jobject obj, jlong window, jboolean fullscreen) { /** not supported, due to missing NV property .. @@ -296,7 +296,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_Window_setFullScreen0 (void)fullscreen; } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_Window_setSize0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_WindowDriver_setSize0 (JNIEnv *env, jobject obj, jlong window, jint width, jint height) { KDWindow *w = (KDWindow*) (intptr_t) window; diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index bbadc9dd0..e0330a563 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -33,7 +33,7 @@ #import -#import "jogamp_newt_driver_macosx_MacWindow.h" +#import "jogamp_newt_driver_macosx_WindowDriver.h" #import "NewtMacWindow.h" #import "MouseEvent.h" @@ -155,11 +155,11 @@ NS_ENDHANDLER } /* - * Class: jogamp_newt_driver_macosx_MacDisplay + * Class: jogamp_newt_driver_macosx_DisplayDriver * Method: initIDs * Signature: ()Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_initNSApplication0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_initNSApplication0 (JNIEnv *env, jclass clazz) { static int initialized = 0; @@ -189,11 +189,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_initNSAppli } /* - * Class: jogamp_newt_driver_macosx_MacDisplay + * Class: jogamp_newt_driver_macosx_DisplayDriver * Method: runNSApplication0 * Signature: ()V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_runNSApplication0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_runNSApplication0 (JNIEnv *env, jclass clazz) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -206,11 +206,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_runNSApplicatio } /* - * Class: jogamp_newt_driver_macosx_MacDisplay + * Class: jogamp_newt_driver_macosx_DisplayDriver * Method: stopNSApplication0 * Signature: ()V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_stopNSApplication0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_stopNSApplication0 (JNIEnv *env, jclass clazz) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -250,11 +250,11 @@ static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx) { } /* - * Class: jogamp_newt_driver_macosx_MacScreen + * Class: jogamp_newt_driver_macosx_ScreenDriver * Method: getWidthImpl * Signature: (I)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getWidthImpl0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getWidthImpl0 (JNIEnv *env, jclass clazz, jint screen_idx) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -268,11 +268,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getWidthImpl0 } /* - * Class: jogamp_newt_driver_macosx_MacScreen + * Class: jogamp_newt_driver_macosx_ScreenDriver * Method: getHeightImpl * Signature: (I)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getHeightImpl0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getHeightImpl0 (JNIEnv *env, jclass clazz, jint screen_idx) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -318,11 +318,11 @@ static long GetDictionaryLong(CFDictionaryRef theDict, const void* key) #define ROTMODES_PER_REALMODE 4 /* - * Class: jogamp_newt_driver_macosx_MacScreen + * Class: jogamp_newt_driver_macosx_ScreenDriver * Method: getScreenSizeMM0 * Signature: (I)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenSizeMM0 +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScreenSizeMM0 (JNIEnv *env, jobject obj, jint scrn_idx) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -367,11 +367,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenSi } /* - * Class: jogamp_newt_driver_macosx_MacScreen + * Class: jogamp_newt_driver_macosx_ScreenDriver * Method: getScreenMode0 * Signature: (IIII)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenMode0 +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScreenMode0 (JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx, jint widthMM, jint heightMM) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -459,11 +459,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenMo } /* - * Class: jogamp_newt_driver_macosx_MacScreen + * Class: jogamp_newt_driver_macosx_ScreenDriver * Method: setScreenMode0 * Signature: (II)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacScreen_setScreenMode0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_setScreenMode0 (JNIEnv *env, jobject object, jint scrn_idx, jint mode_idx) { jboolean res = JNI_TRUE; @@ -504,11 +504,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacScreen_setScreenMod } /* - * Class: jogamp_newt_driver_macosx_MacWindow + * Class: jogamp_newt_driver_macosx_WindowDriver * Method: initIDs * Signature: ()Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_initIDs0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0 (JNIEnv *env, jclass clazz) { static int initialized = 0; @@ -519,16 +519,16 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_initIDs0 jclass c; c = (*env)->FindClass(env, ClazzNamePoint); if(NULL==c) { - NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't find %s", ClazzNamePoint); + NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0: can't find %s", ClazzNamePoint); } pointClz = (jclass)(*env)->NewGlobalRef(env, c); (*env)->DeleteLocalRef(env, c); if(NULL==pointClz) { - NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't use %s", ClazzNamePoint); + NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0: can't use %s", ClazzNamePoint); } pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature); if(NULL==pointCstr) { - NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't fetch %s.%s %s", + NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0: can't fetch %s.%s %s", ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature); } @@ -541,11 +541,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_initIDs0 } /* - * Class: jogamp_newt_driver_macosx_MacWindow + * Class: jogamp_newt_driver_macosx_WindowDriver * Method: createWindow0 * Signature: (JIIIIZIIIJ)J */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_createWindow0 +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow0 (JNIEnv *env, jobject jthis, jlong parent, jint x, jint y, jint w, jint h, jboolean opaque, jboolean fullscreen, jint styleMask, jint bufferingType, jint screen_idx, jlong jview) { @@ -698,11 +698,11 @@ NS_ENDHANDLER /* - * Class: jogamp_newt_driver_macosx_MacWindow + * Class: jogamp_newt_driver_macosx_WindowDriver * Method: close0 * Signature: (J)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_close0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_close0 (JNIEnv *env, jobject unused, jlong window) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -761,11 +761,11 @@ NS_ENDHANDLER } /* - * Class: Java_jogamp_newt_driver_macosx_MacWindow + * Class: Java_jogamp_newt_driver_macosx_WindowDriver * Method: lockSurface0 * Signature: (J)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_lockSurface0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_lockSurface0 (JNIEnv *env, jclass clazz, jlong window) { NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window); @@ -779,11 +779,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_lockSurface0 } /* - * Class: Java_jogamp_newt_driver_macosx_MacWindow + * Class: Java_jogamp_newt_driver_macosx_WindowDriver * Method: unlockSurface0 * Signature: (J)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_unlockSurface0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_unlockSurface0 (JNIEnv *env, jclass clazz, jlong window) { NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window); @@ -794,11 +794,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_unlockSurface0 } /* - * Class: jogamp_newt_driver_macosx_MacWindow + * Class: jogamp_newt_driver_macosx_WindowDriver * Method: requestFocus0 * Signature: (JZ)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_requestFocus0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_requestFocus0 (JNIEnv *env, jobject window, jlong w, jboolean force) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -819,11 +819,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_requestFocus0 } /* - * Class: jogamp_newt_driver_macosx_MacWindow + * Class: jogamp_newt_driver_macosx_WindowDriver * Method: resignFocus0 * Signature: (J)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_resignFocus0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_resignFocus0 (JNIEnv *env, jobject window, jlong w) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -846,11 +846,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_resignFocus0 } /* - * Class: jogamp_newt_driver_macosx_MacWindow + * Class: jogamp_newt_driver_macosx_WindowDriver * Method: orderFront0 * Signature: (J)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_orderFront0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderFront0 (JNIEnv *env, jobject unused, jlong window) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -866,11 +866,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_orderFront0 } /* - * Class: jogamp_newt_driver_macosx_MacWindow + * Class: jogamp_newt_driver_macosx_WindowDriver * Method: orderOut * Signature: (J)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_orderOut0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderOut0 (JNIEnv *env, jobject unused, jlong window) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -891,11 +891,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_orderOut0 } /* - * Class: jogamp_newt_driver_macosx_MacWindow + * Class: jogamp_newt_driver_macosx_WindowDriver * Method: setTitle0 * Signature: (JLjava/lang/String;)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setTitle0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setTitle0 (JNIEnv *env, jobject unused, jlong window, jstring title) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -913,11 +913,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setTitle0 } /* - * Class: jogamp_newt_driver_macosx_MacWindow + * Class: jogamp_newt_driver_macosx_WindowDriver * Method: contentView * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_contentView0 +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_contentView0 (JNIEnv *env, jobject unused, jlong window) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -934,11 +934,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_contentView0 } /* - * Class: jogamp_newt_driver_macosx_MacWindow + * Class: jogamp_newt_driver_macosx_WindowDriver * Method: changeContentView * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_changeContentView0 +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_changeContentView0 (JNIEnv *env, jobject jthis, jlong parentWindowOrView, jlong window, jlong jview) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -977,11 +977,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_changeContentVi } /* - * Class: jogamp_newt_driver_macosx_MacWindow + * Class: jogamp_newt_driver_macosx_WindowDriver * Method: setContentSize * Signature: (JII)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setContentSize0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setContentSize0 (JNIEnv *env, jobject unused, jlong window, jint w, jint h) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -998,11 +998,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setContentSize0 } /* - * Class: jogamp_newt_driver_macosx_MacWindow + * Class: jogamp_newt_driver_macosx_WindowDriver * Method: setFrameTopLeftPoint * Signature: (JJII)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setFrameTopLeftPoint0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setFrameTopLeftPoint0 (JNIEnv *env, jobject unused, jlong parent, jlong window, jint x, jint y) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -1027,11 +1027,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setFrameTopLeftP } /* - * Class: jogamp_newt_driver_macosx_MacWindow + * Class: jogamp_newt_driver_macosx_WindowDriver * Method: setAlwaysOnTop0 * Signature: (JZ)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setAlwaysOnTop0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setAlwaysOnTop0 (JNIEnv *env, jobject unused, jlong window, jboolean atop) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -1051,11 +1051,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setAlwaysOnTop0 } /* - * Class: jogamp_newt_driver_macosx_MacWindow + * Class: jogamp_newt_driver_macosx_WindowDriver * Method: getLocationOnScreen0 * Signature: (JII)Ljavax/media/nativewindow/util/Point; */ -JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_MacWindow_getLocationOnScreen0 +JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getLocationOnScreen0 (JNIEnv *env, jclass unused, jlong win, jint src_x, jint src_y) { NSObject *nsObj = (NSObject*) ((intptr_t) win); @@ -1072,11 +1072,11 @@ JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_MacWindow_getLocationOn } /* - * Class: Java_jogamp_newt_driver_macosx_MacWindow + * Class: Java_jogamp_newt_driver_macosx_WindowDriver * Method: setPointerVisible0 * Signature: (JZ)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setPointerVisible0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerVisible0 (JNIEnv *env, jclass clazz, jlong window, jboolean hasFocus, jboolean mouseVisible) { NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window); @@ -1086,11 +1086,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setPointerVi } /* - * Class: Java_jogamp_newt_driver_macosx_MacWindow + * Class: Java_jogamp_newt_driver_macosx_WindowDriver * Method: confinePointer0 * Signature: (JZ)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_confinePointer0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_confinePointer0 (JNIEnv *env, jclass clazz, jlong window, jboolean confine) { NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window); @@ -1099,11 +1099,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_confinePoint } /* - * Class: Java_jogamp_newt_driver_macosx_MacWindow + * Class: Java_jogamp_newt_driver_macosx_WindowDriver * Method: warpPointer0 * Signature: (JJII)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_warpPointer0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_warpPointer0 (JNIEnv *env, jclass clazz, jlong window, jint x, jint y) { NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window); diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index 6d9c04dc3..40252f59b 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -81,9 +81,9 @@ #define DISPLAY_DEVICE_ACTIVE 0x00000001 #endif -#include "jogamp_newt_driver_windows_WindowsDisplay.h" -#include "jogamp_newt_driver_windows_WindowsScreen.h" -#include "jogamp_newt_driver_windows_WindowsWindow.h" +#include "jogamp_newt_driver_windows_DisplayDriver.h" +#include "jogamp_newt_driver_windows_ScreenDriver.h" +#include "jogamp_newt_driver_windows_WindowDriver.h" #include "Window.h" #include "MouseEvent.h" @@ -1011,11 +1011,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, } /* - * Class: jogamp_newt_driver_windows_WindowsDisplay + * Class: jogamp_newt_driver_windows_DisplayDriver * Method: DispatchMessages * Signature: ()V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsDisplay_DispatchMessages0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_DisplayDriver_DispatchMessages0 (JNIEnv *env, jclass clazz) { int i = 0; @@ -1040,11 +1040,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsDisplay_DispatchMe } /* - * Class: jogamp_newt_driver_windows_WindowsScreen + * Class: jogamp_newt_driver_windows_ScreenDriver * Method: getOriginX0 * Signature: (I)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginX0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getOriginX0 (JNIEnv *env, jobject obj, jint scrn_idx) { if( GetSystemMetrics( SM_CMONITORS) > 1) { @@ -1055,11 +1055,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginX0 } /* - * Class: jogamp_newt_driver_windows_WindowsScreen + * Class: jogamp_newt_driver_windows_ScreenDriver * Method: getOriginY0 * Signature: (I)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginY0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getOriginY0 (JNIEnv *env, jobject obj, jint scrn_idx) { if( GetSystemMetrics( SM_CMONITORS ) > 1) { @@ -1070,11 +1070,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginY0 } /* - * Class: jogamp_newt_driver_windows_WindowsScreen + * Class: jogamp_newt_driver_windows_ScreenDriver * Method: getWidthImpl * Signature: (I)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getWidthImpl0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getWidthImpl0 (JNIEnv *env, jobject obj, jint scrn_idx) { if( GetSystemMetrics( SM_CMONITORS) > 1) { @@ -1085,11 +1085,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getWidthImp } /* - * Class: jogamp_newt_driver_windows_WindowsScreen + * Class: jogamp_newt_driver_windows_ScreenDriver * Method: getHeightImpl * Signature: (I)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getHeightImpl0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getHeightImpl0 (JNIEnv *env, jobject obj, jint scrn_idx) { if( GetSystemMetrics( SM_CMONITORS ) > 1) { @@ -1173,11 +1173,11 @@ static HDC NewtScreen_createDisplayDC(LPCTSTR displayDeviceName) { } /* - * Class: jogamp_newt_driver_windows_WindowsScreen + * Class: jogamp_newt_driver_windows_ScreenDriver * Method: getScreenMode0 * Signature: (II)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getScreenMode0 +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getScreenMode0 (JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx) { DISPLAY_DEVICE device; @@ -1246,11 +1246,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getScr } /* - * Class: jogamp_newt_driver_windows_WindowsScreen + * Class: jogamp_newt_driver_windows_ScreenDriver * Method: setScreenMode0 * Signature: (IIIIII)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_setScreenMode0 +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) { DISPLAY_DEVICE device; @@ -1283,11 +1283,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_setScre } /* - * Class: jogamp_newt_driver_windows_WindowsWindow + * Class: jogamp_newt_driver_windows_WindowDriver * Method: initIDs0 * Signature: ()Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_initIDs0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_initIDs0 (JNIEnv *env, jclass clazz) { NewtCommon_init(env); @@ -1324,11 +1324,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_initIDs } /* - * Class: jogamp_newt_driver_windows_WindowsWindow + * Class: jogamp_newt_driver_windows_WindowDriver * Method: getNewtWndProc0 * Signature: ()J */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_getNewtWndProc0 +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_getNewtWndProc0 (JNIEnv *env, jclass clazz) { return (jlong) (intptr_t) wndProc; @@ -1366,10 +1366,10 @@ static void NewtWindow_setVisiblePosSize(HWND hwnd, BOOL atop, BOOL visible, } /* - * Class: jogamp_newt_driver_windows_WindowsWindow + * Class: jogamp_newt_driver_windows_WindowDriver * Method: CreateWindow */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWindow0 +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindow0 (JNIEnv *env, jobject obj, jlong hInstance, jstring jWndClassName, jstring jWndName, jlong parent, @@ -1473,11 +1473,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind } /* - * Class: jogamp_newt_driver_windows_WindowsWindow + * Class: jogamp_newt_driver_windows_WindowDriver * Method: MonitorFromWindow * Signature: (J)J */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_MonitorFromWindow0 +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_MonitorFromWindow0 (JNIEnv *env, jobject obj, jlong window) { #if (_WIN32_WINNT >= 0x0500 || _WIN32_WINDOWS >= 0x0410 || WINVER >= 0x0500) && !defined(_WIN32_WCE) @@ -1506,11 +1506,11 @@ static jboolean NewtWindows_setFullScreen(jboolean fullscreen) } /* - * Class: jogamp_newt_driver_windows_WindowsWindow + * Class: jogamp_newt_driver_windows_WindowDriver * Method: reconfigureWindow0 * Signature: (JJIIIII)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_reconfigureWindow0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureWindow0 (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jint flags) { @@ -1591,11 +1591,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_reconfigure } /* - * Class: jogamp_newt_driver_windows_WindowsWindow + * Class: jogamp_newt_driver_windows_WindowDriver * Method: setTitle * Signature: (JLjava/lang/String;)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_setTitle0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_setTitle0 (JNIEnv *env, jclass clazz, jlong window, jstring title) { HWND hwnd = (HWND) (intptr_t) window; @@ -1609,11 +1609,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_setTitle0 } /* - * Class: jogamp_newt_driver_windows_WindowsWindow + * Class: jogamp_newt_driver_windows_WindowDriver * Method: requestFocus * Signature: (JZ)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_requestFocus0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_requestFocus0 (JNIEnv *env, jobject obj, jlong window, jboolean force) { DBG_PRINT("*** WindowsWindow: RequestFocus0\n"); @@ -1621,11 +1621,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_requestFocu } /* - * Class: Java_jogamp_newt_driver_windows_WindowsWindow + * Class: Java_jogamp_newt_driver_windows_WindowDriver * Method: setPointerVisible0 * Signature: (JJZ)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_setPointerVisible0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_setPointerVisible0 (JNIEnv *env, jclass clazz, jlong window, jboolean mouseVisible) { HWND hwnd = (HWND) (intptr_t) window; @@ -1660,11 +1660,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_setPoin } /* - * Class: Java_jogamp_newt_driver_windows_WindowsWindow + * Class: Java_jogamp_newt_driver_windows_WindowDriver * Method: confinePointer0 * Signature: (JJZIIII)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_confinePointer0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_confinePointer0 (JNIEnv *env, jclass clazz, jlong window, jboolean confine, jint l, jint t, jint r, jint b) { HWND hwnd = (HWND) (intptr_t) window; @@ -1686,11 +1686,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_confine } /* - * Class: Java_jogamp_newt_driver_windows_WindowsWindow + * Class: Java_jogamp_newt_driver_windows_WindowDriver * Method: warpPointer0 * Signature: (JJII)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_warpPointer0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_warpPointer0 (JNIEnv *env, jclass clazz, jlong window, jint x, jint y) { DBG_PRINT( "*** WindowsWindow: warpPointer0: %d/%d\n", x, y); @@ -1698,11 +1698,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_warpPointer } /* - * Class: Java_jogamp_newt_driver_windows_WindowsWindow + * Class: Java_jogamp_newt_driver_windows_WindowDriver * Method: trackPointerLeave0 * Signature: (J)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_trackPointerLeave0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_trackPointerLeave0 (JNIEnv *env, jclass clazz, jlong window) { HWND hwnd = (HWND) (intptr_t) window; diff --git a/src/newt/native/X11Common.h b/src/newt/native/X11Common.h index 982255b8a..128b6b6f1 100644 --- a/src/newt/native/X11Common.h +++ b/src/newt/native/X11Common.h @@ -45,9 +45,9 @@ #include -#include "jogamp_newt_driver_x11_X11Screen.h" -#include "jogamp_newt_driver_x11_X11Display.h" -#include "jogamp_newt_driver_x11_X11Window.h" +#include "jogamp_newt_driver_x11_ScreenDriver.h" +#include "jogamp_newt_driver_x11_DisplayDriver.h" +#include "jogamp_newt_driver_x11_WindowDriver.h" #include "Window.h" #include "MouseEvent.h" diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c index ce7d9a0e1..3157538c3 100644 --- a/src/newt/native/X11Display.c +++ b/src/newt/native/X11Display.c @@ -34,7 +34,7 @@ jclass X11NewtWindowClazz = NULL; jmethodID insetsChangedID = NULL; jmethodID visibleChangedID = NULL; -static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/X11Window"; +static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/WindowDriver"; static jmethodID displayCompletedID = NULL; @@ -264,11 +264,11 @@ static jint X11InputState2NewtModifiers(unsigned int xstate) { */ /* - * Class: jogamp_newt_driver_x11_X11Display + * Class: jogamp_newt_driver_x11_DisplayDriver * Method: initIDs * Signature: (Z)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Display_initIDs0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0 (JNIEnv *env, jclass clazz, jboolean debug) { jclass c; @@ -281,12 +281,12 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Display_initIDs0 if(NULL==X11NewtWindowClazz) { c = (*env)->FindClass(env, ClazzNameX11NewtWindow); if(NULL==c) { - NewtCommon_FatalError(env, "NEWT X11Window: can't find %s", ClazzNameX11NewtWindow); + NewtCommon_FatalError(env, "NEWT X11Display: can't find %s", ClazzNameX11NewtWindow); } X11NewtWindowClazz = (jclass)(*env)->NewGlobalRef(env, c); (*env)->DeleteLocalRef(env, c); if(NULL==X11NewtWindowClazz) { - NewtCommon_FatalError(env, "NEWT X11Window: can't use %s", ClazzNameX11NewtWindow); + NewtCommon_FatalError(env, "NEWT X11Display: can't use %s", ClazzNameX11NewtWindow); } } @@ -331,11 +331,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Display_initIDs0 } /* - * Class: jogamp_newt_driver_x11_X11Display + * Class: jogamp_newt_driver_x11_DisplayDriver * Method: CompleteDisplay * Signature: (J)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_CompleteDisplay0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_CompleteDisplay0 (JNIEnv *env, jobject obj, jlong display) { Display * dpy = (Display *)(intptr_t)display; @@ -366,11 +366,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_CompleteDisplay0 } /* - * Class: jogamp_newt_driver_x11_X11Display + * Class: jogamp_newt_driver_x11_DisplayDriver * Method: DisplayRelease0 * Signature: (JJJ)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DisplayRelease0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DisplayRelease0 (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom) { Display * dpy = (Display *)(intptr_t)display; @@ -390,11 +390,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DisplayRelease0 } /* - * Class: jogamp_newt_driver_x11_X11Display + * Class: jogamp_newt_driver_x11_DisplayDriver * Method: DispatchMessages * Signature: (JIJJ)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0 (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom) { Display * dpy = (Display *) (intptr_t) display; diff --git a/src/newt/native/X11Screen.c b/src/newt/native/X11Screen.c index 698eed89d..334c39727 100644 --- a/src/newt/native/X11Screen.c +++ b/src/newt/native/X11Screen.c @@ -36,11 +36,11 @@ #endif /* - * Class: jogamp_newt_driver_x11_X11Screen + * Class: jogamp_newt_driver_x11_ScreenDriver * Method: GetScreen * Signature: (JI)J */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0 +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_GetScreen0 (JNIEnv *env, jclass clazz, jlong display, jint screen_index) { Display * dpy = (Display *)(intptr_t)display; @@ -60,14 +60,14 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0 return (jlong) (intptr_t) scrn; } -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getWidth0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getWidth0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) { Display * dpy = (Display *) (intptr_t) display; return (jint) DisplayWidth( dpy, scrn_idx); } -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getHeight0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getHeight0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) { Display * dpy = (Display *) (intptr_t) display; @@ -112,11 +112,11 @@ static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) { } /* - * Class: jogamp_newt_driver_x11_X11Screen + * Class: jogamp_newt_driver_x11_ScreenDriver * Method: getAvailableScreenModeRotations0 * Signature: (JI)I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableScreenModeRotations0 +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getAvailableScreenModeRotations0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -162,11 +162,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableSc } /* - * Class: jogamp_newt_driver_x11_X11Screen + * Class: jogamp_newt_driver_x11_ScreenDriver * Method: getNumScreenModeResolution0 * Signature: (JI)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -177,7 +177,7 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeRes #endif if(False == NewtScreen_hasRANDR(dpy)) { - DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0: RANDR not available\n"); + DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getNumScreenModeResolutions0: RANDR not available\n"); return 0; } @@ -200,17 +200,17 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeRes } /* - * Class: jogamp_newt_driver_x11_X11Screen + * Class: jogamp_newt_driver_x11_ScreenDriver * Method: getScreenModeResolutions0 * Signature: (JII)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0 +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx) { Display *dpy = (Display *) (intptr_t) display; if(False == NewtScreen_hasRANDR(dpy)) { - DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0: RANDR not available\n"); + DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeResolution0: RANDR not available\n"); return (*env)->NewIntArray(env, 0); } @@ -242,17 +242,17 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeR } /* - * Class: jogamp_newt_driver_x11_X11Screen + * Class: jogamp_newt_driver_x11_ScreenDriver * Method: getScreenModeRates0 * Signature: (JII)[I */ -JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0 +JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0 (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx) { Display *dpy = (Display *) (intptr_t) display; if(False == NewtScreen_hasRANDR(dpy)) { - DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0: RANDR not available\n"); + DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getScreenModeRates0: RANDR not available\n"); return (*env)->NewIntArray(env, 0); } @@ -285,11 +285,11 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeR } /* - * Class: jogamp_newt_driver_x11_X11Screen + * Class: jogamp_newt_driver_x11_ScreenDriver * Method: getScreenConfiguration0 * Signature: (JI)J */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenConfiguration0 +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getScreenConfiguration0 (JNIEnv *env, jclass clazz, jlong display, jint screen_idx) { Display *dpy = (Display *) (intptr_t) display; @@ -301,7 +301,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenConfigura #endif if(False == NewtScreen_hasRANDR(dpy)) { - DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenConfiguration0: RANDR not available\n"); + DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_getScreenConfiguration0: RANDR not available\n"); return 0; } #ifdef DBG_PERF @@ -320,22 +320,22 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenConfigura } /* - * Class: jogamp_newt_driver_x11_X11Screen + * Class: jogamp_newt_driver_x11_ScreenDriver * Method: freeScreenConfiguration0 * Signature: (J)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Screen_freeScreenConfiguration0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_freeScreenConfiguration0 (JNIEnv *env, jclass clazz, jlong screenConfiguration) { XRRFreeScreenConfigInfo( (XRRScreenConfiguration *) (intptr_t) screenConfiguration ); } /* - * Class: jogamp_newt_driver_x11_X11Screen + * Class: jogamp_newt_driver_x11_ScreenDriver * Method: getCurrentScreenRate0 * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRate0 (JNIEnv *env, jclass clazz, jlong screenConfiguration) { XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration; @@ -347,11 +347,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRat } /* - * Class: jogamp_newt_driver_x11_X11Screen + * Class: jogamp_newt_driver_x11_ScreenDriver * Method: getCurrentScreenRotation0 * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenRotation0 (JNIEnv *env, jclass clazz, jlong screenConfiguration) { XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration; @@ -364,11 +364,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRot /* - * Class: jogamp_newt_driver_x11_X11Screen + * Class: jogamp_newt_driver_x11_ScreenDriver * Method: getCurrentScreenResolutionIndex0 * Signature: (J)I */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0 +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getCurrentScreenResolutionIndex0 (JNIEnv *env, jclass clazz, jlong screenConfiguration) { XRRScreenConfiguration *conf = (XRRScreenConfiguration *) (intptr_t) screenConfiguration; @@ -383,11 +383,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRes } /* - * Class: jogamp_newt_driver_x11_X11Screen + * Class: jogamp_newt_driver_x11_ScreenDriver * Method: setCurrentScreenModeStart0 * Signature: (JIJIII)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModeStart0 (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenConfiguration, jint resMode_idx, jint freq, jint rotation) { Display *dpy = (Display *) (intptr_t) display; @@ -432,11 +432,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree } /* - * Class: jogamp_newt_driver_x11_X11Screen + * Class: jogamp_newt_driver_x11_ScreenDriver * Method: setCurrentScreenModePollEnd0 * Signature: (J)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0 (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation) { Display *dpy = (Display *) (intptr_t) display; @@ -445,7 +445,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt; if(False == NewtScreen_hasRANDR(dpy)) { - DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0: RANDR not available\n"); + DBG_PRINT("Java_jogamp_newt_driver_x11_ScreenDriver_setCurrentScreenModePollEnd0: RANDR not available\n"); return JNI_FALSE; } diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index daf9f2b53..59862f463 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -467,11 +467,11 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy, */ /* - * Class: jogamp_newt_driver_x11_X11Window + * Class: jogamp_newt_driver_x11_WindowDriver * Method: initIDs * Signature: ()Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_initIDs0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_WindowDriver_initIDs0 (JNIEnv *env, jclass clazz) { return JNI_TRUE; @@ -505,10 +505,10 @@ static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint } /* - * Class: jogamp_newt_driver_x11_X11Window + * Class: jogamp_newt_driver_x11_WindowDriver * Method: CreateWindow */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0 +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWindow0 (JNIEnv *env, jobject obj, jlong parent, jlong display, jint screen_index, jint visualID, jlong javaObjectAtom, jlong windowDeleteAtom, @@ -666,11 +666,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0 } /* - * Class: jogamp_newt_driver_x11_X11Window + * Class: jogamp_newt_driver_x11_WindowDriver * Method: CloseWindow * Signature: (JJ)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0 (JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom, jlong windowDeleteAtom) { Display * dpy = (Display *) (intptr_t) display; @@ -703,7 +703,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0 NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); // Drain all events related to this window .. - Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom); + Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom); XDestroyWindow(dpy, w); XSync(dpy, False); @@ -729,11 +729,11 @@ static Bool WaitForReparentNotify( Display *dpy, XEvent *event, XPointer arg ) { */ /* - * Class: jogamp_newt_driver_x11_X11Window + * Class: jogamp_newt_driver_x11_WindowDriver * Method: reconfigureWindow0 * Signature: (JIJJIIIII)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindow0 (JNIEnv *env, jobject obj, jlong jdisplay, jint screen_index, jlong jparent, jlong jwindow, jlong windowDeleteAtom, jint x, jint y, jint width, jint height, jint flags) @@ -869,33 +869,33 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0 } /* - * Class: jogamp_newt_driver_x11_X11Window + * Class: jogamp_newt_driver_x11_WindowDriver * Method: requestFocus0 * Signature: (JJZ)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_requestFocus0 +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 ) ; } /* - * Class: jogamp_newt_driver_x11_X11Window + * Class: jogamp_newt_driver_x11_WindowDriver * Method: getParentWindow0 * Signature: (JJ)J */ -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_getParentWindow0 +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_getParentWindow0 (JNIEnv *env, jclass clazz, jlong display, jlong window) { return (jlong) NewtWindows_getParent ((Display *) (intptr_t) display, (Window)window); } /* - * Class: Java_jogamp_newt_driver_x11_X11Window + * Class: Java_jogamp_newt_driver_x11_WindowDriver * Method: setTitle0 * Signature: (JJLjava/lang/String;)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_setTitle0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_setTitle0 (JNIEnv *env, jclass clazz, jlong display, jlong window, jstring title) { Display * dpy = (Display *) (intptr_t) display; @@ -942,11 +942,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_setTitle0 } /* - * Class: Java_jogamp_newt_driver_x11_X11Window + * Class: Java_jogamp_newt_driver_x11_WindowDriver * Method: setPointerVisible0 * Signature: (JJZ)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_setPointerVisible0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_WindowDriver_setPointerVisible0 (JNIEnv *env, jclass clazz, jlong display, jlong window, jboolean mouseVisible) { static char noData[] = { 0,0,0,0,0,0,0,0 }; @@ -976,11 +976,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_setPointerVisib } /* - * Class: Java_jogamp_newt_driver_x11_X11Window + * Class: Java_jogamp_newt_driver_x11_WindowDriver * Method: confinePointer0 * Signature: (JJZ)Z */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_confinePointer0 +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_WindowDriver_confinePointer0 (JNIEnv *env, jclass clazz, jlong display, jlong window, jboolean confine) { Display * dpy = (Display *) (intptr_t) display; @@ -999,11 +999,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_confinePointer0 } /* - * Class: Java_jogamp_newt_driver_x11_X11Window + * Class: Java_jogamp_newt_driver_x11_WindowDriver * Method: warpPointer0 * Signature: (JJII)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_warpPointer0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_warpPointer0 (JNIEnv *env, jclass clazz, jlong display, jlong window, jint x, jint y) { Display * dpy = (Display *) (intptr_t) display; diff --git a/src/newt/native/bcm_egl.c b/src/newt/native/bcm_egl.c index 79ebd20e0..9b960d278 100644 --- a/src/newt/native/bcm_egl.c +++ b/src/newt/native/bcm_egl.c @@ -37,7 +37,7 @@ #include #include -#include "jogamp_newt_driver_bcm_egl_Window.h" +#include "jogamp_newt_driver_bcm_egl_WindowDriver.h" #include "MouseEvent.h" #include "KeyEvent.h" @@ -67,7 +67,7 @@ static jmethodID windowCreatedID = NULL; * Display */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_Display_DispatchMessages +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_DisplayDriver_DispatchMessages (JNIEnv *env, jobject obj) { // FIXME: n/a @@ -75,7 +75,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_Display_DispatchMessages (void) obj; } -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_egl_Display_CreateDisplay +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_egl_DisplayDriver_CreateDisplay (JNIEnv *env, jobject obj, jint width, jint height) { (void) env; @@ -89,7 +89,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_egl_Display_CreateDisplay return (jlong) (intptr_t) dpy; } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_Display_DestroyDisplay +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_DisplayDriver_DestroyDisplay (JNIEnv *env, jobject obj, jlong display) { EGLDisplay dpy = (EGLDisplay)(intptr_t)display; @@ -106,7 +106,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_Display_DestroyDisplay * Window */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_egl_Window_initIDs +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_egl_WindowDriver_initIDs (JNIEnv *env, jclass clazz) { windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(III)V"); @@ -118,7 +118,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_egl_Window_initIDs return JNI_TRUE; } -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_egl_Window_CreateWindow +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_egl_WindowDriver_CreateWindow (JNIEnv *env, jobject obj, jlong display, jboolean chromaKey, jint width, jint height) { EGLDisplay dpy = (EGLDisplay)(intptr_t)display; @@ -162,7 +162,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_egl_Window_CreateWindow return (jlong) (intptr_t) window; } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_Window_CloseWindow +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_WindowDriver_CloseWindow (JNIEnv *env, jobject obj, jlong display, jlong window) { EGLDisplay dpy = (EGLDisplay) (intptr_t) display; @@ -175,7 +175,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_Window_CloseWindow DBG_PRINT( "[CloseWindow] X\n"); } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_Window_SwapWindow +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_egl_WindowDriver_SwapWindow (JNIEnv *env, jobject obj, jlong display, jlong window) { EGLDisplay dpy = (EGLDisplay) (intptr_t) display; diff --git a/src/newt/native/bcm_vc_iv.c b/src/newt/native/bcm_vc_iv.c index 09ab8a634..e41745e14 100644 --- a/src/newt/native/bcm_vc_iv.c +++ b/src/newt/native/bcm_vc_iv.c @@ -32,9 +32,9 @@ #include "bcm_vc_iv.h" -#include "jogamp_newt_driver_bcm_vc_iv_Display.h" -#include "jogamp_newt_driver_bcm_vc_iv_Screen.h" -#include "jogamp_newt_driver_bcm_vc_iv_Window.h" +#include "jogamp_newt_driver_bcm_vc_iv_DisplayDriver.h" +#include "jogamp_newt_driver_bcm_vc_iv_ScreenDriver.h" +#include "jogamp_newt_driver_bcm_vc_iv_WindowDriver.h" #define VERBOSE_ON 1 @@ -57,7 +57,7 @@ static jmethodID sendKeyEventID = NULL; * Display */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Display_initIDs +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_initIDs (JNIEnv *env, jclass clazz) { bcm_host_init(); @@ -66,7 +66,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Display_initIDs return JNI_TRUE; } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Display_DispatchMessages +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_DispatchMessages (JNIEnv *env, jobject obj) { } @@ -75,7 +75,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Display_DispatchMessage * Screen */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Screen_initIDs +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_ScreenDriver_initIDs (JNIEnv *env, jclass clazz) { uint32_t screen_width; @@ -91,7 +91,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Screen_initIDs return JNI_TRUE; } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Screen_initNative +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_ScreenDriver_initNative (JNIEnv *env, jobject obj) { uint32_t screen_width; @@ -109,7 +109,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Screen_initNative * Window */ -JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Window_initIDs +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_initIDs (JNIEnv *env, jclass clazz) { windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V"); @@ -131,7 +131,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Window_initIDs return JNI_TRUE; } -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Window_CreateWindow +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CreateWindow (JNIEnv *env, jobject obj, jint width, jint height) { int32_t success = 0; @@ -166,13 +166,13 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Window_CreateWindow return (jlong) (intptr_t) nativeWindowPtr; } -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Window_RealizeWindow +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_RealizeWindow (JNIEnv *env, jobject obj, jlong window) { return (jlong) (intptr_t) 0; } -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Window_CloseWindow +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CloseWindow (JNIEnv *env, jobject obj, jlong window, jlong juserData) { EGL_DISPMANX_WINDOW_T * nativeWindowPtr = (EGL_DISPMANX_WINDOW_T *) (intptr_t) window ; @@ -181,21 +181,21 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Window_CloseWindow } /* - * Class: jogamp_newt_driver_bcm_vc_iv_Window + * Class: jogamp_newt_driver_bcm_vc_iv_WindowDriver * Method: setVisible0 * Signature: (JJZ)V */ -JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Window_setVisible0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_setVisible0 (JNIEnv *env, jobject obj, jlong window, jboolean visible) { } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Window_setFullScreen0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_setFullScreen0 (JNIEnv *env, jobject obj, jlong window, jboolean fullscreen) { } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_Window_setSize0 +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_setSize0 (JNIEnv *env, jobject obj, jlong window, jint width, jint height) { // FIXME RESIZE (*env)->CallVoidMethod(env, obj, sizeChangedID, JNI_FALSE, (jint) width, (jint) height, JNI_FALSE); diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java index 11babf187..89395e309 100644 --- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java +++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity0.java @@ -34,11 +34,11 @@ import java.util.Arrays; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLProfile; -import jogamp.newt.driver.android.AndroidWindow; import jogamp.newt.driver.android.NewtBaseActivity; import com.jogamp.common.util.IOUtil; import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.Window; import com.jogamp.newt.event.MouseAdapter; import com.jogamp.newt.event.MouseEvent; import com.jogamp.newt.opengl.GLWindow; @@ -55,8 +55,8 @@ public class MovieSimpleActivity0 extends NewtBaseActivity { MouseAdapter toFrontMouseListener = new MouseAdapter() { public void mouseClicked(MouseEvent e) { Object src = e.getSource(); - if(src instanceof AndroidWindow) { - ((AndroidWindow)src).requestFocus(false); + if(src instanceof Window) { + ((Window)src).requestFocus(false); } } }; diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java index a5e5f4ccb..a7fefd838 100644 --- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java +++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity1.java @@ -36,11 +36,11 @@ import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLProfile; import javax.media.opengl.GLRunnable; -import jogamp.newt.driver.android.AndroidWindow; import jogamp.newt.driver.android.NewtBaseActivity; import com.jogamp.common.util.IOUtil; import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.Window; import com.jogamp.newt.event.MouseAdapter; import com.jogamp.newt.event.MouseEvent; import com.jogamp.newt.opengl.GLWindow; @@ -59,8 +59,8 @@ public class MovieSimpleActivity1 extends NewtBaseActivity { MouseAdapter toFrontMouseListener = new MouseAdapter() { public void mouseClicked(MouseEvent e) { Object src = e.getSource(); - if(src instanceof AndroidWindow) { - ((AndroidWindow)src).requestFocus(false); + if(src instanceof Window) { + ((Window)src).requestFocus(false); } } }; @@ -121,7 +121,7 @@ public class MovieSimpleActivity1 extends NewtBaseActivity { final GLWindow glWindowMain = GLWindow.create(scrn, capsMain); { final int padding = mPlayerHUD ? 32 : 0; - final android.view.View androidView = ((AndroidWindow)glWindowMain.getDelegatedWindow()).getAndroidView(); + final android.view.View androidView = ((jogamp.newt.driver.android.WindowDriver)glWindowMain.getDelegatedWindow()).getAndroidView(); glWindowMain.setSize(scrn.getWidth()-padding, scrn.getHeight()-padding); glWindowMain.setUndecorated(true); // setContentView(getWindow(), glWindowMain); @@ -168,7 +168,7 @@ public class MovieSimpleActivity1 extends NewtBaseActivity { viewGroup.post(new Runnable() { public void run() { - final android.view.View androidView = ((AndroidWindow)glWindowHUD.getDelegatedWindow()).getAndroidView(); + final android.view.View androidView = ((jogamp.newt.driver.android.WindowDriver)glWindowHUD.getDelegatedWindow()).getAndroidView(); // addContentView(getWindow(), glWindowHUD, new android.view.ViewGroup.LayoutParams(glWindowHUD.getWidth(), glWindowHUD.getHeight())); viewGroup.addView(androidView, new android.widget.FrameLayout.LayoutParams(glWindowHUD.getWidth(), glWindowHUD.getHeight(), Gravity.TOP|Gravity.LEFT)); registerNEWTWindow(glWindowHUD); -- cgit v1.2.3 From fbe331f013608eb31ff0d8675f4e4c9881c9c48b Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Thu, 27 Sep 2012 17:33:39 +0200 Subject: Fix Bug 616: X11: Remove XInitThreads() dependency while cleaning up device locking, resulting in a native-lock-free impl. The X11 implementation details of NativeWindow and NEWT used the X11 implicit locking facility XLockDisplay/XUnlockDisplay, enabled via XInitThreads(). The latter useage is complicated within an unsure environment where the initialization point of JOGL is unknown, but XInitThreads() requires to be called once and before any other X11 calls. The solution is simple and thorough, replace native X11 locking w/ 'application level' locking. Following this pattern actually cleans up a pretty messy part of X11 NativeWindow and NEWT, since the generalization of platform independent locking simplifies code. Simply using our RecursiveLock also speeds up locking, since it doesn't require JNI calls down to X11 anymore. It allows us to get rid of X11ToolkitLock and X11JAWTToolkitLock. Using the RecursiveLock also allows us to remove the shortcut of explicitly createing a NullToolkitLocked device for 'private' display connections. All devices use proper locking as claimed in their toolkit util 'requiresToolkitLock()' in X11Util, OSXUtil, .. Further more a bug has been fixed of X11ErrorHandler usage, i.e. we need to keep our handler alive at all times due to async X11 messaging behavior. This allows to remove the redundant code in X11/NEWT. The AbstractGraphicsDevice lifecycle has been fixed as well, i.e. called when closing NEWT's Display for all driver implementations. On the NEWT side the Display's AbstractGraphicsDevice semantics has been clarified, i.e. it's usage for EDT and lifecycle operations. Hence the X11 Display 2nd device for rendering operations has been moved to X11 Window where it belongs - and the X11 Display's default device used for EDT/lifecycle-ops as it should be. This allows running X11/NEWT properly with the default usage, where the Display instance and hence the EDT thread is shared with many Screen and Window. Rendering using NEWT Window is decoupled from it's shared Display lock via it's own native X11 display. Lock free AbstractGraphicsDevice impl. (Windows, OSX, ..) don't require any attention in this regard since they use NullToolkitLock. Tests: ====== This implementation has been tested manually with Mesa3d (soft, Intel), ATI and Nvidia on X11, Windows and OSX w/o any regressions found in any unit test. Issues on ATI: ============== Only on ATI w/o a composite renderer the unit tests expose a driver or WM bug where XCB claims a lack of locking. Setting env. var 'LIBXCB_ALLOW_SLOPPY_LOCK=true' is one workaround if users refuse to enable compositing. We may investigate this issue in more detail later on. --- make/scripts/tests.sh | 50 ++++- .../classes/jogamp/opengl/egl/EGLDisplayUtil.java | 3 +- .../jogamp/opengl/x11/glx/X11GLXContext.java | 37 +--- .../opengl/x11/glx/X11GLXDrawableFactory.java | 13 +- .../jogamp/nativewindow/x11/X11GraphicsDevice.java | 2 +- .../jogamp/nativewindow/x11/X11GraphicsScreen.java | 2 +- .../media/nativewindow/AbstractGraphicsDevice.java | 2 +- .../media/nativewindow/DefaultGraphicsDevice.java | 3 +- .../media/nativewindow/NativeWindowFactory.java | 99 ++------- .../javax/media/nativewindow/ToolkitLock.java | 18 +- .../jogamp/nativewindow/NullToolkitLock.java | 9 + .../jogamp/nativewindow/ResourceToolkitLock.java | 74 +++++++ .../nativewindow/SharedResourceToolkitLock.java | 141 +++++++++++++ .../classes/jogamp/nativewindow/jawt/JAWTUtil.java | 3 + .../nativewindow/jawt/x11/X11JAWTToolkitLock.java | 76 ------- .../nativewindow/jawt/x11/X11JAWTWindow.java | 3 +- .../jogamp/nativewindow/x11/X11ToolkitLock.java | 70 ------ .../classes/jogamp/nativewindow/x11/X11Util.java | 119 ++++------- .../awt/X11AWTGraphicsConfigurationFactory.java | 7 +- src/nativewindow/native/x11/Xmisc.c | 38 ++-- src/newt/classes/com/jogamp/newt/Display.java | 35 ++- src/newt/classes/com/jogamp/newt/NewtFactory.java | 2 +- src/newt/classes/com/jogamp/newt/Screen.java | 2 +- src/newt/classes/jogamp/newt/DisplayImpl.java | 79 ++++--- src/newt/classes/jogamp/newt/ScreenImpl.java | 3 +- src/newt/classes/jogamp/newt/WindowImpl.java | 33 +-- .../jogamp/newt/driver/awt/DisplayDriver.java | 4 +- .../jogamp/newt/driver/bcm/egl/DisplayDriver.java | 2 + .../newt/driver/intel/gdl/DisplayDriver.java | 1 + .../jogamp/newt/driver/macosx/DisplayDriver.java | 4 +- .../jogamp/newt/driver/windows/DisplayDriver.java | 1 + .../jogamp/newt/driver/x11/DisplayDriver.java | 65 ++---- .../jogamp/newt/driver/x11/ScreenDriver.java | 31 ++- .../jogamp/newt/driver/x11/WindowDriver.java | 107 +++++++--- src/newt/native/X11Common.h | 1 - src/newt/native/X11Display.c | 91 -------- src/newt/native/X11Window.c | 10 - .../junit/jogl/acore/InitConcurrentBaseNEWT.java | 219 +++++++++++++++++++ .../junit/jogl/acore/TestInitConcurrent01NEWT.java | 78 +++++++ .../junit/jogl/acore/TestInitConcurrent02NEWT.java | 78 +++++++ .../junit/jogl/acore/TestInitConcurrentNEWT.java | 235 --------------------- 41 files changed, 964 insertions(+), 886 deletions(-) create mode 100644 src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java create mode 100644 src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java delete mode 100644 src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java delete mode 100644 src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent01NEWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrent02NEWT.java delete mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrentNEWT.java (limited to 'src/newt/native/X11Window.c') diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 8a0a638ba..3dc983072 100755 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -81,6 +81,7 @@ function jrun() { #D_ARGS="-Djogl.debug.GLDebugMessageHandler -Djogl.debug.TraceGL -Djogl.debug.DebugGL -Djogl.debug.GLSLCode -Djogl.debug.GLSLState" #D_ARGS="-Djogl.debug.GLDebugMessageHandler -Djogl.debug.DebugGL -Djogl.debug.TraceGL" #D_ARGS="-Djogamp.debug.NativeLibrary -Djogamp.debug.NativeLibrary.UseCurrentThreadLibLoader" + #D_ARGS="-Djogamp.debug.NativeLibrary" #D_ARGS="-Djogl.1thread=false -Djogl.debug.Threading" #D_ARGS="-Djogl.1thread=true -Djogl.debug.Threading" #D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL -Djogl.debug.GLContext.TraceSwitch -Djogl.debug=all" @@ -100,7 +101,6 @@ function jrun() { #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile -Djogl.debug.GLDrawable" #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLProfile" #D_ARGS="-Djogl.debug.GLProfile" - #D_ARGS="-Dnewt.debug.EDT -Dnativewindow.debug.ToolkitLock.TraceLock -Dnativewindow.debug.NativeWindow" #D_ARGS="-Dnativewindow.debug.NativeWindow" #D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT" #D_ARGS="-Dnewt.debug.EDT -Dnewt.debug.Window -Djogl.debug.GLContext" @@ -109,6 +109,7 @@ function jrun() { #D_ARGS="-Dnativewindow.debug.X11Util -Dnativewindow.debug.X11Util.XSync" #D_ARGS="-Dnativewindow.debug.X11Util.XSync -Dnewt.debug.Window" #D_ARGS="-Djogl.debug.GLDrawable -Djogl.debug.GLContext" + #D_ARGS="-Dnativewindow.debug.NativeWindow -Dnativewindow.debug.X11Util" #D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=3000 -Djogamp.debug.Lock -Djogl.debug.GLContext.TraceSwitch" #D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=600000 -Djogamp.debug.Lock -Djogamp.debug.Lock.TraceLock" #D_ARGS="-Djogamp.common.utils.locks.Lock.timeout=600000 -Djogamp.debug.Lock -Djogamp.debug.Lock.TraceLock -Dnativewindow.debug.ToolkitLock.TraceLock" @@ -135,7 +136,9 @@ function jrun() { #D_ARGS="-Djogl.debug.Animator" #D_ARGS="-Dnativewindow.debug=all" #D_ARGS="-Djogl.debug.GLCanvas" - #D_ARGS="-Dnativewindow.debug.ToolkitLock.TraceLock" + #D_ARGS="-Djogl.debug.GLContext -Dnativewindow.debug.X11Util.XSync" + #D_ARGS="-Dnativewindow.debug.X11Util.XSync" + #D_ARGS="-Dnativewindow.debug.ToolkitLock" #D_ARGS="-Djogl.debug.graph.curve -Djogl.debug.GLSLCode -Djogl.debug.TraceGL" #D_ARGS="-Djogl.debug.graph.curve -Djogl.debug.GLSLState" #D_ARGS="-Djogamp.debug.JNILibLoader -Djogamp.debug.TempJarCache -Djogamp.debug.JarUtil" @@ -187,6 +190,8 @@ function jrun() { #export LD_LIBRARY_PATH=/opt-linux-x86_64/mesa-7.8.1/lib64:$LD_LIBRARY_PATH #export LD_LIBRARY_PATH=/usr/lib/mesa:/usr/lib32/mesa:$LD_LIBRARY_PATH #export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/mesa:/usr/lib/i386-linux-gnu/mesa:$LD_LIBRARY_PATH + #export LD_LIBRARY_PATH=`pwd`/lib/external/mesa/x86_64-linux-gnu:$LD_LIBRARY_PATH + #export LD_LIBRARY_PATH=`pwd`/lib/external/mesa/x86_64-linux-gnu/gallium:$LD_LIBRARY_PATH echo echo "Test Start: $*" echo @@ -194,10 +199,10 @@ function jrun() { echo echo $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $* #LIBGL_DRIVERS_PATH=/usr/lib/mesa:/usr/lib32/mesa \ - #gdb --args $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $* #LIBGL_DEBUG=verbose INTEL_STRICT_CONFORMANCE=1 INTEL_DEBUG="buf bat" \ #LIBGL_DEBUG=verbose MESA_DEBUG=true INTEL_STRICT_CONFORMANCE=1 \ - #LIBGL_DEBUG=verbose MESA_DEBUG=true LIBGL_ALWAYS_SOFTWARE=true \ + #export LIBGL_DEBUG=verbose MESA_DEBUG=true LIBGL_ALWAYS_SOFTWARE=true + #gdb --args $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $* $javaexe $javaxargs $X_ARGS $D_ARGS $C_ARG $* echo echo "Test End: $*" @@ -239,7 +244,8 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile00NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $* -#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrentNEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent01NEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent02NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextSurfaceLockNEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug01NEWT $* @@ -250,6 +256,38 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextDrawableSwitchNEWT $* +# x11 no XinitThreads() specific tests (regressions, concurrent behavior) ! +# Deadlock: +# com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT2 - test01 +#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT2 $* +# com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT - testEachWithAnimatorSharedOffscreen +#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT $* +# +# XCB: +# +# com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT - testShaderState01PerformanceDouble +#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT $* +# com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT - testWindowParenting02ReparentTop2WinReparentRecreate +#testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT $* +# com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT - winHopFrame2FrameDirectHop +#testawtswt com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $* +#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting04AWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOOffThreadSharedContextMix2DemosES2NEWT $* + +#testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle02NEWT +#testnoawt com.jogamp.opengl.test.junit.newt.TestWindows01NEWT $* +testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent01NEWT $* +testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrent02NEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT $* +#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting04AWT $* +#testnoawt com.jogamp.opengl.test.junit.newt.TestRemoteGLWindows01NEWT $* +#testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTEclipseGLCanvas01GLn $* +#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT2 $* +#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOOffThreadSharedContextMix2DemosES2NEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOOnThreadSharedContext1DemoES2NEWT $* + + #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateOnOffscrnCapsNEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT $* #testawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT $* @@ -322,7 +360,7 @@ function testawtswt() { #testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT02WindowClosing #testawt com.jogamp.opengl.test.junit.jogl.awt.text.TestAWTTextRendererUseVertexArrayBug464 #testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT $* -testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT $* +#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWTAnalyzeBug455 $* #testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWTBug450 $* diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java index ce2e824f5..0a603ab8a 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java @@ -71,10 +71,9 @@ public class EGLDisplayUtil { Thread.dumpStack(); } if( eglDisplayCounter.size() > 0) { - EGLDisplayUtil.dumpOpenDisplayConnections(); + dumpOpenDisplayConnections(); } } - return eglDisplayCounter.size(); } diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java index e1e25be67..bdccc1047 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java @@ -172,7 +172,6 @@ public abstract class X11GLXContext extends GLContextImpl { glXMakeContextCurrent(display, 0, 0, 0); GLX.glXDestroyContext(display, ctx); } - private static final int ctx_arb_attribs_idx_major = 0; private static final int ctx_arb_attribs_idx_minor = 2; private static final int ctx_arb_attribs_idx_flags = 6; @@ -228,14 +227,14 @@ public abstract class X11GLXContext extends GLContextImpl { X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration(); AbstractGraphicsDevice device = config.getScreen().getDevice(); - long display = device.getHandle(); + final long display = device.getHandle(); try { // critical path, a remote display might not support this command, // hence we need to catch the X11 Error within this block. - X11Lib.XSync(display, false); + X11Util.setX11ErrorHandler(true, DEBUG ? false : true); // make sure X11 error handler is set ctx = _glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs); - X11Lib.XSync(display, false); + if(DEBUG) { X11Lib.XSync(display, false); } } catch (RuntimeException re) { if(DEBUG) { Throwable t = new Throwable(getThreadName()+": Info: X11GLXContext.createContextARBImpl glXCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re); @@ -263,16 +262,6 @@ public abstract class X11GLXContext extends GLContextImpl { @Override protected boolean createImpl(GLContextImpl shareWith) { - // covers the whole context creation loop incl createContextARBImpl and destroyContextARBImpl - X11Util.setX11ErrorHandler(true, DEBUG ? false : true); - try { - return createImplRaw(shareWith); - } finally { - X11Util.setX11ErrorHandler(false, false); - } - } - - private boolean createImplRaw(GLContextImpl shareWith) { boolean direct = true; // try direct always isDirect = false; // fall back @@ -401,14 +390,9 @@ public abstract class X11GLXContext extends GLContextImpl { protected void makeCurrentImpl() throws GLException { long dpy = drawable.getNativeSurface().getDisplayHandle(); - if (GLX.glXGetCurrentContext() != contextHandle) { - X11Util.setX11ErrorHandler(true, DEBUG ? false : true); - try { - if (!glXMakeContextCurrent(dpy, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { - throw new GLException(getThreadName()+": Error making context current: "+this); - } - } finally { - X11Util.setX11ErrorHandler(false, false); + if (GLX.glXGetCurrentContext() != contextHandle) { + if (!glXMakeContextCurrent(dpy, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { + throw new GLException(getThreadName()+": Error making context current: "+this); } } } @@ -416,13 +400,8 @@ public abstract class X11GLXContext extends GLContextImpl { @Override protected void releaseImpl() throws GLException { long display = drawable.getNativeSurface().getDisplayHandle(); - X11Util.setX11ErrorHandler(true, DEBUG ? false : true); - try { - if (!glXMakeContextCurrent(display, 0, 0, 0)) { - throw new GLException(getThreadName()+": Error freeing OpenGL context"); - } - } finally { - X11Util.setX11ErrorHandler(false, false); + if (!glXMakeContextCurrent(display, 0, 0, 0)) { + throw new GLException(getThreadName()+": Error freeing OpenGL context"); } } diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java index ca5cd424b..03c661565 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java @@ -47,7 +47,6 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.NativeSurface; -import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.ProxySurface; import javax.media.nativewindow.UpstreamSurfaceHook; import javax.media.nativewindow.VisualIDHolder; @@ -230,11 +229,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { @Override public SharedResourceRunner.Resource createSharedResource(String connection) { - final X11GraphicsDevice sharedDevice = - new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT, - true); // own non-shared display connection, w/ locking - // new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT, - // NativeWindowFactory.getNullToolkitLock(), true); // own non-shared display connection, w/o locking + final X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT, true); sharedDevice.lock(); try { final X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, sharedDevice.getDefaultScreen()); @@ -509,8 +504,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) { final X11GraphicsDevice device; if(createNewDevice) { - // Null X11 locking, due to private non-shared Display handle - device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), NativeWindowFactory.getNullToolkitLock(), true); + // Null X11 resource locking, due to private non-shared Display handle + device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true); } else { device = (X11GraphicsDevice)deviceReq; } @@ -531,7 +526,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { @Override protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) { - final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), NativeWindowFactory.getNullToolkitLock(), true); + final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true); final X11GraphicsScreen screen = new X11GraphicsScreen(device, screenIdx); final int xvisualID = X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle); if(VisualIDHolder.VID_UNDEFINED == xvisualID) { diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java index 152384980..2e4099c1b 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java @@ -73,7 +73,7 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl /** * @param display the Display connection - * @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking in NEWT + * @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking w/ private connection * @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int, long, ToolkitLock) */ public X11GraphicsDevice(long display, int unitID, ToolkitLock locker, boolean owner) { diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java index 5f3c220ca..7ab5bd6aa 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java @@ -63,7 +63,7 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl private static int fetchScreen(X11GraphicsDevice device, int screen) { // It still could be an AWT hold handle .. - if(X11Util.XineramaIsEnabled(device.getHandle())) { + if(X11Util.XineramaIsEnabled(device)) { screen = 0; // Xinerama -> 1 screen } return screen; diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java index 756e4451b..5eaaa6613 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java @@ -131,7 +131,7 @@ public interface AbstractGraphicsDevice extends Cloneable { /** * Optionally closing the device if handle is not null. *

- * The default implementation is a NOP, just setting the handle to null. + * The default implementation {@link ToolkitLock#dispose() dispose} it's {@link ToolkitLock} and sets the handle to null. *

*

* Example implementations like {@link com.jogamp.nativewindow.x11.X11GraphicsDevice} diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java index 583fde07f..b16b0c75c 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java @@ -153,6 +153,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice @Override public boolean close() { + toolkitLock.dispose(); if(0 != handle) { handle = 0; return true; @@ -162,7 +163,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice @Override public String toString() { - return getClass().getSimpleName()+"[type "+getType()+", connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+"]"; + return getClass().getSimpleName()+"[type "+getType()+", connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", "+toolkitLock+"]"; } /** diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index 40aaa8a25..4f4bb629b 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -33,7 +33,6 @@ package javax.media.nativewindow; -import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; @@ -43,6 +42,7 @@ import java.util.Map; import jogamp.nativewindow.Debug; import jogamp.nativewindow.NativeWindowFactoryImpl; +import jogamp.nativewindow.ResourceToolkitLock; import com.jogamp.common.os.Platform; import com.jogamp.common.util.ReflectionUtil; @@ -93,13 +93,6 @@ public abstract class NativeWindowFactory { private static ToolkitLock jawtUtilJAWTToolkitLock; - public static final String X11JAWTToolkitLockClassName = "jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock" ; - public static final String X11ToolkitLockClassName = "jogamp.nativewindow.x11.X11ToolkitLock" ; - - private static Class x11JAWTToolkitLockClass; - private static Constructor x11JAWTToolkitLockConstructor; - private static Class x11ToolkitLockClass; - private static Constructor x11ToolkitLockConstructor; private static boolean requiresToolkitLock; private static volatile boolean isJVMShuttingDown = false; @@ -266,16 +259,6 @@ public abstract class NativeWindowFactory { // register either our default factory or (if exist) the X11/AWT one -> AWT Component registerFactory(ReflectionUtil.getClass(ReflectionUtil.AWTNames.ComponentClass, false, cl), factory); } - - if( TYPE_X11 == nativeWindowingTypePure ) { - // passing through RuntimeException if not exists intended - x11ToolkitLockClass = ReflectionUtil.getClass(X11ToolkitLockClassName, false, cl); - x11ToolkitLockConstructor = ReflectionUtil.getConstructor(x11ToolkitLockClass, new Class[] { long.class } ); - if( isAWTAvailable() ) { - x11JAWTToolkitLockClass = ReflectionUtil.getClass(X11JAWTToolkitLockClassName, false, cl); - x11JAWTToolkitLockConstructor = ReflectionUtil.getConstructor(x11JAWTToolkitLockClass, new Class[] { long.class } ); - } - } if(DEBUG) { System.err.println("NativeWindowFactory requiresToolkitLock "+requiresToolkitLock); @@ -300,6 +283,7 @@ public abstract class NativeWindowFactory { GraphicsConfigurationFactory.shutdown(); } shutdownNativeImpl(NativeWindowFactory.class.getClassLoader()); // always re-shutdown + // SharedResourceToolkitLock.shutdown(DEBUG); // not used yet if(DEBUG) { System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END JVM Shutdown "+isJVMShuttingDown); } @@ -358,16 +342,9 @@ public abstract class NativeWindowFactory { /** * Provides the default {@link ToolkitLock} for type, a singleton instance. - *
*

    - *
  • If {@link #initSingleton(boolean) initSingleton( firstUIActionOnProcess := false )}
  • - *
      - *
    • If AWT-type and native-X11-type and AWT-available
    • - *
        - *
      • return {@link #getAWTToolkitLock()}
      • - *
      - *
    - *
  • Otherwise return {@link #getNullToolkitLock()}
  • + *
  • JAWT {@link ToolkitLock} if required and AWT available, otherwise
  • + *
  • {@link jogamp.nativewindow.NullToolkitLock}
  • *
*/ public static ToolkitLock getDefaultToolkitLock(String type) { @@ -390,84 +367,36 @@ public abstract class NativeWindowFactory { /** * Creates the default {@link ToolkitLock} for type and deviceHandle. - *
*
    - *
  • If {@link #initSingleton(boolean) initSingleton( firstUIActionOnProcess := false )}
  • - *
      - *
    • If X11 type
    • - *
        - *
      • return {@link jogamp.nativewindow.x11.X11ToolkitLock}
      • - *
      - *
    - *
  • Otherwise return {@link jogamp.nativewindow.NullToolkitLock}
  • + *
  • {@link jogamp.nativewindow.ResourceToolkitLock} if required, otherwise
  • + *
  • {@link jogamp.nativewindow.NullToolkitLock}
  • *
*/ public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) { if( requiresToolkitLock() ) { - if( TYPE_X11 == type ) { - if( 0== deviceHandle ) { - throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11"); - } - return createX11ToolkitLock(deviceHandle); - } + return ResourceToolkitLock.create(); } return NativeWindowFactoryImpl.getNullToolkitLock(); } /** * Creates the default {@link ToolkitLock} for type and deviceHandle. - *
*
    - *
  • If {@link #initSingleton(boolean) initSingleton( firstUIActionOnProcess := false )}
  • - *
      - *
    • If X11 type
    • - *
        - *
      • If shared-AWT-type and AWT available
      • - *
          - *
        • return {@link jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock}
        • - *
        - *
      • else return {@link jogamp.nativewindow.x11.X11ToolkitLock}
      • - *
      - *
    - *
  • Otherwise return {@link jogamp.nativewindow.NullToolkitLock}
  • + *
  • JAWT {@link ToolkitLock} if required and AWT available,
  • + *
  • {@link jogamp.nativewindow.ResourceToolkitLock} if required, otherwise
  • + *
  • {@link jogamp.nativewindow.NullToolkitLock}
  • *
*/ public static ToolkitLock createDefaultToolkitLock(String type, String sharedType, long deviceHandle) { if( requiresToolkitLock() ) { - if( TYPE_X11 == type ) { - if( 0== deviceHandle ) { - throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11"); - } - if( TYPE_AWT == sharedType && isAWTAvailable() ) { - return createX11AWTToolkitLock(deviceHandle); - } - return createX11ToolkitLock(deviceHandle); + if( TYPE_AWT == sharedType && isAWTAvailable() ) { + return getAWTToolkitLock(); } + return ResourceToolkitLock.create(); } return NativeWindowFactoryImpl.getNullToolkitLock(); } - - protected static ToolkitLock createX11AWTToolkitLock(long deviceHandle) { - try { - if(DEBUG) { - System.err.println("NativeWindowFactory.createX11AWTToolkitLock(0x"+Long.toHexString(deviceHandle)+")"); - // Thread.dumpStack(); - } - return (ToolkitLock) x11JAWTToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)}); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - protected static ToolkitLock createX11ToolkitLock(long deviceHandle) { - try { - return (ToolkitLock) x11ToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)}); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - + /** Returns the appropriate NativeWindowFactory to handle window objects of the given type. The windowClass might be {@link NativeWindow NativeWindow}, in which case the client has diff --git a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java index 30f9660f0..18b7cf5d9 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java +++ b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java @@ -33,12 +33,26 @@ import jogamp.nativewindow.Debug; /** * Marker for a singleton global recursive blocking lock implementation, * optionally locking a native windowing toolkit as well. - *
- * One use case is the AWT locking on X11, see {@link jogamp.nativewindow.jawt.JAWTToolkitLock}. + *

+ * Toolkit locks are created solely via {@link NativeWindowFactory}. + *

+ *

+ * One use case is the AWT locking on X11, see {@link NativeWindowFactory#createDefaultToolkitLock(String, long)}. + *

*/ public interface ToolkitLock { public static final boolean TRACE_LOCK = Debug.isPropertyDefined("nativewindow.debug.ToolkitLock.TraceLock", true); public void lock(); public void unlock(); + + /** + * Dispose this instance. + *

+ * Shall be called when instance is no more required. + *

+ * This allows implementations sharing a lock via resources + * to decrease the reference counter. + */ + public void dispose(); } diff --git a/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java index 1af6bf279..e59910138 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java +++ b/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java @@ -50,4 +50,13 @@ public class NullToolkitLock implements ToolkitLock { public final void unlock() { if(TRACE_LOCK) { System.err.println("NullToolkitLock.unlock()"); } } + + public final void dispose() { + // nop + } + + public String toString() { + return "NullToolkitLock[]"; + } + } diff --git a/src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java new file mode 100644 index 000000000..a3b0804fa --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java @@ -0,0 +1,74 @@ +/** + * Copyright 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.nativewindow; + +import javax.media.nativewindow.ToolkitLock; + +import com.jogamp.common.util.locks.LockFactory; +import com.jogamp.common.util.locks.RecursiveLock; + +/** + * Implementing a resource based recursive {@link javax.media.nativewindow.ToolkitLock}. + *

+ * A resource handle maybe used within a unique object + * and can be synchronized across threads via an instance of ResourceToolkitLock. + *

+ */ +public class ResourceToolkitLock implements ToolkitLock { + public static final boolean DEBUG = Debug.debug("ToolkitLock"); + + public static final ResourceToolkitLock create() { + return new ResourceToolkitLock(); + } + + private final RecursiveLock lock; + + private ResourceToolkitLock() { + this.lock = LockFactory.createRecursiveLock(); + } + + + public final void lock() { + if(TRACE_LOCK) { System.err.println("ResourceToolkitLock.lock()"); } + lock.lock(); + } + + public final void unlock() { + if(TRACE_LOCK) { System.err.println("ResourceToolkitLock.unlock()"); } + lock.unlock(); + } + + public final void dispose() { + // nop + } + + public String toString() { + return "ResourceToolkitLock[obj 0x"+Integer.toHexString(hashCode())+", isOwner "+lock.isOwner(Thread.currentThread())+", "+lock.toString()+"]"; + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java new file mode 100644 index 000000000..5d7ae8abb --- /dev/null +++ b/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java @@ -0,0 +1,141 @@ +/** + * Copyright 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.nativewindow; + +import java.util.Iterator; + +import javax.media.nativewindow.ToolkitLock; + +import com.jogamp.common.util.LongObjectHashMap; +import com.jogamp.common.util.locks.LockFactory; +import com.jogamp.common.util.locks.RecursiveLock; + +/** + * Implementing a shared resource based recursive {@link javax.media.nativewindow.ToolkitLock}. + *

+ * A resource handle maybe used within many objects + * and can be synchronized across threads via an unique instance of SharedResourceToolkitLock. + *

+ *

+ * Implementation holds a synchronized map from handle to reference counted {@link SharedResourceToolkitLock}. + * New elements are added via {@link #get(long)} if new + * and removed via {@link #dispose()} if no more referenced. + *

+ */ +public class SharedResourceToolkitLock implements ToolkitLock { + public static final boolean DEBUG = Debug.debug("ToolkitLock"); + private static final LongObjectHashMap handle2Lock; + static { + handle2Lock = new LongObjectHashMap(); + handle2Lock.setKeyNotFoundValue(null); + } + + /** + * @return number of unclosed EGL Displays.
+ */ + public static int shutdown(boolean verbose) { + if(DEBUG || verbose || handle2Lock.size() > 0 ) { + System.err.println("SharedResourceToolkitLock: Shutdown (open: "+handle2Lock.size()+")"); + if(DEBUG) { + Thread.dumpStack(); + } + if( handle2Lock.size() > 0) { + dumpOpenDisplayConnections(); + } + } + return handle2Lock.size(); + } + + public static void dumpOpenDisplayConnections() { + System.err.println("SharedResourceToolkitLock: Open ResourceToolkitLock's: "+handle2Lock.size()); + int i=0; + for(Iterator iter = handle2Lock.iterator(); iter.hasNext(); i++) { + final LongObjectHashMap.Entry e = iter.next(); + System.err.println("SharedResourceToolkitLock: Open["+i+"]: "+e.value); + } + } + + public static final SharedResourceToolkitLock get(long handle) { + SharedResourceToolkitLock res; + synchronized(handle2Lock) { + res = (SharedResourceToolkitLock) handle2Lock.get(handle); + if( null == res ) { + res = new SharedResourceToolkitLock(handle); + res.refCount++; + handle2Lock.put(handle, res); + if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.get() * NEW *: "+res); } + } else { + res.refCount++; + if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.get() * EXIST *: "+res); } + } + } + return res; + } + + private final RecursiveLock lock; + private final long handle; + private volatile int refCount; + + private SharedResourceToolkitLock(long handle) { + this.lock = LockFactory.createRecursiveLock(); + this.handle = handle; + this.refCount = 0; + } + + + public final void lock() { + if(TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.lock()"); } + lock.lock(); + } + + public final void unlock() { + if(TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.unlock()"); } + lock.unlock(); + } + + public final void dispose() { + if(0 < refCount) { // volatile OK + synchronized(handle2Lock) { + refCount--; + if(0 == refCount) { + if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.dispose() * REMOV *: "+this); } + handle2Lock.remove(handle); + } else { + if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.dispose() * DOWN *: "+this); } + } + } + } else { + if(DEBUG || TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.dispose() * NULL *: "+this); } + } + } + + public String toString() { + return "SharedResourceToolkitLock[refCount "+refCount+", handle 0x"+Long.toHexString(handle)+", obj 0x"+Integer.toHexString(hashCode())+", isOwner "+lock.isOwner(Thread.currentThread())+", "+lock.toString()+"]"; + } +} diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java index f1e8a786a..7c934b154 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java @@ -237,6 +237,9 @@ public class JAWTUtil { public final void unlock() { JAWTUtil.unlockToolkit(); } + public final void dispose() { + // nop + } }; // trigger native AWT toolkit / properties initialization diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java deleted file mode 100644 index 743d371b7..000000000 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ -package jogamp.nativewindow.jawt.x11; - -import jogamp.nativewindow.jawt.*; -import jogamp.nativewindow.x11.X11Lib; -import jogamp.nativewindow.x11.X11Util; -import javax.media.nativewindow.ToolkitLock; - -import com.jogamp.common.util.locks.LockFactory; -import com.jogamp.common.util.locks.RecursiveLock; - -/** - * Implementing a recursive {@link javax.media.nativewindow.ToolkitLock} - * utilizing JAWT's AWT lock via {@link JAWTUtil#lockToolkit()} and {@link X11Util#XLockDisplay(long)}. - *
- * This strategy should only be used if AWT is using the underlying native windowing toolkit - * in a not intrinsic thread safe manner, e.g. under X11 where no XInitThreads() call - * is issued before any other X11 usage. This is the current situation for e.g. Webstart or Applets. - */ -public class X11JAWTToolkitLock implements ToolkitLock { - long displayHandle; - RecursiveLock lock; - - public X11JAWTToolkitLock(long displayHandle) { - this.displayHandle = displayHandle; - if(!X11Util.isNativeLockAvailable()) { - lock = LockFactory.createRecursiveLock(); - } - } - - public final void lock() { - if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.lock() - native: "+(null==lock)); } - JAWTUtil.lockToolkit(); - if(null == lock) { - X11Lib.XLockDisplay(displayHandle); - } else { - lock.lock(); - } - } - - public final void unlock() { - if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.unlock() - native: "+(null==lock)); } - if(null == lock) { - X11Lib.XUnlockDisplay(displayHandle); - } else { - lock.unlock(); - } - JAWTUtil.unlockToolkit(); - } -} diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java index 736718de8..467809284 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java @@ -127,7 +127,8 @@ public class X11JAWTWindow extends JAWTWindow { } protected Point getLocationOnScreenNativeImpl(int x, int y) { - return X11Lib.GetRelativeLocation( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y); + // surface is locked and hence the device + return X11Lib.GetRelativeLocation(getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y); } // Variables for lockSurface/unlockSurface diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java deleted file mode 100644 index 5166ef577..000000000 --- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ -package jogamp.nativewindow.x11; - -import javax.media.nativewindow.ToolkitLock; - -import com.jogamp.common.util.locks.LockFactory; -import com.jogamp.common.util.locks.RecursiveLock; - -/** - * Implementing a recursive {@link javax.media.nativewindow.ToolkitLock} - * utilizing {@link X11Util#XLockDisplay(long)}. - *
- * This strategy should not be used in case XInitThreads() is being used, - * or a higher level toolkit lock is required, ie AWT lock. - */ -public class X11ToolkitLock implements ToolkitLock { - long displayHandle; - RecursiveLock lock; - - public X11ToolkitLock(long displayHandle) { - this.displayHandle = displayHandle; - if(!X11Util.isNativeLockAvailable()) { - lock = LockFactory.createRecursiveLock(); - } - } - - public final void lock() { - if(TRACE_LOCK) { System.err.println("X11ToolkitLock.lock() - native: "+(null==lock)); } - if(null == lock) { - X11Lib.XLockDisplay(displayHandle); - } else { - lock.lock(); - } - } - - public final void unlock() { - if(TRACE_LOCK) { System.err.println("X11ToolkitLock.unlock() - native: "+(null==lock)); } - if(null == lock) { - X11Lib.XUnlockDisplay(displayHandle); - } else { - lock.unlock(); - } - } -} diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java index 2ea75c7fb..60f54eb3c 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java @@ -42,8 +42,8 @@ import javax.media.nativewindow.NativeWindowFactory; import jogamp.nativewindow.Debug; import jogamp.nativewindow.NWJNILibLoader; - import com.jogamp.common.util.LongObjectHashMap; +import com.jogamp.nativewindow.x11.X11GraphicsDevice; /** * Contains a thread safe X11 utility to retrieve display connections. @@ -80,25 +80,15 @@ public class X11Util { */ public static final boolean ATI_HAS_XCLOSEDISPLAY_BUG = !Debug.isPropertyDefined("nativewindow.debug.X11Util.ATI_HAS_NO_XCLOSEDISPLAY_BUG", true); - /** Value is true, best 'stable' results if always using XInitThreads(). */ - public static final boolean XINITTHREADS_ALWAYS_ENABLED = true; - - /** Value is true, best 'stable' results if not using XLockDisplay/XUnlockDisplay at all. */ - public static final boolean HAS_XLOCKDISPLAY_BUG = true; - public static final boolean DEBUG = Debug.debug("X11Util"); public static final boolean XSYNC_ENABLED = Debug.isPropertyDefined("nativewindow.debug.X11Util.XSync", true); public static final boolean XERROR_STACKDUMP = DEBUG || Debug.isPropertyDefined("nativewindow.debug.X11Util.XErrorStackDump", true); private static final boolean TRACE_DISPLAY_LIFECYCLE = Debug.isPropertyDefined("nativewindow.debug.X11Util.TraceDisplayLifecycle", true); private static String nullDisplayName = null; - private static boolean isX11LockAvailable = false; - private static boolean requiresX11Lock = true; private static volatile boolean isInit = false; private static boolean markAllDisplaysUnclosable = false; // ATI/AMD X11 driver issues - private static int setX11ErrorHandlerRecCount = 0; private static Object setX11ErrorHandlerLock = new Object(); - /** * Called by {@link NativeWindowFactory#initSingleton()} @@ -115,9 +105,7 @@ public class X11Util { throw new NativeWindowException("NativeWindow X11 native library load error."); } - final boolean callXInitThreads = XINITTHREADS_ALWAYS_ENABLED ; - final boolean isXInitThreadsOK = initialize0( callXInitThreads, XERROR_STACKDUMP); - isX11LockAvailable = isXInitThreadsOK && !HAS_XLOCKDISPLAY_BUG ; + final boolean isInitOK = initialize0( XERROR_STACKDUMP ); final long dpy = X11Lib.XOpenDisplay(null); if(0 != dpy) { @@ -134,9 +122,7 @@ public class X11Util { } if(DEBUG) { - System.err.println("X11Util requiresX11Lock "+requiresX11Lock+ - ", XInitThreads [called "+callXInitThreads+", OK "+isXInitThreadsOK+"]"+ - ", isX11LockAvailable "+isX11LockAvailable+ + System.err.println("X11Util init OK "+isInitOK+"]"+ ", X11 Display(NULL) <"+nullDisplayName+">"+ ", XSynchronize Enabled: "+XSYNC_ENABLED); // Thread.dumpStack(); @@ -199,31 +185,14 @@ public class X11Util { } } } - - public static synchronized boolean isNativeLockAvailable() { - return isX11LockAvailable; - } - - public static synchronized boolean requiresToolkitLock() { - return requiresX11Lock; + + public static boolean requiresToolkitLock() { + return true; // JAWT locking: yes, instead of native X11 locking w use a recursive lock. } - + public static void setX11ErrorHandler(boolean onoff, boolean quiet) { synchronized(setX11ErrorHandlerLock) { - if(onoff) { - if(0==setX11ErrorHandlerRecCount) { - setX11ErrorHandler0(true, quiet); - } - setX11ErrorHandlerRecCount++; - } else { - if(0 >= setX11ErrorHandlerRecCount) { - throw new InternalError(); - } - setX11ErrorHandlerRecCount--; - if(0==setX11ErrorHandlerRecCount) { - setX11ErrorHandler0(false, false); - } - } + setX11ErrorHandler0(onoff, quiet); } } @@ -492,52 +461,50 @@ public class X11Util { *******************************/ public static long XOpenDisplay(String arg0) { - NativeWindowFactory.getDefaultToolkitLock().lock(); - try { - long handle = X11Lib.XOpenDisplay(arg0); - if(XSYNC_ENABLED && 0 != handle) { - X11Lib.XSynchronize(handle, true); - } - if(TRACE_DISPLAY_LIFECYCLE) { - System.err.println(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle)); - // Thread.dumpStack(); - } - return handle; - } finally { - NativeWindowFactory.getDefaultToolkitLock().unlock(); + long handle = X11Lib.XOpenDisplay(arg0); + if(XSYNC_ENABLED && 0 != handle) { + X11Lib.XSynchronize(handle, true); + } + if(TRACE_DISPLAY_LIFECYCLE) { + System.err.println(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle)); + // Thread.dumpStack(); } + return handle; } public static int XCloseDisplay(long display) { - NativeWindowFactory.getDefaultToolkitLock().lock(); + if(TRACE_DISPLAY_LIFECYCLE) { + System.err.println(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display)); + // Thread.dumpStack(); + } + int res = -1; try { - if(TRACE_DISPLAY_LIFECYCLE) { - System.err.println(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display)); - // Thread.dumpStack(); - } - int res = -1; - X11Util.setX11ErrorHandler(true, DEBUG ? false : true); - try { - res = X11Lib.XCloseDisplay(display); - } catch (Exception ex) { - System.err.println("X11Util: Catched Exception:"); - ex.printStackTrace(); - } finally { - X11Util.setX11ErrorHandler(false, false); - } - return res; - } finally { - NativeWindowFactory.getDefaultToolkitLock().unlock(); + res = X11Lib.XCloseDisplay(display); + } catch (Exception ex) { + System.err.println("X11Util: Catched Exception:"); + ex.printStackTrace(); } + return res; } static volatile boolean XineramaFetched = false; static long XineramaLibHandle = 0; static long XineramaQueryFunc = 0; - public static boolean XineramaIsEnabled(long display) { - if(0==display) { - throw new IllegalArgumentException("Display NULL"); + public static boolean XineramaIsEnabled(X11GraphicsDevice device) { + if(null == device) { + throw new IllegalArgumentException("X11 Display device is NULL"); + } + device.lock(); + try { + return XineramaIsEnabled(device.getHandle()); + } finally { + device.unlock(); + } + } + public static boolean XineramaIsEnabled(long displayHandle) { + if( 0 == displayHandle ) { + throw new IllegalArgumentException("X11 Display handle is NULL"); } if(!XineramaFetched) { // volatile: ok synchronized(X11Util.class) { @@ -551,9 +518,9 @@ public class X11Util { } } if(0!=XineramaQueryFunc) { - final boolean res = X11Lib.XineramaIsEnabled(XineramaQueryFunc, display); + final boolean res = X11Lib.XineramaIsEnabled(XineramaQueryFunc, displayHandle); if(DEBUG) { - System.err.println("XineramaIsEnabled: "+res); + System.err.println("XineramaIsEnabled: 0x"+Long.toHexString(displayHandle)+": "+res); } return res; } else if(DEBUG) { @@ -566,7 +533,7 @@ public class X11Util { private static final String getCurrentThreadName() { return Thread.currentThread().getName(); } // Callback for JNI private static final void dumpStack() { Thread.dumpStack(); } // Callback for JNI - private static native boolean initialize0(boolean firstUIActionOnProcess, boolean debug); + private static native boolean initialize0(boolean debug); private static native void shutdown0(); private static native void setX11ErrorHandler0(boolean onoff, boolean quiet); } diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java index 1de03e8be..b152f0f97 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java @@ -91,7 +91,7 @@ public class X11AWTGraphicsConfigurationFactory extends GraphicsConfigurationFac final long displayHandleAWT = X11SunJDKReflection.graphicsDeviceGetDisplay(device); final long displayHandle; - boolean owner = false; + final boolean owner; if(0==displayHandleAWT) { displayHandle = X11Util.openDisplay(null); owner = true; @@ -112,9 +112,8 @@ public class X11AWTGraphicsConfigurationFactory extends GraphicsConfigurationFac System.err.println(getThreadName()+" - X11AWTGraphicsConfigurationFactory: AWT dpy "+displayName+" / "+toHexString(displayHandleAWT)+", create X11 display "+toHexString(displayHandle)); } } - final ToolkitLock lock = owner ? - NativeWindowFactory.getDefaultToolkitLock(NativeWindowFactory.TYPE_AWT) : // own non-shared X11 display connection, no X11 lock - NativeWindowFactory.createDefaultToolkitLock(NativeWindowFactory.TYPE_X11, NativeWindowFactory.TYPE_AWT, displayHandle); + // Global JAWT lock required - No X11 resource locking due to private display connection + final ToolkitLock lock = NativeWindowFactory.getDefaultToolkitLock(NativeWindowFactory.TYPE_AWT); final X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, lock, owner); final X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex()); if(DEBUG) { diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c index fcba8580c..afdd413eb 100644 --- a/src/nativewindow/native/x11/Xmisc.c +++ b/src/nativewindow/native/x11/Xmisc.c @@ -178,11 +178,14 @@ static int x11ErrorHandler(Display *dpy, XErrorEvent *e) char threadName[80]; char errCodeStr[80]; char reqCodeStr[80]; - int shallBeDetached = 0; - JNIEnv *jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); + JNIEnv *jniEnv = NULL; + if( errorHandlerDebug || errorHandlerThrowException ) { + jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); + } (void) NativewindowCommon_GetStaticStringMethod(jniEnv, X11UtilClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a"); + snprintf(errCodeStr, sizeof(errCodeStr), "%d", e->request_code); XGetErrorDatabaseText(dpy, "XRequest", errCodeStr, "Unknown", reqCodeStr, sizeof(reqCodeStr)); XGetErrorText(dpy, e->error_code, errCodeStr, sizeof(errCodeStr)); @@ -191,7 +194,7 @@ static int x11ErrorHandler(Display *dpy, XErrorEvent *e) threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial, (int)e->request_code, (int)e->minor_code, reqCodeStr); - if( errorHandlerDebug ) { + if( errorHandlerDebug && NULL != jniEnv ) { (*jniEnv)->CallStaticVoidMethod(jniEnv, X11UtilClazz, dumpStackID); } @@ -246,16 +249,17 @@ static int x11IOErrorHandler(Display *dpy) { const char * dpyName = XDisplayName(NULL); const char * errnoStr = strerror(errno); - char threadName[80]; int shallBeDetached = 0; - JNIEnv *jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); - - (void) NativewindowCommon_GetStaticStringMethod(jniEnv, X11UtilClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a"); + JNIEnv *jniEnv = NULL; - fprintf(stderr, "Nativewindow X11 IOError (Thread %s): Display %p (%s): %s\n", threadName, dpy, dpyName, errnoStr); + fprintf(stderr, "Nativewindow X11 IOError: Display %p (%s): %s\n", dpy, dpyName, errnoStr); (*jniEnv)->CallStaticVoidMethod(jniEnv, X11UtilClazz, dumpStackID); + jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); if (NULL != jniEnv) { + char threadName[80]; + (void) NativewindowCommon_GetStaticStringMethod(jniEnv, X11UtilClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a"); + NativewindowCommon_FatalError(jniEnv, "Nativewindow X11 IOError (Thread %s): Display %p (%s): %s", threadName, dpy, dpyName, errnoStr); if (shallBeDetached) { @@ -305,6 +309,7 @@ Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass clazz, jboo _initClazzAccess(env); x11IOErrorHandlerEnable(1, env); + NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 1, 0, 0 /* no dpy, no sync */); _initialized=1; if(JNI_TRUE == debug) { fprintf(stderr, "Info: NativeWindow native init passed\n"); @@ -315,6 +320,7 @@ Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass clazz, jboo JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Util_shutdown0(JNIEnv *env, jclass _unused) { + NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, 0 /* no dpy, no sync */); x11IOErrorHandlerEnable(0, env); } @@ -347,7 +353,7 @@ Java_jogamp_nativewindow_x11_X11Lib_XGetVisualInfo1__JJLjava_nio_ByteBuffer_2Lja } NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 1, 0, 0); _res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3); - NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 0, 0); + // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 0, 0); count = _ptr3[0]; if (arg3 != NULL) { (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0); @@ -382,7 +388,7 @@ Java_jogamp_nativewindow_x11_X11Lib_GetVisualIDFromWindow(JNIEnv *env, jclass _u } else { r = 0; } - NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); + // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); return r; } @@ -396,7 +402,7 @@ Java_jogamp_nativewindow_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass _unused, } NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 1, 0, 0); r = (jint) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) ); - NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 0, 0, 0); + // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 0, 0, 0); return r; } @@ -439,7 +445,7 @@ Java_jogamp_nativewindow_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused } NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 1, 0, 0); _res = XCloseDisplay((Display *) (intptr_t) display); - NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, 0); + // NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, 0); return _res; } @@ -497,7 +503,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow if (visual==NULL) { - NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); + // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); NativewindowCommon_throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!"); return 0; } @@ -541,7 +547,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow XSelectInput(dpy, window, 0); // no events - NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); + // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", window, dpy); @@ -569,7 +575,7 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow XUnmapWindow(dpy, w); XSync(dpy, False); XDestroyWindow(dpy, w); - NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); + // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); } /* @@ -597,7 +603,7 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_x11_X11Lib_GetRelativeLocatio res = XTranslateCoordinates(dpy, src_win, dest_win, src_x, src_y, &dest_x, &dest_y, &child); - NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0); + // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0); DBG_PRINT( "X11: GetRelativeLocation0: %p %d/%d -> %p %d/%d - ok: %d\n", (void*)src_win, src_x, src_y, (void*)dest_win, dest_x, dest_y, (int)res); diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java index 1e9a0e9eb..391bccf3d 100644 --- a/src/newt/classes/com/jogamp/newt/Display.java +++ b/src/newt/classes/com/jogamp/newt/Display.java @@ -113,16 +113,22 @@ public abstract class Display { */ public abstract int removeReference(); + /** + * Return the {@link AbstractGraphicsDevice} used for depending resources lifecycle, + * i.e. {@link Screen} and {@link Window}, as well as the event dispatching (EDT). */ public abstract AbstractGraphicsDevice getGraphicsDevice(); /** - * @return the fully qualified Display name, - * which is a key of {@link #getType()} + {@link #getName()} + {@link #getId()} + * Return the handle of the {@link AbstractGraphicsDevice} as returned by {@link #getGraphicsDevice()}. */ - public abstract String getFQName(); - public abstract long getHandle(); + /** + * @return The fully qualified Display name, + * which is a key of {@link #getType()} + {@link #getName()} + {@link #getId()}. + */ + public abstract String getFQName(); + /** * @return this display internal serial id */ @@ -141,6 +147,9 @@ public abstract class Display { */ public abstract String getType(); + /** Return true if this instance is exclusive, i.e. will not be shared. */ + public abstract boolean isExclusive(); + /** * Sets a new {@link EDTUtil} and returns the previous one. *

@@ -183,11 +192,12 @@ public abstract class Display { * * @param type * @param name - * @param fromIndex start index, then increasing until found or end of list * + * @param fromIndex start index, then increasing until found or end of list + * @paran shared if true, only shared instances are found, otherwise also exclusive * @return */ - public static Display getFirstDisplayOf(String type, String name, int fromIndex) { - return getDisplayOfImpl(type, name, fromIndex, 1); + public static Display getFirstDisplayOf(String type, String name, int fromIndex, boolean shared) { + return getDisplayOfImpl(type, name, fromIndex, 1, shared); } /** @@ -195,19 +205,22 @@ public abstract class Display { * @param type * @param name * @param fromIndex start index, then decreasing until found or end of list. -1 is interpreted as size - 1. + * @paran shared if true, only shared instances are found, otherwise also exclusive * @return */ - public static Display getLastDisplayOf(String type, String name, int fromIndex) { - return getDisplayOfImpl(type, name, fromIndex, -1); + public static Display getLastDisplayOf(String type, String name, int fromIndex, boolean shared) { + return getDisplayOfImpl(type, name, fromIndex, -1, shared); } - private static Display getDisplayOfImpl(String type, String name, int fromIndex, int incr) { + private static Display getDisplayOfImpl(String type, String name, int fromIndex, int incr, boolean shared) { synchronized(displayList) { int i = fromIndex >= 0 ? fromIndex : displayList.size() - 1 ; while( ( incr > 0 ) ? i < displayList.size() : i >= 0 ) { Display display = (Display) displayList.get(i); if( display.getType().equals(type) && - display.getName().equals(name) ) { + display.getName().equals(name) && + ( !shared || shared && !display.isExclusive() ) + ) { return display; } i+=incr; diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java index abae94ab6..1bf47f4aa 100644 --- a/src/newt/classes/com/jogamp/newt/NewtFactory.java +++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java @@ -305,7 +305,7 @@ public class NewtFactory { * Instantiate a Display entity using the native handle. */ public static Display createDisplay(String type, long handle, boolean reuse) { - return DisplayImpl.create(type, null, handle, false); + return DisplayImpl.create(type, null, handle, reuse); } public static boolean isScreenCompatible(NativeWindow parent, Screen childScreen) { diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java index 26f19ad6b..cfbcc988a 100644 --- a/src/newt/classes/com/jogamp/newt/Screen.java +++ b/src/newt/classes/com/jogamp/newt/Screen.java @@ -145,7 +145,7 @@ public abstract class Screen { public abstract Display getDisplay(); /** - * @return the screen fully qualified Screen name, + * @return The screen fully qualified Screen name, * which is a key of {@link com.jogamp.newt.Display#getFQName()} + {@link #getIndex()}. */ public abstract String getFQName(); diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java index bca7f6e5b..daeb3e886 100644 --- a/src/newt/classes/jogamp/newt/DisplayImpl.java +++ b/src/newt/classes/jogamp/newt/DisplayImpl.java @@ -42,6 +42,7 @@ import com.jogamp.newt.event.NEWTEventConsumer; import jogamp.newt.event.NEWTEventTask; import com.jogamp.newt.util.EDTUtil; import java.util.ArrayList; + import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeWindowException; @@ -66,7 +67,7 @@ public abstract class DisplayImpl extends Display { name = display.validateDisplayName(name, handle); synchronized(displayList) { if(reuse) { - Display display0 = Display.getLastDisplayOf(type, name, -1); + Display display0 = Display.getLastDisplayOf(type, name, -1, true /* shared only */); if(null != display0) { if(DEBUG) { System.err.println("Display.create() REUSE: "+display0+" "+getThreadName()); @@ -74,9 +75,9 @@ public abstract class DisplayImpl extends Display { return display0; } } + display.exclusive = !reuse; display.name = name; display.type=type; - display.destroyWhenUnused=false; display.refCount=0; display.id = serialno++; display.fqname = getFQName(display.type, display.name, display.id); @@ -94,7 +95,7 @@ public abstract class DisplayImpl extends Display { throw new RuntimeException(e); } } - + @Override public boolean equals(Object obj) { if (obj == null) { @@ -116,10 +117,12 @@ public abstract class DisplayImpl extends Display { return true; } + @Override public int hashCode() { return hashCode; } + @Override public synchronized final void createNative() throws NativeWindowException { @@ -148,10 +151,6 @@ public abstract class DisplayImpl extends Display { } } - protected boolean shallRunOnEDT() { - return true; - } - protected EDTUtil createEDTUtil() { final EDTUtil def; if(NewtFactory.useEDT()) { @@ -179,12 +178,7 @@ public abstract class DisplayImpl extends Display { if(DEBUG) { System.err.println("Display.setEDTUtil: "+oldEDTUtil+" -> "+newEDTUtil); } - if(null != oldEDTUtil) { - stopEDT( new Runnable() { public void run() {} } ); - // ready for restart .. - oldEDTUtil.waitUntilStopped(); - oldEDTUtil.reset(); - } + removeEDT( new Runnable() { public void run() {} } ); edtUtil = newEDTUtil; return oldEDTUtil; } @@ -194,16 +188,19 @@ public abstract class DisplayImpl extends Display { return edtUtil; } - private void stopEDT(final Runnable task) { - if( shallRunOnEDT() && null!=edtUtil ) { + private void removeEDT(final Runnable task) { + if(null!=edtUtil) { edtUtil.invokeStop(task); + // ready for restart .. + edtUtil.waitUntilStopped(); + edtUtil.reset(); } else { task.run(); } } public void runOnEDTIfAvail(boolean wait, final Runnable task) { - if( shallRunOnEDT() && null!=edtUtil && !edtUtil.isCurrentThreadEDT()) { + if( null!=edtUtil && !edtUtil.isCurrentThreadEDT()) { edtUtil.invoke(wait, task); } else { task.run(); @@ -212,18 +209,17 @@ public abstract class DisplayImpl extends Display { public boolean validateEDT() { if(0==refCount && null==aDevice && null != edtUtil && edtUtil.isRunning()) { - stopEDT( new Runnable() { + removeEDT( new Runnable() { public void run() { // nop } } ); - edtUtil.waitUntilStopped(); - edtUtil.reset(); return true; } return false; } + @Override public synchronized final void destroy() { if(DEBUG) { dumpDisplayList("Display.destroy("+getFQName()+") BEGIN"); @@ -239,17 +235,13 @@ public abstract class DisplayImpl extends Display { } final AbstractGraphicsDevice f_aDevice = aDevice; final DisplayImpl f_dpy = this; - stopEDT( new Runnable() { + removeEDT( new Runnable() { public void run() { if ( null != f_aDevice ) { f_dpy.closeNativeImpl(); } } } ); - if(null!=edtUtil) { - edtUtil.waitUntilStopped(); - edtUtil.reset(); - } aDevice = null; refCount=0; if(DEBUG) { @@ -290,21 +282,30 @@ public abstract class DisplayImpl extends Display { protected abstract void createNativeImpl(); protected abstract void closeNativeImpl(); + @Override public final int getId() { return id; } + @Override public final String getType() { return type; } + @Override public final String getName() { return name; } + @Override public final String getFQName() { return fqname; } + + @Override + public final boolean isExclusive() { + return exclusive; + } public static final String nilString = "nil" ; @@ -324,9 +325,10 @@ public abstract class DisplayImpl extends Display { sb.append(name); sb.append("-"); sb.append(id); - return sb.toString().intern(); + return sb.toString(); } + @Override public final long getHandle() { if(null!=aDevice) { return aDevice.getHandle(); @@ -334,14 +336,17 @@ public abstract class DisplayImpl extends Display { return 0; } + @Override public final AbstractGraphicsDevice getGraphicsDevice() { return aDevice; } + @Override public synchronized final boolean isNativeValid() { return null != aDevice; } + @Override public boolean isEDTRunning() { if(null!=edtUtil) { return edtUtil.isRunning(); @@ -351,7 +356,7 @@ public abstract class DisplayImpl extends Display { @Override public String toString() { - return "NEWT-Display["+getFQName()+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", edtRunning "+isEDTRunning()+", "+aDevice+"]"; + return "NEWT-Display["+getFQName()+", excl "+exclusive+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", edtRunning "+isEDTRunning()+", "+aDevice+"]"; } protected abstract void dispatchMessagesNative(); @@ -403,6 +408,7 @@ public abstract class DisplayImpl extends Display { eventTask.notifyCaller(); } + @Override public void dispatchMessages() { // System.err.println("Display.dispatchMessages() 0 "+this+" "+getThreadName()); if(0==refCount || // no screens @@ -475,20 +481,23 @@ public abstract class DisplayImpl extends Display { public interface DisplayRunnable { T run(long dpy); } - public final T runWithLockedDisplayHandle(DisplayRunnable action) { - final AbstractGraphicsDevice aDevice = getGraphicsDevice(); - if(null == aDevice) { - throw new RuntimeException("null device - not initialized: "+this); - } + public static final T runWithLockedDevice(AbstractGraphicsDevice device, DisplayRunnable action) { T res; - aDevice.lock(); + device.lock(); try { - res = action.run(aDevice.getHandle()); + res = action.run(device.getHandle()); } finally { - aDevice.unlock(); + device.unlock(); } return res; } + public final T runWithLockedDisplayDevice(DisplayRunnable action) { + final AbstractGraphicsDevice device = getGraphicsDevice(); + if(null == device) { + throw new RuntimeException("null device - not initialized: "+this); + } + return runWithLockedDevice(device, action); + } protected EDTUtil edtUtil = null; protected int id; @@ -497,7 +506,7 @@ public abstract class DisplayImpl extends Display { protected String fqname; protected int hashCode; protected int refCount; // number of Display references by Screen - protected boolean destroyWhenUnused; + protected boolean exclusive; // do not share this display, uses NullLock! protected AbstractGraphicsDevice aDevice; } diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java index e2c0f746f..1cc53e80e 100644 --- a/src/newt/classes/jogamp/newt/ScreenImpl.java +++ b/src/newt/classes/jogamp/newt/ScreenImpl.java @@ -42,7 +42,6 @@ import java.util.List; import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.util.Dimension; import javax.media.nativewindow.util.DimensionImmutable; import javax.media.nativewindow.util.Point; @@ -130,7 +129,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { } } screen.screen_idx = idx; - screen.fqname = (display.getFQName()+idx).intern(); + screen.fqname = display.getFQName()+"-s"+idx; screen.hashCode = screen.fqname.hashCode(); screenList.add(screen); if(DEBUG) { diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index c1ac87d38..79770189b 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -85,7 +85,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private volatile long windowHandle = 0; // lifecycle critical private volatile boolean visible = false; // lifecycle critical private RecursiveLock windowLock = LockFactory.createRecursiveLock(); // Window instance wide lock - private RecursiveLock surfaceLock = LockFactory.createRecursiveLock(); // Surface only lock + private int surfaceLockCount = 0; // surface lock recursion count private ScreenImpl screen; // never null after create - may change reference though (reparent) private boolean screenReferenceAdded = false; @@ -553,10 +553,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer @Override public final int lockSurface() throws NativeWindowException, RuntimeException { final RecursiveLock _wlock = windowLock; - final RecursiveLock _slock = surfaceLock; _wlock.lock(); - _slock.lock(); - int res = _slock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ? + surfaceLockCount++; + int res = ( 1 == surfaceLockCount ) ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ? if ( LOCK_SURFACE_NOT_READY == res ) { try { @@ -573,7 +572,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } finally { if (LOCK_SURFACE_NOT_READY >= res) { - _slock.unlock(); _wlock.unlock(); } } @@ -583,12 +581,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer @Override public final void unlockSurface() { - final RecursiveLock _slock = surfaceLock; final RecursiveLock _wlock = windowLock; - _slock.validateLocked(); _wlock.validateLocked(); - if (_slock.getHoldCount() == 1) { + if ( 1 == surfaceLockCount ) { final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice(); try { unlockSurfaceImpl(); @@ -596,42 +592,48 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer adevice.unlock(); } } - _slock.unlock(); + surfaceLockCount--; _wlock.unlock(); } @Override public final boolean isSurfaceLockedByOtherThread() { - return surfaceLock.isLockedByOtherThread(); + return windowLock.isLockedByOtherThread(); } @Override public final Thread getSurfaceLockOwner() { - return surfaceLock.getOwner(); + return windowLock.getOwner(); } public final RecursiveLock getLock() { return windowLock; } + @Override public long getSurfaceHandle() { return windowHandle; // default: return window handle } + @Override public boolean surfaceSwap() { return false; } + @Override public final AbstractGraphicsConfiguration getGraphicsConfiguration() { return config.getNativeGraphicsConfiguration(); } - public final long getDisplayHandle() { - return getScreen().getDisplay().getHandle(); + @Override + public long getDisplayHandle() { + // Actually: return getGraphicsConfiguration().getScreen().getDevice().getHandle(); + return screen.getDisplay().getHandle(); // shortcut } + @Override public final int getScreenIndex() { - return getScreen().getIndex(); + return screen.getIndex(); } //---------------------------------------------------------------------- @@ -1554,8 +1556,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer for (int i = 0; i < keyListeners.size(); i++ ) { sb.append(keyListeners.get(i)+", "); } - sb.append("], surfaceLock "+surfaceLock); - sb.append(", windowLock "+windowLock+"]"); + sb.append("], windowLock "+windowLock+"]"); return sb.toString(); } diff --git a/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java index 70e9ba570..ead567d82 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java @@ -66,7 +66,9 @@ public class DisplayDriver extends DisplayImpl { return def; } - protected void closeNativeImpl() { } + protected void closeNativeImpl() { + aDevice.close(); + } protected void dispatchMessagesNative() { /* nop */ } } diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java index 65ca63eec..cc55c336e 100644 --- a/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java @@ -39,6 +39,7 @@ import javax.media.nativewindow.NativeWindowException; import jogamp.newt.NEWTJNILibLoader; import jogamp.opengl.egl.EGL; +import jogamp.opengl.egl.EGLDisplayUtil; import com.jogamp.nativewindow.egl.EGLGraphicsDevice; @@ -72,6 +73,7 @@ public class DisplayDriver extends jogamp.newt.DisplayImpl { if (aDevice.getHandle() != EGL.EGL_NO_DISPLAY) { DestroyDisplay(aDevice.getHandle()); } + aDevice.close(); } protected void dispatchMessagesNative() { diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java index 97c384d33..e370038d9 100644 --- a/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java @@ -84,6 +84,7 @@ public class DisplayDriver extends jogamp.newt.DisplayImpl { } } } + aDevice.close(); } protected void dispatchMessagesNative() { diff --git a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java index 1a3f14859..b49c6b6e0 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java @@ -72,7 +72,9 @@ public class DisplayDriver extends DisplayImpl { aDevice = new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); } - protected void closeNativeImpl() { } + protected void closeNativeImpl() { + aDevice.close(); + } public static void runNSApplication() { runNSApplication0(); diff --git a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java index 579ec5be8..615f9e63b 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java @@ -73,6 +73,7 @@ public class DisplayDriver extends DisplayImpl { protected void closeNativeImpl() { sharedClassFactory.releaseSharedClass(); + aDevice.close(); } protected void dispatchMessagesNative() { diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java index 714324d63..bff050030 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java @@ -36,7 +36,6 @@ package jogamp.newt.driver.x11; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.NativeWindowFactory; import com.jogamp.nativewindow.x11.X11GraphicsDevice; @@ -74,71 +73,48 @@ public class DisplayDriver extends DisplayImpl { * {@inheritDoc} * * We use a private non-shared X11 Display instance for EDT window operations and one for exposed animation, eg. OpenGL. - *

- * In case {@link X11Util#HAS_XLOCKDISPLAY_BUG} and {@link X11Util#XINITTHREADS_ALWAYS_ENABLED}, - * we use null locking. Even though this seems not to be rational, it gives most stable results on all platforms. - *

- *

- * Otherwise we use basic locking via the constructor {@link X11GraphicsDevice#X11GraphicsDevice(long, int, boolean)}, - * since it is possible to share this device via {@link com.jogamp.newt.NewtFactory#createDisplay(String, boolean)}. - *

*/ - @SuppressWarnings("unused") protected void createNativeImpl() { + X11Util.setX11ErrorHandler(true, DEBUG ? false : true); // make sure X11 error handler is set long handle = X11Util.openDisplay(name); if( 0 == handle ) { throw new RuntimeException("Error creating display(Win): "+name); } - if(USE_SEPARATE_DISPLAY_FOR_EDT) { - edtDisplayHandle = X11Util.openDisplay(name); - if( 0 == edtDisplayHandle ) { - X11Util.closeDisplay(handle); - throw new RuntimeException("Error creating display(EDT): "+name); - } - } else { - edtDisplayHandle = handle; - } + aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, true); try { - CompleteDisplay0(edtDisplayHandle); + CompleteDisplay0(aDevice.getHandle()); } catch(RuntimeException e) { closeNativeImpl(); throw e; - } - - // see API doc above! - if(X11Util.XINITTHREADS_ALWAYS_ENABLED && X11Util.HAS_XLOCKDISPLAY_BUG) { - aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock(), false); - } else { - aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, false); - } + } } protected void closeNativeImpl() { - DisplayRelease0(edtDisplayHandle, javaObjectAtom, windowDeleteAtom); + DisplayRelease0(aDevice.getHandle(), javaObjectAtom, windowDeleteAtom); javaObjectAtom = 0; windowDeleteAtom = 0; - // closing using ATI driver bug 'same order' - final long handle = getHandle(); - X11Util.closeDisplay(handle); - if(handle != edtDisplayHandle) { - X11Util.closeDisplay(edtDisplayHandle); - } - edtDisplayHandle = 0; + aDevice.close(); // closes X11 display } protected void dispatchMessagesNative() { - if(0 != edtDisplayHandle) { - DispatchMessages0(edtDisplayHandle, javaObjectAtom, windowDeleteAtom); + aDevice.lock(); + try { + final long handle = aDevice.getHandle(); + if(0 != handle) { + DispatchMessages0(handle, javaObjectAtom, windowDeleteAtom); + } + } finally { + aDevice.unlock(); } } - protected long getEDTHandle() { return edtDisplayHandle; } protected long getJavaObjectAtom() { return javaObjectAtom; } protected long getWindowDeleteAtom() { return windowDeleteAtom; } //---------------------------------------------------------------------- // Internals only // + private static native boolean initIDs0(boolean debug); private native void CompleteDisplay0(long handle); @@ -151,17 +127,6 @@ public class DisplayDriver extends DisplayImpl { private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom); - /** - * 2011/06/14 libX11 1.4.2 and libxcb 1.7 bug 20708 - Multithreading Issues w/ OpenGL, .. - * https://bugs.freedesktop.org/show_bug.cgi?id=20708 - * https://jogamp.org/bugzilla/show_bug.cgi?id=502 - * Affects: Ubuntu 11.04, OpenSuSE 11, .. - * Workaround: Using a separate X11 Display connection for event dispatching (EDT) - */ - private final boolean USE_SEPARATE_DISPLAY_FOR_EDT = true; - - private long edtDisplayHandle; - /** X11 Window delete atom marker used on EDT */ private long windowDeleteAtom; diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java index 10f6b84da..b09d98e06 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java @@ -59,7 +59,7 @@ public class ScreenDriver extends ScreenImpl { protected void createNativeImpl() { // validate screen index - Long handle = display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + Long handle = runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { public Long run(long dpy) { return new Long(GetScreen0(dpy, screen_idx)); } } ); @@ -81,7 +81,7 @@ public class ScreenDriver extends ScreenImpl { private int nmode_number; protected int[] getScreenModeFirstImpl() { - return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { public int[] run(long dpy) { // initialize iterators and static data nrotations = getAvailableScreenModeRotations0(dpy, screen_idx); @@ -110,7 +110,7 @@ public class ScreenDriver extends ScreenImpl { protected int[] getScreenModeNextImpl() { // assemble: w x h x bpp x f x r - return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { public int[] run(long dpy) { /** System.err.println("******** mode: "+nmode_number); @@ -176,7 +176,7 @@ public class ScreenDriver extends ScreenImpl { } protected ScreenMode getCurrentScreenModeImpl() { - return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { public ScreenMode run(long dpy) { long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx); if(0 == screenConfigHandle) { @@ -237,7 +237,7 @@ public class ScreenDriver extends ScreenImpl { throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode); } final long t0 = System.currentTimeMillis(); - boolean done = runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + boolean done = runWithTempDisplayHandle( new DisplayImpl.DisplayRunnable() { public Boolean run(long dpy) { boolean done = false; long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx); @@ -276,23 +276,21 @@ public class ScreenDriver extends ScreenImpl { return done; } - private class XineramaEnabledQuery implements DisplayImpl.DisplayRunnable { + private DisplayImpl.DisplayRunnable xineramaEnabledQueryWithTemp = new DisplayImpl.DisplayRunnable() { public Boolean run(long dpy) { return new Boolean(X11Util.XineramaIsEnabled(dpy)); - } - } - private XineramaEnabledQuery xineramaEnabledQuery = new XineramaEnabledQuery(); + } }; protected int validateScreenIndex(final int idx) { if(getDisplay().isNativeValid()) { - return runWithLockedDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx; + return X11Util.XineramaIsEnabled((X11GraphicsDevice)getDisplay().getGraphicsDevice()) ? 0 : idx; } else { - return runWithTempDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx; + return runWithTempDisplayHandle( xineramaEnabledQueryWithTemp ).booleanValue() ? 0 : idx; } } protected void getVirtualScreenOriginAndSize(final Point virtualOrigin, final Dimension virtualSize) { - display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { public Object run(long dpy) { virtualOrigin.setX(0); virtualOrigin.setY(0); @@ -305,10 +303,8 @@ public class ScreenDriver extends ScreenImpl { //---------------------------------------------------------------------- // Internals only // - private final T runWithLockedDisplayHandle(DisplayRunnable action) { - return display.runWithLockedDisplayHandle(action); - // return runWithTempDisplayHandle(action); - // return runWithoutLock(action); + private final T runWithLockedDisplayDevice(DisplayRunnable action) { + return display.runWithLockedDisplayDevice(action); } private final T runWithTempDisplayHandle(DisplayRunnable action) { @@ -324,9 +320,6 @@ public class ScreenDriver extends ScreenImpl { } return res; } - private final T runWithoutLock(DisplayRunnable action) { - return action.run(display.getHandle()); - } private static native long GetScreen0(long dpy, int scrn_idx); diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java index 97d1ae3db..aea86a420 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java @@ -35,6 +35,7 @@ package jogamp.newt.driver.x11; import jogamp.nativewindow.x11.X11Lib; +import jogamp.nativewindow.x11.X11Util; import jogamp.newt.DisplayImpl; import jogamp.newt.DisplayImpl.DisplayRunnable; import jogamp.newt.WindowImpl; @@ -44,6 +45,8 @@ import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.InsetsImmutable; import javax.media.nativewindow.util.Point; +import com.jogamp.nativewindow.x11.X11GraphicsDevice; +import com.jogamp.nativewindow.x11.X11GraphicsScreen; import com.jogamp.newt.event.MouseEvent; public class WindowDriver extends WindowImpl { @@ -63,9 +66,19 @@ public class WindowDriver extends WindowImpl { protected void createNativeImpl() { final ScreenDriver screen = (ScreenDriver) getScreen(); final DisplayDriver display = (DisplayDriver) screen.getDisplay(); + final AbstractGraphicsDevice edtDevice = display.getGraphicsDevice(); + + // Decoupled X11 Device/Screen allowing X11 display lock-free off-thread rendering + final long renderDeviceHandle = X11Util.openDisplay(edtDevice.getConnection()); + if( 0 == renderDeviceHandle ) { + throw new RuntimeException("Error creating display(EDT): "+edtDevice.getConnection()); + } + renderDevice = new X11GraphicsDevice(renderDeviceHandle, AbstractGraphicsDevice.DEFAULT_UNIT, true); + AbstractGraphicsScreen renderScreen = new X11GraphicsScreen((X11GraphicsDevice) renderDevice, screen.getIndex()); + final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice(), capsRequested); final AbstractGraphicsConfiguration cfg = factory.chooseGraphicsConfiguration( - capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED); + capsRequested, capsRequested, capabilitiesChooser, renderScreen, VisualIDHolder.VID_UNDEFINED); if(DEBUG_IMPLEMENTATION) { System.err.println("X11Window.createNativeImpl() factory: "+factory+", chosen config: "+cfg); } @@ -78,11 +91,16 @@ public class WindowDriver extends WindowImpl { } setGraphicsConfiguration(cfg); final int flags = getReconfigureFlags(0, true) & - ( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ; - setWindowHandle(CreateWindow0(getParentWindowHandle(), - display.getEDTHandle(), screen.getIndex(), visualID, - display.getJavaObjectAtom(), display.getWindowDeleteAtom(), - getX(), getY(), getWidth(), getHeight(), autoPosition(), flags)); + ( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ; + edtDevice.lock(); + try { + setWindowHandle(CreateWindow0(getParentWindowHandle(), + edtDevice.getHandle(), screen.getIndex(), visualID, + display.getJavaObjectAtom(), display.getWindowDeleteAtom(), + getX(), getY(), getWidth(), getHeight(), autoPosition(), flags)); + } finally { + edtDevice.unlock(); + } windowHandleClose = getWindowHandle(); if (0 == windowHandleClose) { throw new NativeWindowException("Error creating window"); @@ -92,8 +110,10 @@ public class WindowDriver extends WindowImpl { protected void closeNativeImpl() { if(0!=windowHandleClose && null!=getScreen() ) { DisplayDriver display = (DisplayDriver) getScreen().getDisplay(); + final AbstractGraphicsDevice edtDevice = display.getGraphicsDevice(); + edtDevice.lock(); try { - CloseWindow0(display.getEDTHandle(), windowHandleClose, + CloseWindow0(edtDevice.getHandle(), windowHandleClose, display.getJavaObjectAtom(), display.getWindowDeleteAtom()); } catch (Throwable t) { if(DEBUG_IMPLEMENTATION) { @@ -101,28 +121,47 @@ public class WindowDriver extends WindowImpl { e.printStackTrace(); } } finally { + edtDevice.unlock(); windowHandleClose = 0; } } + if(null != renderDevice) { + renderDevice.close(); // closes X11 display + renderDevice = null; + } } - protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { + @Override + public long getDisplayHandle() { + // Actually: return getGraphicsConfiguration().getScreen().getDevice().getHandle(); + return renderDevice.getHandle(); // shortcut + } + + protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final int flags) { if(DEBUG_IMPLEMENTATION) { System.err.println("X11Window reconfig: "+x+"/"+y+" "+width+"x"+height+", "+ getReconfigureFlagsAsString(null, flags)); } + final int _x, _y; if(0 == ( FLAG_IS_UNDECORATED & flags)) { final InsetsImmutable i = getInsets(); // client position -> top-level window position - x -= i.getLeftWidth() ; - y -= i.getTopHeight() ; + _x = x - i.getLeftWidth() ; + _y = y - i.getTopHeight() ; + } else { + _x = x; + _y = y; } final DisplayDriver display = (DisplayDriver) getScreen().getDisplay(); - reconfigureWindow0( getDisplayEDTHandle(), getScreenIndex(), - getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(), - x, y, width, height, flags); - + runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { + public Object run(long dpy) { + reconfigureWindow0( dpy, getScreenIndex(), + getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(), + _x, _y, width, height, flags); + return null; + } + }); return true; } @@ -133,13 +172,18 @@ public class WindowDriver extends WindowImpl { } } - protected void requestFocusImpl(boolean force) { - requestFocus0(getDisplayEDTHandle(), getWindowHandle(), force); + protected void requestFocusImpl(final boolean force) { + runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { + public Object run(long dpy) { + requestFocus0(dpy, getWindowHandle(), force); + return null; + } + }); } @Override protected void setTitleImpl(final String title) { - runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { public Object run(long dpy) { setTitle0(dpy, getWindowHandle(), title); return null; @@ -149,35 +193,38 @@ public class WindowDriver extends WindowImpl { @Override protected boolean setPointerVisibleImpl(final boolean pointerVisible) { - return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { public Boolean run(long dpy) { - return Boolean.valueOf(setPointerVisible0(getDisplayEDTHandle(), getWindowHandle(), pointerVisible)); + return Boolean.valueOf(setPointerVisible0(dpy, getWindowHandle(), pointerVisible)); } }).booleanValue(); } @Override protected boolean confinePointerImpl(final boolean confine) { - return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { public Boolean run(long dpy) { - return Boolean.valueOf(confinePointer0(getDisplayEDTHandle(), getWindowHandle(), confine)); + return Boolean.valueOf(confinePointer0(dpy, getWindowHandle(), confine)); } }).booleanValue(); } @Override protected void warpPointerImpl(final int x, final int y) { - runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable() { + runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { public Object run(long dpy) { - warpPointer0(getDisplayEDTHandle(), getWindowHandle(), x, y); + warpPointer0(dpy, getWindowHandle(), x, y); return null; } }); } protected Point getLocationOnScreenImpl(final int x, final int y) { - // X11Util.GetRelativeLocation: locks display already ! - return X11Lib.GetRelativeLocation( getScreen().getDisplay().getHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y); + return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { + public Point run(long dpy) { + return X11Lib.GetRelativeLocation(dpy, getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y); + } + } ); } protected void updateInsetsImpl(Insets insets) { @@ -229,16 +276,11 @@ public class WindowDriver extends WindowImpl { //---------------------------------------------------------------------- // Internals only // - private static final String getCurrentThreadName() { return Thread.currentThread().getName(); } // Callback for JNI private static final void dumpStack() { Thread.dumpStack(); } // Callback for JNI - private final long getDisplayEDTHandle() { - return ((DisplayDriver) getScreen().getDisplay()).getEDTHandle(); - } - private final T runWithLockedDisplayHandle(DisplayRunnable action) { - return ((DisplayImpl) getScreen().getDisplay()).runWithLockedDisplayHandle(action); - // return runWithTempDisplayHandle(action); + private final T runWithLockedDisplayDevice(DisplayRunnable action) { + return ((DisplayDriver) getScreen().getDisplay()).runWithLockedDisplayDevice(action); } protected static native boolean initIDs0(); @@ -258,4 +300,5 @@ public class WindowDriver extends WindowImpl { private static native void warpPointer0(long display, long windowHandle, int x, int y); private long windowHandleClose; + private AbstractGraphicsDevice renderDevice; } diff --git a/src/newt/native/X11Common.h b/src/newt/native/X11Common.h index 128b6b6f1..4d1a7b59e 100644 --- a/src/newt/native/X11Common.h +++ b/src/newt/native/X11Common.h @@ -70,7 +70,6 @@ extern jclass X11NewtWindowClazz; extern jmethodID insetsChangedID; extern jmethodID visibleChangedID; -void NewtDisplay_x11ErrorHandlerEnable(JNIEnv * env, Display *dpy, int onoff, int quiet, int sync); jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning); Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return); diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c index 84b3a7630..56c11fab4 100644 --- a/src/newt/native/X11Display.c +++ b/src/newt/native/X11Display.c @@ -52,90 +52,6 @@ static jmethodID enqueueKeyEventID = NULL; static jmethodID sendKeyEventID = NULL; static jmethodID requestFocusID = NULL; -static JavaVM *jvmHandle = NULL; -static int jvmVersion = 0; - -static void setupJVMVars(JNIEnv * env) { - if(0 != (*env)->GetJavaVM(env, &jvmHandle)) { - jvmHandle = NULL; - } - jvmVersion = (*env)->GetVersion(env); -} - -static XErrorHandler origErrorHandler = NULL ; -static int errorHandlerQuiet = 0 ; -static int errorHandlerDebug = 0 ; -static int errorHandlerThrowException = 0; - -static int x11ErrorHandler(Display *dpy, XErrorEvent *e) -{ - if(!errorHandlerQuiet) { - const char * errnoStr = strerror(errno); - char threadName[80]; - char errCodeStr[80]; - char reqCodeStr[80]; - - int shallBeDetached = 0; - JNIEnv *jniEnv = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); - - (void) NewtCommon_GetStaticStringMethod(jniEnv, X11NewtWindowClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a"); - snprintf(errCodeStr, sizeof(errCodeStr), "%d", e->request_code); - XGetErrorDatabaseText(dpy, "XRequest", errCodeStr, "Unknown", reqCodeStr, sizeof(reqCodeStr)); - XGetErrorText(dpy, e->error_code, errCodeStr, sizeof(errCodeStr)); - - fprintf(stderr, "Info: Newt X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n", - threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial, - (int)e->request_code, (int)e->minor_code, reqCodeStr); - - if( errorHandlerDebug ) { - (*jniEnv)->CallStaticVoidMethod(jniEnv, X11NewtWindowClazz, dumpStackID); - } - - if(errorHandlerThrowException) { - if(NULL != jniEnv) { - NewtCommon_throwNewRuntimeException(jniEnv, "Newt X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n", - threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial, - (int)e->request_code, (int)e->minor_code, reqCodeStr); - } else { - fprintf(stderr, "Nativewindow X11 Error: null JNIEnv"); - #if 0 - if(NULL!=origErrorHandler) { - origErrorHandler(dpy, e); - } - #endif - } - } - fflush(stderr); - - if (NULL != jniEnv && shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); - } - } - - return 0; -} - -void NewtDisplay_x11ErrorHandlerEnable(JNIEnv * env, Display *dpy, int onoff, int quiet, int sync) { - errorHandlerQuiet = quiet; - if(onoff) { - if(NULL==origErrorHandler) { - setupJVMVars(env); - origErrorHandler = XSetErrorHandler(x11ErrorHandler); - if(sync && NULL!=dpy) { - XSync(dpy, False); - } - } - } else { - if(NULL!=origErrorHandler) { - if(sync && NULL!=dpy) { - XSync(dpy, False); - } - XSetErrorHandler(origErrorHandler); - origErrorHandler = NULL; - } - } -} - /** * Keycode */ @@ -273,9 +189,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0 { jclass c; - if(debug) { - errorHandlerDebug = 1 ; - } NewtCommon_init(env); if(NULL==X11NewtWindowClazz) { @@ -439,8 +352,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type); - NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0); - jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom, #ifdef VERBOSE_ON True @@ -449,8 +360,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage #endif ); - NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); - if(NULL==jwindow) { fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", (void*)dpy, evt.type, (void*)evt.xany.window); diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 59862f463..2e16e7cae 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -683,16 +683,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0 DBG_PRINT( "X11: CloseWindow START dpy %p, win %p\n", (void*)dpy, (void*)w); - NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0); - jwindow = getJavaWindowProperty(env, dpy, w, javaObjectAtom, True); if(NULL==jwindow) { - NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); NewtCommon_throwNewRuntimeException(env, "could not fetch Java Window object, bail out!"); return; } if ( JNI_FALSE == (*env)->IsSameObject(env, jwindow, obj) ) { - NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); NewtCommon_throwNewRuntimeException(env, "Internal Error .. Window global ref not the same!"); return; } @@ -700,7 +696,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0 XSync(dpy, False); XSelectInput(dpy, w, 0); XUnmapWindow(dpy, w); - NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); // Drain all events related to this window .. Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom); @@ -761,8 +756,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo fsEWMHFlags |= _NET_WM_ABOVE; // toggle above } - NewtDisplay_x11ErrorHandlerEnable(env, dpy, 1, 0, 0); - 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", (void*)dpy, screen_index, (void*) jparent, (void*)parent, (void*)w, x, y, width, height, @@ -779,7 +772,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo ( 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) ) { - NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); #ifdef FS_GRAB_KEYBOARD if(TST_FLAG_CHANGE_FULLSCREEN(flags)) { if(TST_FLAG_IS_FULLSCREEN(flags)) { @@ -863,8 +855,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo #endif } - NewtDisplay_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); - DBG_PRINT( "X11: reconfigureWindow0 X\n"); } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java new file mode 100644 index 000000000..11d1331ed --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/InitConcurrentBaseNEWT.java @@ -0,0 +1,219 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.acore; + +import javax.media.nativewindow.Capabilities; +import javax.media.nativewindow.util.InsetsImmutable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLProfile; + +import org.junit.Assert; +import org.junit.BeforeClass; + +import com.jogamp.newt.Display; +import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.Screen; +import com.jogamp.newt.Window; +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.util.Animator; + +/** + * Concurrent and lock-free initialization and rendering using exclusive NEWT Display EDT instances, or + * concurrent locked initialization and lock-free rendering using a shared NEWT Display EDT instances. + *

+ * Rendering is always lock-free and independent of the EDT. + *

+ */ +public class InitConcurrentBaseNEWT extends UITestCase { + + static final int demoSize = 128; + + static long duration = 300; // ms + + static InsetsImmutable insets = null; + static int scrnHeight, scrnWidth; + static int num_x, num_y; + + @BeforeClass + public static void initClass() { + Window dummyWindow = NewtFactory.createWindow(new Capabilities()); + dummyWindow.setSize(demoSize, demoSize); + dummyWindow.setVisible(true); + Assert.assertEquals(true, dummyWindow.isVisible()); + Assert.assertEquals(true, dummyWindow.isNativeValid()); + insets = dummyWindow.getInsets(); + scrnHeight = dummyWindow.getScreen().getHeight(); + scrnWidth = dummyWindow.getScreen().getWidth(); + num_x = scrnWidth / ( demoSize + insets.getTotalWidth() ) - 2; + num_y = scrnHeight / ( demoSize + insets.getTotalHeight() ) - 2; + dummyWindow.destroy(); + } + + public class JOGLTask implements Runnable { + private final int id; + private final Object postSync; + private final boolean reuse; + private boolean done = false; + + public JOGLTask(Object postSync, int id, boolean reuse) { + this.postSync = postSync; + this.id = id; + this.reuse = reuse; + } + public void run() { + int x = ( id % num_x ) * ( demoSize + insets.getTotalHeight() ); + int y = ( (id / num_x) % num_y ) * ( demoSize + insets.getTotalHeight() ); + + System.err.println("JOGLTask "+id+": START: "+x+"/"+y+", reuse "+reuse+" - "+Thread.currentThread().getName()); + final Display display = NewtFactory.createDisplay(null, reuse); + final Screen screen = NewtFactory.createScreen(display, 0); + final GLWindow glWindow = GLWindow.create(screen, new GLCapabilities(GLProfile.getDefault())); + Assert.assertNotNull(glWindow); + glWindow.setTitle("Task "+id); + glWindow.setPosition(x + insets.getLeftWidth(), y + insets.getTopHeight() ); + + glWindow.addGLEventListener(new GearsES2(0)); + + Animator animator = new Animator(glWindow); + + glWindow.setSize(demoSize, demoSize); + glWindow.setVisible(true); + animator.setUpdateFPSFrames(60, null); + + System.err.println("JOGLTask "+id+": INITIALIZED: "+", "+display+" - "+Thread.currentThread().getName()); + + animator.start(); + Assert.assertEquals(true, animator.isAnimating()); + Assert.assertEquals(true, glWindow.isVisible()); + Assert.assertEquals(true, glWindow.isNativeValid()); + Assert.assertEquals(true, glWindow.isRealized()); + System.err.println("JOGLTask "+id+": RUNNING: "+Thread.currentThread().getName()); + + while(animator.isAnimating() && animator.getTotalFPSDuration()=0; i--) { + if(!tasks[i].done()) { + return false; + } + } + return true; + } + protected static String doneDump(JOGLTask[] tasks) { + StringBuilder sb = new StringBuilder(); + sb.append("["); + for(int i=0; i0) { + sb.append(", "); + } + sb.append(i).append(": ").append(tasks[i].done()); + } + sb.append("]"); + return sb.toString(); + } + + protected static boolean isDead(Thread[] threads) { + for(int i=threads.length-1; i>=0; i--) { + if(threads[i].isAlive()) { + return false; + } + } + return true; + } + protected static String isAliveDump(Thread[] threads) { + StringBuilder sb = new StringBuilder(); + sb.append("["); + for(int i=0; i0) { + sb.append(", "); + } + sb.append(i).append(": ").append(threads[i].isAlive()); + } + sb.append("]"); + return sb.toString(); + } + + protected void runJOGLTasks(int num, boolean reuse) throws InterruptedException { + final String currentThreadName = Thread.currentThread().getName(); + final Object syncDone = new Object(); + final JOGLTask[] tasks = new JOGLTask[num]; + final Thread[] threads = new Thread[num]; + int i; + for(i=0; i + * Rendering is always lock-free and independent of the EDT, however shared NEWT Display instances + * perform lifecycle actions (window creation etc) with locking. + *

+ */ +public class TestInitConcurrent01NEWT extends InitConcurrentBaseNEWT { + + @Test + public void test02TwoThreads() throws InterruptedException { + runJOGLTasks(2, true); + } + + @Test + public void test02FourThreads() throws InterruptedException { + runJOGLTasks(4, true); + } + + @Test + public void test16SixteenThreads() throws InterruptedException { + if( Platform.getCPUFamily() != Platform.CPUFamily.ARM ) { + runJOGLTasks(16, true); + } else { + runJOGLTasks( 8, true); + } + } + + public static void main(String args[]) throws IOException { + for(int i=0; i + * Rendering is always lock-free and independent of the EDT, however exclusive NEWT Display instances + * perform lifecycle actions (window creation etc) w/o locking. + *

+ */ +public class TestInitConcurrent02NEWT extends InitConcurrentBaseNEWT { + + @Test + public void test02TwoThreads() throws InterruptedException { + runJOGLTasks(2, false); + } + + @Test + public void test02FourThreads() throws InterruptedException { + runJOGLTasks(4, false); + } + + @Test + public void test16SixteenThreads() throws InterruptedException { + if( Platform.getCPUFamily() != Platform.CPUFamily.ARM ) { + runJOGLTasks(16, false); + } else { + runJOGLTasks( 8, false); + } + } + + public static void main(String args[]) throws IOException { + for(int i=0; i=0; i--) { - if(!tasks[i].done()) { - return false; - } - } - return true; - } - protected static String doneDump(JOGLTask[] tasks) { - StringBuilder sb = new StringBuilder(); - sb.append("["); - for(int i=0; i0) { - sb.append(", "); - } - sb.append(i).append(": ").append(tasks[i].done()); - } - sb.append("]"); - return sb.toString(); - } - - protected static boolean isDead(Thread[] threads) { - for(int i=threads.length-1; i>=0; i--) { - if(threads[i].isAlive()) { - return false; - } - } - return true; - } - protected static String isAliveDump(Thread[] threads) { - StringBuilder sb = new StringBuilder(); - sb.append("["); - for(int i=0; i0) { - sb.append(", "); - } - sb.append(i).append(": ").append(threads[i].isAlive()); - } - sb.append("]"); - return sb.toString(); - } - - protected void runJOGLTasks(int num) throws InterruptedException { - final String currentThreadName = Thread.currentThread().getName(); - final Object sync = new Object(); - final JOGLTask[] tasks = new JOGLTask[num]; - final Thread[] threads = new Thread[num]; - int i; - for(i=0; i Date: Tue, 2 Oct 2012 07:28:00 +0200 Subject: Relax Bug 613 workaround of commit 92398025abdabb2fdef0d78edd41e730991a6f94 Utilizing a GlobalToolkitLock in general to lock the display connection results in deadlock situations where locked surfaces signal other [offscreen] surfaces to render. We have to see whether we find a better solution, for now sporadic XCB assertion still happen. But it is preferrable to point to the root cause, then to jumping through hoops to complicate locking or even to deadlock. Locking: - X11GLXGraphicsConfigurationFactory add missing device locking in: - getAvailableCapabilities - chooseGraphicsConfigurationStatic - Newt/X11Window: Discard display events after window close. Relax ATI XCB/threading bug workaround: - ToolkitProperties: requiresGlobalToolkitLock() -> hasThreadingIssues() - NativeWindowFactory: Don't use GlobalToolkitLock in case of 'threadingIssues' the impact is too severe (see above) - NativeWindowFactory: Add getGlobalToolkitLockIfRequired(): To be used for small code blocks. If having 'threadingIssues' a GlobalToolkitLock is returned, otherwise NullToolkitLock. - X11GLXContext: [create/destroy]ContextARBImpl: Use 'NativeWindowFactory.getGlobalToolkitLockIfRequired()' for extra locking Misc Cleanup: - *DrawableFactory createMutableSurface: Also create new device if type is not suitable - *DrawableFactory createDummySurfaceImpl: Pass chosenCaps and use it (preserves orig. requested user caps) --- .../jogamp/opengl/GLDrawableFactoryImpl.java | 9 ++--- .../jogamp/opengl/egl/EGLDrawableFactory.java | 8 ++--- .../macosx/cgl/MacOSXCGLDrawableFactory.java | 9 ++--- .../windows/wgl/WindowsWGLDrawableFactory.java | 13 +++---- .../jogamp/opengl/x11/glx/X11GLXContext.java | 24 +++++++++---- .../opengl/x11/glx/X11GLXDrawableFactory.java | 22 ++++++------ .../glx/X11GLXGraphicsConfigurationFactory.java | 41 ++++++++++++++-------- .../com/jogamp/nativewindow/swt/SWTAccessor.java | 2 +- .../media/nativewindow/NativeWindowFactory.java | 40 ++++++++------------- .../jogamp/nativewindow/GlobalToolkitLock.java | 13 ++++--- .../nativewindow/NativeWindowFactoryImpl.java | 5 --- .../jogamp/nativewindow/ToolkitProperties.java | 8 ++--- .../classes/jogamp/nativewindow/jawt/JAWTUtil.java | 3 -- .../jogamp/nativewindow/macosx/OSXUtil.java | 2 +- .../jogamp/nativewindow/windows/GDIUtil.java | 2 +- .../classes/jogamp/nativewindow/x11/X11Util.java | 10 +++--- .../jogamp/newt/driver/x11/DisplayDriver.java | 2 +- .../jogamp/newt/driver/x11/WindowDriver.java | 2 +- src/newt/native/X11Display.c | 4 +-- src/newt/native/X11Window.c | 2 +- 20 files changed, 113 insertions(+), 108 deletions(-) (limited to 'src/newt/native/X11Window.c') diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java index bd2db1b81..0ea565b89 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java @@ -188,7 +188,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { } if( chosenCaps.isFBO() && isFBOAvailable ) { // need to hook-up a native dummy surface since source may not have - final ProxySurface dummySurface = createDummySurfaceImpl(adevice, true, chosenCaps, null, 64, 64); + final ProxySurface dummySurface = createDummySurfaceImpl(adevice, false, chosenCaps, (GLCapabilitiesImmutable)config.getRequestedCapabilities(), null, 64, 64); dummySurface.setUpstreamSurfaceHook(new DelegatedUpstreamSurfaceHookWithSurfaceSize(dummySurface.getUpstreamSurfaceHook(), target)); result = createFBODrawableImpl(dummySurface, chosenCaps, 0); } else { @@ -299,7 +299,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { if( capsChosen.isFBO() ) { device.lock(); try { - final ProxySurface dummySurface = createDummySurfaceImpl(device, true, capsRequested, null, width, height); + final ProxySurface dummySurface = createDummySurfaceImpl(device, true, capsChosen, capsRequested, null, width, height); final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(dummySurface); return new GLFBODrawableImpl.ResizeableImpl(this, dummyDrawable, dummySurface, capsChosen, 0); } finally { @@ -370,7 +370,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { } device.lock(); try { - return createDummySurfaceImpl(device, true, requestedCaps, chooser, width, height); + return createDummySurfaceImpl(device, true, requestedCaps, requestedCaps, chooser, width, height); } finally { device.unlock(); } @@ -386,6 +386,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { * @param device a valid platform dependent target device. * @param createNewDevice if true a new device instance is created using device details, * otherwise device instance is used as-is. + * @param chosenCaps * @param requestedCaps * @param chooser the custom chooser, may be null for default * @param width the initial width as returned by {@link NativeSurface#getWidth()}, not the actual dummy surface width. @@ -395,7 +396,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { * @return the created {@link ProxySurface} instance w/o defined surface handle but platform specific {@link UpstreamSurfaceHook}. */ public abstract ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice, - GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height); + GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height); //--------------------------------------------------------------------------- // diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java index a907c4aff..da3907193 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java @@ -367,7 +367,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { if( hasPBuffer[0] ) { // 2nd case create defaultDevice shared resource using pbuffer surface - surface = createDummySurfaceImpl(eglDevice, false, reqCapsPBuffer, null, 64, 64); // egl pbuffer offscreen + surface = createDummySurfaceImpl(eglDevice, false, reqCapsPBuffer, reqCapsPBuffer, null, 64, 64); // egl pbuffer offscreen upstreamSurface = (ProxySurface)surface; upstreamSurface.createNotify(); deviceFromUpstreamSurface = false; @@ -664,7 +664,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) { final boolean ownDevice; final EGLGraphicsDevice device; - if(createNewDevice || ! ( deviceReq instanceof EGLGraphicsDevice ) ) { + if( createNewDevice || ! (deviceReq instanceof EGLGraphicsDevice) ) { final long nativeDisplayID = ( deviceReq instanceof EGLGraphicsDevice) ? ( (EGLGraphicsDevice) deviceReq ).getNativeDisplayID() : deviceReq.getHandle() ; device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(nativeDisplayID, deviceReq.getConnection(), deviceReq.getUnitID()); @@ -683,8 +683,8 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { @Override public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, - GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { - final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOffscreenBitOnly(requestedCaps); // complete validation in EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(..) above + GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { + chosenCaps = GLGraphicsConfigurationUtil.fixOffscreenBitOnly(chosenCaps); // complete validation in EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(..) above return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new EGLDummyUpstreamSurfaceHook(width, height)); } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java index d59197e1d..ec3156f52 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -226,7 +226,8 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { if (null == glp) { throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); } - final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64)); + final GLCapabilitiesImmutable caps = new GLCapabilities(glp); + final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, caps, caps, null, 64, 64)); sharedDrawable.setRealized(true); final MacOSXCGLContext sharedContext = (MacOSXCGLContext) sharedDrawable.createContext(null); @@ -358,7 +359,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) { final MacOSXGraphicsDevice device; - if(createNewDevice) { + if( createNewDevice || !(deviceReq instanceof MacOSXGraphicsDevice) ) { device = new MacOSXGraphicsDevice(deviceReq.getUnitID()); } else { device = (MacOSXGraphicsDevice)deviceReq; @@ -373,8 +374,8 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { @Override public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, - GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { - final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps); + GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { + chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps); return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new OSXDummyUpstreamSurfaceHook(width, height)); } diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java index 91d5c225a..c6bc61a27 100644 --- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java @@ -318,7 +318,8 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { if (null == glp) { throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); } - final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64)); + final GLCapabilitiesImmutable caps = new GLCapabilities(glp); + final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, caps, caps, null, 64, 64)); sharedDrawable.setRealized(true); final GLContextImpl sharedContext = (GLContextImpl) sharedDrawable.createContext(null); @@ -543,7 +544,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) { final WindowsGraphicsDevice device; - if(createNewDevice) { + if(createNewDevice || !(deviceReq instanceof WindowsGraphicsDevice)) { device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID()); } else { device = (WindowsGraphicsDevice)deviceReq; @@ -558,18 +559,18 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { @Override public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, - GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { + GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { final WindowsGraphicsDevice device; - if(createNewDevice) { + if( createNewDevice || !(deviceReq instanceof WindowsGraphicsDevice) ) { device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID()); } else { device = (WindowsGraphicsDevice)deviceReq; } final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0); - final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps); + chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps); final WindowsWGLGraphicsConfiguration config = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(chosenCaps, requestedCaps, chooser, screen); if(null == config) { - throw new GLException("Choosing GraphicsConfiguration failed w/ "+requestedCaps+" on "+screen); + throw new GLException("Choosing GraphicsConfiguration failed w/ "+chosenCaps+" on "+screen); } return new GDISurface(config, 0, new GDIDummyUpstreamSurfaceHook(width, height), createNewDevice); } diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java index 72ddd2693..f7389d42e 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java @@ -48,6 +48,8 @@ import java.util.Map; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.NativeWindowFactory; +import javax.media.nativewindow.ToolkitLock; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; import javax.media.opengl.GLException; @@ -180,11 +182,16 @@ public abstract class X11GLXContext extends GLContextImpl { @Override protected void destroyContextARBImpl(long ctx) { - X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration(); - long display = config.getScreen().getDevice().getHandle(); - - glXMakeContextCurrent(display, 0, 0, 0); - GLX.glXDestroyContext(display, ctx); + final ToolkitLock tkLock = NativeWindowFactory.getGlobalToolkitLockIfRequired(); + tkLock.lock(); + try { + long display = drawable.getNativeSurface().getDisplayHandle(); + + glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, ctx); + } finally { + tkLock.unlock(); + } } private static final int ctx_arb_attribs_idx_major = 0; private static final int ctx_arb_attribs_idx_minor = 2; @@ -243,6 +250,8 @@ public abstract class X11GLXContext extends GLContextImpl { AbstractGraphicsDevice device = config.getScreen().getDevice(); final long display = device.getHandle(); + final ToolkitLock tkLock = NativeWindowFactory.getGlobalToolkitLockIfRequired(); + tkLock.lock(); try { // critical path, a remote display might not support this command, // hence we need to catch the X11 Error within this block. @@ -253,7 +262,10 @@ public abstract class X11GLXContext extends GLContextImpl { Throwable t = new Throwable(getThreadName()+": Info: X11GLXContext.createContextARBImpl glXCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re); t.printStackTrace(); } + } finally { + tkLock.unlock(); } + if(0!=ctx) { if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), ctx)) { if(DEBUG) { @@ -420,7 +432,7 @@ public abstract class X11GLXContext extends GLContextImpl { @Override protected void destroyImpl() throws GLException { - GLX.glXDestroyContext(drawable.getNativeSurface().getDisplayHandle(), contextHandle); + destroyContextARBImpl(contextHandle); } @Override diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java index 018f6a6ea..e38aabef8 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java @@ -229,7 +229,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { @Override public SharedResourceRunner.Resource createSharedResource(String connection) { - final X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT, true); + final X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */); sharedDevice.lock(); try { final X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, sharedDevice.getDefaultScreen()); @@ -246,8 +246,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { if (null == glp) { throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); } - - final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64)); + + final GLCapabilitiesImmutable caps = new GLCapabilities(glp); + final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, caps, caps, null, 64, 64)); sharedDrawable.setRealized(true); final GLContextImpl sharedContext = (GLContextImpl) sharedDrawable.createContext(null); @@ -499,11 +500,10 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) { final X11GraphicsDevice device; - if(createNewDevice) { - // Null X11 resource locking, due to private non-shared Display handle - device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true); + if( createNewDevice || !(deviceReq instanceof X11GraphicsDevice) ) { + device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true /* owner */); } else { - device = (X11GraphicsDevice)deviceReq; + device = (X11GraphicsDevice) deviceReq; } final X11GraphicsScreen screen = new X11GraphicsScreen(device, device.getDefaultScreen()); final X11GLXGraphicsConfiguration config = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED); @@ -512,17 +512,17 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } return new WrappedSurface(config, 0, upstreamHook, createNewDevice); } - + @Override public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice, - GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { - final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps); + GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) { + chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps); return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new X11DummyUpstreamSurfaceHook(width, height)); } @Override protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) { - final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true); + final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), true /* owner */); final X11GraphicsScreen screen = new X11GraphicsScreen(device, screenIdx); final int xvisualID = X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle); if(VisualIDHolder.VID_UNDEFINED == xvisualID) { diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java index ef2d3283d..8ac324205 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java @@ -127,16 +127,22 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF throw new GLException("Shared resource for device n/a: "+device); } final X11GraphicsScreen sharedScreen = (X11GraphicsScreen) sharedResource.getScreen(); - final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(sharedScreen.getDevice()); + final X11GraphicsDevice sharedDevice = (X11GraphicsDevice) sharedScreen.getDevice(); + final boolean isMultisampleAvailable = sharedResource.isGLXMultisampleAvailable(); final GLProfile glp = GLProfile.getDefault(device); List availableCaps = null; - - if( sharedResource.isGLXVersionGreaterEqualOneThree() ) { - availableCaps = getAvailableGLCapabilitiesFBConfig(sharedScreen, glp, isMultisampleAvailable); - } - if( null == availableCaps || availableCaps.isEmpty() ) { - availableCaps = getAvailableGLCapabilitiesXVisual(sharedScreen, glp, isMultisampleAvailable); + + sharedDevice.lock(); + try { + if( sharedResource.isGLXVersionGreaterEqualOneThree() ) { + availableCaps = getAvailableGLCapabilitiesFBConfig(sharedScreen, glp, isMultisampleAvailable); + } + if( null == availableCaps || availableCaps.isEmpty() ) { + availableCaps = getAvailableGLCapabilitiesXVisual(sharedScreen, glp, isMultisampleAvailable); + } + } finally { + sharedDevice.unlock(); } if( null != availableCaps && availableCaps.size() > 1 ) { Collections.sort(availableCaps, XVisualIDComparator); @@ -215,16 +221,21 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory, x11Device); final boolean usePBuffer = !capsChosen.isOnscreen() && capsChosen.isPBuffer(); - + X11GLXGraphicsConfiguration res = null; - if( factory.isGLXVersionGreaterEqualOneThree(x11Device) ) { - res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen, xvisualID); - } - if(null==res) { - if(usePBuffer) { - throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for visualID "+toHexString(xvisualID)+", "+capsChosen); + x11Device.lock(); + try { + if( factory.isGLXVersionGreaterEqualOneThree(x11Device) ) { + res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen, xvisualID); + } + if(null==res) { + if(usePBuffer) { + throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for visualID "+toHexString(xvisualID)+", "+capsChosen); + } + res = chooseGraphicsConfigurationXVisual(capsChosen, capsReq, chooser, x11Screen, xvisualID); } - res = chooseGraphicsConfigurationXVisual(capsChosen, capsReq, chooser, x11Screen, xvisualID); + } finally { + x11Device.unlock(); } if(null==res) { throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig and XVisual for visualID "+toHexString(xvisualID)+", "+x11Screen+", "+capsChosen); diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java index 1cc796086..7be747ff5 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java @@ -210,7 +210,7 @@ public class SWTAccessor { if( null != OS_gtk_class ) { long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle); long displayHandle = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, widgedHandle); - return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, false); + return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, false /* owner */); } final String nwt = NativeWindowFactory.getNativeWindowType(false); if( NativeWindowFactory.TYPE_WINDOWS == nwt ) { diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index 1962bcd09..006ee4c97 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -42,6 +42,7 @@ import java.util.HashMap; import java.util.Map; import jogamp.nativewindow.Debug; +import jogamp.nativewindow.GlobalToolkitLock; import jogamp.nativewindow.NativeWindowFactoryImpl; import jogamp.nativewindow.ToolkitProperties; import jogamp.nativewindow.ResourceToolkitLock; @@ -102,7 +103,7 @@ public abstract class NativeWindowFactory { private static ToolkitLock jawtUtilJAWTToolkitLock; private static boolean requiresToolkitLock; - private static boolean requiresGlobalToolkitLock; + private static boolean desktopHasThreadingIssues; private static volatile boolean isJVMShuttingDown = false; @@ -183,15 +184,11 @@ public abstract class NativeWindowFactory { final Boolean res1 = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "requiresToolkitLock", null, null, cl); requiresToolkitLock = res1.booleanValue(); - if(requiresToolkitLock) { - final Boolean res2 = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "requiresGlobalToolkitLock", null, null, cl); - requiresGlobalToolkitLock = res2.booleanValue(); - } else { - requiresGlobalToolkitLock = false; - } + final Boolean res2 = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "hasThreadingIssues", null, null, cl); + desktopHasThreadingIssues = res2.booleanValue(); } else { requiresToolkitLock = false; - requiresGlobalToolkitLock = false; + desktopHasThreadingIssues = false; } } @@ -293,7 +290,7 @@ public abstract class NativeWindowFactory { } if(DEBUG) { - System.err.println("NativeWindowFactory requiresToolkitLock "+requiresToolkitLock+", requiresGlobalToolkitLock "+requiresGlobalToolkitLock); + System.err.println("NativeWindowFactory requiresToolkitLock "+requiresToolkitLock+", desktopHasThreadingIssues "+desktopHasThreadingIssues); System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+", defaultFactory "+factory); } @@ -329,11 +326,6 @@ public abstract class NativeWindowFactory { return requiresToolkitLock; } - /** @return true if the underlying toolkit requires global locking, otherwise false. */ - public static boolean requiresGlobalToolkitLock() { - return requiresGlobalToolkitLock; - } - /** @return true if not headless, AWT Component and NativeWindow's AWT part available */ public static boolean isAWTAvailable() { return isAWTAvailable; } @@ -382,11 +374,15 @@ public abstract class NativeWindowFactory { public static ToolkitLock getNullToolkitLock() { return NativeWindowFactoryImpl.getNullToolkitLock(); } - - public static ToolkitLock getGlobalToolkitLock() { - return NativeWindowFactoryImpl.getGlobalToolkitLock(); - } + /** + * Ony call this for small code segments for desktop w/ threading issues. + * @return {@link GlobalToolkitLock} if desktop has threading issues, otherwise {@link #getNullToolkitLock()} + */ + public static ToolkitLock getGlobalToolkitLockIfRequired() { + return desktopHasThreadingIssues ? GlobalToolkitLock.getSingleton() : getNullToolkitLock(); + } + /** * Provides the system default {@link ToolkitLock} for the default system windowing type. * @see #getNativeWindowType(boolean) @@ -400,7 +396,6 @@ public abstract class NativeWindowFactory { * Provides the default {@link ToolkitLock} for type. *
    *
  • JAWT {@link ToolkitLock} if required and type is of {@link #TYPE_AWT} and AWT available,
  • - *
  • {@link jogamp.nativewindow.GlobalToolkitLock} if required, otherwise
  • *
  • {@link jogamp.nativewindow.ResourceToolkitLock} if required, otherwise
  • *
  • {@link jogamp.nativewindow.NullToolkitLock}
  • *
@@ -410,9 +405,6 @@ public abstract class NativeWindowFactory { if( TYPE_AWT == type && isAWTAvailable() ) { return getAWTToolkitLock(); } - if( requiresGlobalToolkitLock ) { - return NativeWindowFactoryImpl.getGlobalToolkitLock(); - } return ResourceToolkitLock.create(); } return NativeWindowFactoryImpl.getNullToolkitLock(); @@ -422,7 +414,6 @@ public abstract class NativeWindowFactory { * Provides the default {@link ToolkitLock} for type and deviceHandle. *
    *
  • JAWT {@link ToolkitLock} if required and type is of {@link #TYPE_AWT} and AWT available,
  • - *
  • {@link jogamp.nativewindow.GlobalToolkitLock} if required, otherwise
  • *
  • {@link jogamp.nativewindow.ResourceToolkitLock} if required, otherwise
  • *
  • {@link jogamp.nativewindow.NullToolkitLock}
  • *
@@ -432,9 +423,6 @@ public abstract class NativeWindowFactory { if( TYPE_AWT == type && isAWTAvailable() ) { return getAWTToolkitLock(); } - if( requiresGlobalToolkitLock ) { - return NativeWindowFactoryImpl.getGlobalToolkitLock(); - } return ResourceToolkitLock.create(); } return NativeWindowFactoryImpl.getNullToolkitLock(); diff --git a/src/nativewindow/classes/jogamp/nativewindow/GlobalToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/GlobalToolkitLock.java index 0c2a1e43f..c9f830811 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/GlobalToolkitLock.java +++ b/src/nativewindow/classes/jogamp/nativewindow/GlobalToolkitLock.java @@ -36,16 +36,19 @@ import com.jogamp.common.util.locks.RecursiveLock; /** * Implementing a global recursive {@link javax.media.nativewindow.ToolkitLock}. *

- * This is the last resort for unstable driver, e.g. proprietary ATI/X11 12.8 and 12.9, - * where multiple X11 display connections to the same connection name are not treated - * thread safe within the GL/X11 driver. + * This is the last resort for unstable driver where multiple X11 display connections + * to the same connection name are not treated thread safe within the GL/X11 driver. *

*/ public class GlobalToolkitLock implements ToolkitLock { private static final RecursiveLock globalLock = LockFactory.createRecursiveLock(); + private static GlobalToolkitLock singleton = new GlobalToolkitLock(); - /** Singleton via {@link NativeWindowFactoryImpl#getGlobalToolkitLock()} */ - protected GlobalToolkitLock() { } + public static final GlobalToolkitLock getSingleton() { + return singleton; + } + + private GlobalToolkitLock() { } @Override public final void lock() { diff --git a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java index c35cede77..a3a66b7f1 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java +++ b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java @@ -44,16 +44,11 @@ import com.jogamp.common.util.ReflectionUtil.AWTNames; public class NativeWindowFactoryImpl extends NativeWindowFactory { private static final ToolkitLock nullToolkitLock = new NullToolkitLock(); - private static final ToolkitLock globalToolkitLock = new GlobalToolkitLock(); public static ToolkitLock getNullToolkitLock() { return nullToolkitLock; } - public static ToolkitLock getGlobalToolkitLock() { - return globalToolkitLock; - } - // This subclass of NativeWindowFactory handles the case of // NativeWindows being passed in protected NativeWindow getNativeWindowImpl(Object winObj, AbstractGraphicsConfiguration config) throws IllegalArgumentException { diff --git a/src/nativewindow/classes/jogamp/nativewindow/ToolkitProperties.java b/src/nativewindow/classes/jogamp/nativewindow/ToolkitProperties.java index 2062d1f58..ed23def8f 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/ToolkitProperties.java +++ b/src/nativewindow/classes/jogamp/nativewindow/ToolkitProperties.java @@ -13,15 +13,11 @@ import javax.media.nativewindow.NativeWindowFactory; public static boolean requiresToolkitLock() {} - public static boolean requiresGlobalToolkitLock() {} + public static boolean hasThreadingIssues() {} * * Above static methods are invoked by {@link NativeWindowFactory#initSingleton()}, * or {@link NativeWindowFactory#shutdown()} via reflection. *

- *

- * If requiresGlobalToolkitLock() == true, then - * requiresToolkitLock() == true shall be valid as well. - *

*/ public interface ToolkitProperties { @@ -46,6 +42,6 @@ public interface ToolkitProperties { /** * Called by {@link NativeWindowFactory#initSingleton()} */ - // boolean requiresGlobalToolkitLock(); + // boolean hasThreadingIssues(); } diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java index 67c64a95c..349da8ee6 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java @@ -237,18 +237,15 @@ public class JAWTUtil { jawtToolkitLock = new ToolkitLock() { public final void lock() { - NativeWindowFactory.getGlobalToolkitLock().lock(); JAWTUtil.lockToolkit(); if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.lock()"); } } public final void unlock() { if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.unlock()"); } JAWTUtil.unlockToolkit(); - NativeWindowFactory.getGlobalToolkitLock().unlock(); } @Override public final void validateLocked() throws RuntimeException { - NativeWindowFactory.getGlobalToolkitLock().validateLocked(); JAWTUtil.validateLocked(); } public final void dispose() { diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java index 481cbbe39..a195f137e 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java @@ -76,7 +76,7 @@ public class OSXUtil implements ToolkitProperties { * Called by {@link NativeWindowFactory#initSingleton()} * @see ToolkitProperties */ - public static final boolean requiresGlobalToolkitLock() { return false; } + public static final boolean hasThreadingIssues() { return false; } public static boolean isNSView(long object) { return isNSView0(object); diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java index 4408a0903..2f4e18359 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java @@ -84,7 +84,7 @@ public class GDIUtil implements ToolkitProperties { * Called by {@link NativeWindowFactory#initSingleton()} * @see ToolkitProperties */ - public static final boolean requiresGlobalToolkitLock() { return false; } + public static final boolean hasThreadingIssues() { return false; } private static RegisteredClass dummyWindowClass = null; private static Object dummyWindowSync = new Object(); diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java index 103995a8d..c771cd67a 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java @@ -95,7 +95,7 @@ public class X11Util implements ToolkitProperties { private static String nullDisplayName = null; private static volatile boolean isInit = false; private static boolean markAllDisplaysUnclosable = false; // ATI/AMD X11 driver issues - private static boolean requiresGlobalToolkitLock = false; // ATI/AMD X11 driver issues + private static boolean hasThreadingIssues = false; // ATI/AMD X11 driver issues private static Object setX11ErrorHandlerLock = new Object(); private static final String X11_EXTENSION_ATIFGLRXDRI = "ATIFGLRXDRI"; @@ -137,7 +137,7 @@ public class X11Util implements ToolkitProperties { hasX11_EXTENSION_ATIFGLRXDRI = false; hasX11_EXTENSION_ATIFGLEXTENSION = false; } - requiresGlobalToolkitLock = ATI_HAS_MULTITHREADING_BUG && ( hasX11_EXTENSION_ATIFGLRXDRI || hasX11_EXTENSION_ATIFGLEXTENSION ); + hasThreadingIssues = ATI_HAS_MULTITHREADING_BUG && ( hasX11_EXTENSION_ATIFGLRXDRI || hasX11_EXTENSION_ATIFGLEXTENSION ); markAllDisplaysUnclosable = ATI_HAS_XCLOSEDISPLAY_BUG && ( hasX11_EXTENSION_ATIFGLRXDRI || hasX11_EXTENSION_ATIFGLEXTENSION ); if(DEBUG) { @@ -147,7 +147,7 @@ public class X11Util implements ToolkitProperties { ",\n\t X11_EXTENSION_ATIFGLRXDRI " + hasX11_EXTENSION_ATIFGLRXDRI+ ",\n\t X11_EXTENSION_ATIFGLEXTENSION " + hasX11_EXTENSION_ATIFGLEXTENSION+ ",\n\t requiresToolkitLock "+requiresToolkitLock()+ - ",\n\t requiresGlobalToolkitLock "+requiresGlobalToolkitLock()+ + ",\n\t hasThreadingIssues "+hasThreadingIssues()+ ",\n\t markAllDisplaysUnclosable "+getMarkAllDisplaysUnclosable() ); // Thread.dumpStack(); @@ -228,8 +228,8 @@ public class X11Util implements ToolkitProperties { * Called by {@link NativeWindowFactory#initSingleton()} * @see ToolkitProperties */ - public static final boolean requiresGlobalToolkitLock() { - return requiresGlobalToolkitLock; // JAWT locking: yes, instead of native X11 locking w use a global lock. + public static final boolean hasThreadingIssues() { + return hasThreadingIssues; // JOGL impl. may utilize special locking "somewhere" } public static void setX11ErrorHandler(boolean onoff, boolean quiet) { diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java index 6e80e966a..a3230fa62 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java @@ -80,7 +80,7 @@ public class DisplayDriver extends DisplayImpl { if( 0 == handle ) { throw new RuntimeException("Error creating display(Win): "+name); } - aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, true); + aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */); try { CompleteDisplay0(aDevice.getHandle()); } catch(RuntimeException e) { diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java index bde723634..92f174e39 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java @@ -73,7 +73,7 @@ public class WindowDriver extends WindowImpl { if( 0 == renderDeviceHandle ) { throw new RuntimeException("Error creating display(EDT): "+edtDevice.getConnection()); } - renderDevice = new X11GraphicsDevice(renderDeviceHandle, AbstractGraphicsDevice.DEFAULT_UNIT, true); + renderDevice = new X11GraphicsDevice(renderDeviceHandle, AbstractGraphicsDevice.DEFAULT_UNIT, true /* owner */); final AbstractGraphicsScreen renderScreen = new X11GraphicsScreen(renderDevice, screen.getIndex()); final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice(), capsRequested); diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c index 56c11fab4..69a115ab1 100644 --- a/src/newt/native/X11Display.c +++ b/src/newt/native/X11Display.c @@ -329,10 +329,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage char text[255]; // XEventsQueued(dpy, X): - // QueuedAlready : No I/O Flush or system call doesn't work on some cards (eg ATI) ?) + // QueuedAlready == XQLength(): No I/O Flush or system call doesn't work on some cards (eg ATI) ?) // QueuedAfterFlush == XPending(): I/O Flush only if no already queued events are available // QueuedAfterReading : QueuedAlready + if queue==0, attempt to read more .. - if ( 0 >= XPending(dpy) ) { + if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) ) { // DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy); return; } diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 2e16e7cae..202ad6fff 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -701,7 +701,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0 Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom); XDestroyWindow(dpy, w); - XSync(dpy, False); + XSync(dpy, True); // discard all events now, no more handler (*env)->DeleteGlobalRef(env, jwindow); -- cgit v1.2.3 From ed596d9a329f1788979e148a4d09df7815ada527 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Mon, 8 Apr 2013 02:47:23 +0200 Subject: Bug 641 NEWT: X11 Deliver keyCode layout independent, keySym layout dependent and UTF-16 keyChar value On X11, the layout dependent keySym was not delivered [1], as well as the UTF-8 to UTF-16 translation was missing [2]. [1] is solved using XLookupString w/o ShiftMask [2] is solved using JNI's NewStringUTF, which takes UTF-8. --- make/scripts/tests.sh | 6 +- .../jogamp/newt/driver/x11/DisplayDriver.java | 16 +++-- .../jogamp/newt/driver/x11/WindowDriver.java | 16 +++-- src/newt/native/X11Display.c | 74 +++++++++++++++++----- src/newt/native/X11Window.c | 4 +- 5 files changed, 83 insertions(+), 33 deletions(-) (limited to 'src/newt/native/X11Window.c') diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index cb8abc8bf..eee4edec0 100755 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -170,7 +170,7 @@ function jrun() { #D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT -Djogl.debug.GLContext" #D_ARGS="-Dnewt.debug.Window -Djogl.debug.Animator -Dnewt.debug.Screen" #D_ARGS="-Dnativewindow.debug.JAWT -Dnewt.debug.Window" - #D_ARGS="-Dnewt.debug.Window.KeyEvent" + D_ARGS="-Dnewt.debug.Window.KeyEvent" #D_ARGS="-Dnewt.debug.Window.MouseEvent" #D_ARGS="-Dnewt.debug.Window.MouseEvent -Dnewt.debug.Window.KeyEvent" #D_ARGS="-Dnewt.debug.Window -Dnativewindow.debug=all" @@ -276,7 +276,7 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestRedSquareES1NEWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT $* -#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* +testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* #testawtswt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasSWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple $* @@ -291,7 +291,7 @@ function testawtswt() { #testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWTBug450 $* #testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT $* -testnoawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestTeapotNEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestTeapotNEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.gl3.newt.TestGeomShader01TextureGL3NEWT $* # diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java index f3a548a08..4fe025ec4 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java @@ -91,9 +91,10 @@ public class DisplayDriver extends DisplayImpl { @Override protected void closeNativeImpl() { - DisplayRelease0(aDevice.getHandle(), javaObjectAtom, windowDeleteAtom); + DisplayRelease0(aDevice.getHandle(), javaObjectAtom, windowDeleteAtom /*, kbdHandle */); // XKB disabled for now javaObjectAtom = 0; windowDeleteAtom = 0; + // kbdHandle = 0; aDevice.close(); // closes X11 display } @@ -103,7 +104,7 @@ public class DisplayDriver extends DisplayImpl { try { final long handle = aDevice.getHandle(); if(0 != handle) { - DispatchMessages0(handle, javaObjectAtom, windowDeleteAtom); + DispatchMessages0(handle, javaObjectAtom, windowDeleteAtom /*, kbdHandle */); // XKB disabled for now } } finally { if(null != aDevice) { // could be pulled by destroy event @@ -114,6 +115,7 @@ public class DisplayDriver extends DisplayImpl { protected long getJavaObjectAtom() { return javaObjectAtom; } protected long getWindowDeleteAtom() { return windowDeleteAtom; } + // protected long getKbdHandle() { return kbdHandle; } // XKB disabled for now /** Returns null if !{@link #isNativeValid()}, otherwise the Boolean value of {@link X11GraphicsDevice#isXineramaEnabled()}. */ protected Boolean isXineramaEnabled() { return isNativeValid() ? Boolean.valueOf(((X11GraphicsDevice)aDevice).isXineramaEnabled()) : null; } @@ -126,18 +128,22 @@ public class DisplayDriver extends DisplayImpl { private native void CompleteDisplay0(long handle); - private void displayCompleted(long javaObjectAtom, long windowDeleteAtom) { + private void displayCompleted(long javaObjectAtom, long windowDeleteAtom /*, long kbdHandle */) { this.javaObjectAtom=javaObjectAtom; this.windowDeleteAtom=windowDeleteAtom; + // this.kbdHandle = kbdHandle; // XKB disabled for now } - private native void DisplayRelease0(long handle, long javaObjectAtom, long windowDeleteAtom); + private native void DisplayRelease0(long handle, long javaObjectAtom, long windowDeleteAtom /*, long kbdHandle */); // XKB disabled for now - private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom); + private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom /* , long kbdHandle */); // XKB disabled for now /** X11 Window delete atom marker used on EDT */ private long windowDeleteAtom; /** X11 Window java object property used on EDT */ private long javaObjectAtom; + + /** X11 Keyboard handle used on EDT */ + // private long kbdHandle; // XKB disabled for now } diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java index 8d33d4d73..666d0cb5b 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java @@ -116,7 +116,7 @@ public class WindowDriver extends WindowImpl { edtDevice.lock(); try { CloseWindow0(edtDevice.getHandle(), windowHandleClose, - display.getJavaObjectAtom(), display.getWindowDeleteAtom()); + display.getJavaObjectAtom(), display.getWindowDeleteAtom() /* , display.getKbdHandle() */); // XKB disabled for now } catch (Throwable t) { if(DEBUG_IMPLEMENTATION) { Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t); @@ -271,13 +271,13 @@ public class WindowDriver extends WindowImpl { super.doMouseEvent(enqueue, wait, eventType, modifiers, x, y, button, rotation); } - @Override - public final void sendKeyEvent(short eventType, int modifiers, short keyCode, short keySym, char keyChar) { + protected final void sendKeyEvent(short eventType, int modifiers, short keyCode, short keySym, char keyChar0, String keyString) { // handleKeyEvent(true, false, eventType, modifiers, keyCode, keyChar); final boolean isModifierKey = KeyEvent.isModifierKey(keyCode); final boolean isAutoRepeat = 0 != ( KeyEvent.AUTOREPEAT_MASK & modifiers ); - // System.err.println("*** sendKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", keyCode "+toHexString(keyCode)+", keyChar <"+keyChar+">, mods "+toHexString(modifiers)+ - // ", isKeyCodeTracked "+isKeyCodeTracked(keyCode)+", was: pressed "+isKeyPressed(keyCode)+", repeat "+isAutoRepeat+", [modifierKey "+isModifierKey+"] - "+System.currentTimeMillis()); + final char keyChar = ( null != keyString ) ? keyString.charAt(0) : keyChar0; + // System.err.println("*** sendKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", keyCode "+toHexString(keyCode)+", keyChar <"+keyChar0+">/<"+keyChar+">, keyString "+keyString+", mods "+toHexString(modifiers)+ + // ", isKeyCodeTracked "+isKeyCodeTracked(keyCode)+", was: pressed "+isKeyPressed(keyCode)+", repeat "+isAutoRepeat+", [modifierKey "+isModifierKey+"] - "+System.currentTimeMillis()); if( !isAutoRepeat || !isModifierKey ) { // ! ( isModifierKey && isAutoRepeat ) switch(eventType) { @@ -295,6 +295,10 @@ public class WindowDriver extends WindowImpl { } } + @Override + public final void sendKeyEvent(short eventType, int modifiers, short keyCode, short keySym, char keyChar) { + throw new InternalError("XXX: Adapt Java Code to Native Code Changes"); + } @Override public final void enqueueKeyEvent(boolean wait, short eventType, int modifiers, short keyCode, short keySym, char keyChar) { throw new InternalError("XXX: Adapt Java Code to Native Code Changes"); @@ -315,7 +319,7 @@ public class WindowDriver extends WindowImpl { private native long CreateWindow0(long parentWindowHandle, long display, int screen_index, int visualID, long javaObjectAtom, long windowDeleteAtom, int x, int y, int width, int height, boolean autoPosition, int flags); - private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom); + private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom /*, long kbdHandle*/ ); // XKB disabled for now private native void reconfigureWindow0(long display, int screen_index, long parentWindowHandle, long windowHandle, long windowDeleteAtom, int x, int y, int width, int height, int flags); private native void requestFocus0(long display, long windowHandle, boolean force); diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c index d927b8069..a2df0d2e2 100644 --- a/src/newt/native/X11Display.c +++ b/src/newt/native/X11Display.c @@ -28,6 +28,8 @@ #include "X11Common.h" +// #include // XKB disabled for now + jclass X11NewtWindowClazz = NULL; jmethodID insetsChangedID = NULL; jmethodID visibleChangedID = NULL; @@ -223,6 +225,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0 } } + // displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJJ)V"); // Variant using XKB displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJ)V"); getCurrentThreadNameID = (*env)->GetStaticMethodID(env, X11NewtWindowClazz, "getCurrentThreadName", "()Ljava/lang/String;"); dumpStackID = (*env)->GetStaticMethodID(env, X11NewtWindowClazz, "dumpStack", "()V"); @@ -235,7 +238,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0 windowDestroyNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowDestroyNotify", "(Z)Z"); windowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowRepaint", "(ZIIII)V"); sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(SIIISF)V"); - sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(SISSC)V"); + sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(SISSCLjava/lang/String;)V"); requestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "requestFocus", "(Z)V"); if (displayCompletedID == NULL || @@ -270,6 +273,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_CompleteDisplay Display * dpy = (Display *)(intptr_t)display; jlong javaObjectAtom; jlong windowDeleteAtom; + // jlong kbdHandle; // XKB disabled for now if(dpy==NULL) { NewtCommon_FatalError(env, "invalid display connection.."); @@ -288,10 +292,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_CompleteDisplay } // XSetCloseDownMode(dpy, RetainTemporary); // Just a try .. + // kbdHandle = (jlong) (intptr_t) XkbGetKeyboard(dpy, XkbAllComponentsMask, XkbUseCoreKbd); // XKB disabled for now DBG_PRINT("X11: X11Display_completeDisplay dpy %p\n", dpy); - (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom); + (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom /*, kbdHandle*/); // XKB disabled for now } /* @@ -300,11 +305,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_CompleteDisplay * Signature: (JJJ)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DisplayRelease0 - (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom) + (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom /*, jlong kbdHandle*/) { Display * dpy = (Display *)(intptr_t)display; Atom wm_javaobject_atom = (Atom)javaObjectAtom; Atom wm_delete_atom = (Atom)windowDeleteAtom; + // XkbDescPtr kbdDesc = (XkbDescPtr)(intptr_t)kbdHandle; // XKB disabled for now if(dpy==NULL) { NewtCommon_FatalError(env, "invalid display connection.."); @@ -314,6 +320,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DisplayRelease0 (void) wm_javaobject_atom; (void) wm_delete_atom; + // XkbFreeKeyboard(kbdDesc, XkbAllNamesMask, True); // XKB disabled for now + XSync(dpy, True); // discard all pending events DBG_PRINT("X11: X11Display_DisplayRelease dpy %p\n", dpy); } @@ -321,13 +329,14 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DisplayRelease0 /* * Class: jogamp_newt_driver_x11_DisplayDriver * Method: DispatchMessages - * Signature: (JIJJ)V + * Signature: (JJJ)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0 - (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom) + (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom /*, jlong kbdHandle*/) { Display * dpy = (Display *) (intptr_t) display; Atom wm_delete_atom = (Atom)windowDeleteAtom; + // XkbDescPtr kbdDesc = (XkbDescPtr)(intptr_t)kbdHandle; // XKB disabled for now int num_events = 100; int autoRepeatModifiers = 0; @@ -335,6 +344,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage return; } + /** XKB disabled for now + if( NULL == kbdDesc) { + NewtCommon_throwNewRuntimeException(env, "NULL kbd handle, bail out!"); + return; + } */ + // Periodically take a break while( num_events > 0 ) { jobject jwindow = NULL; @@ -344,7 +359,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage jshort javaVKeyUS = 0; jshort javaVKeyNN = 0; jint modifiers = 0; - char keyChar = 0; + uint16_t keyChar = 0; + jstring keyString = NULL; char text[255]; // XEventsQueued(dpy, X): @@ -403,23 +419,43 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage // fall through intended case KeyPress: { KeySym shiftedKeySym; // layout depending keySym w/ SHIFT + KeySym unShiftedKeySym; // layout depending keySym w/o SHIFT + unsigned int xkey_state = evt.xkey.state; keyCode = evt.xkey.keycode; - keySym = XkbKeycodeToKeysym(dpy, keyCode, 0 /* group */, 0 /* shift level */); // layout depending keySym w/o SHIFT - if( XLookupString(&evt.xkey, text, 255, &shiftedKeySym, 0) == 1 ) { - keyChar=text[0]; + // Layout depending keySym w/o SHIFT, + // using fixed group 0 (US default layout) + // + // unsigned int mods_rtrn = 0; + // Bool res = XkbTranslateKeyCode (kbdDesc, keyCode, 0, &mods_rtrn, &keySym); // XKB disabled for now + // if( !res ) { + keySym = XkbKeycodeToKeysym(dpy, keyCode, 0 /* group */, 0 /* shift level */); + // } + + text[0] = 0; text[1] = 0; text[2] = 0; + int charCount = XLookupString(&evt.xkey, text, 2, &shiftedKeySym, NULL); + if( 1 == charCount ) { + keyChar = 0x00FF & (uint16_t) (text[0]); + } else if( 2 == charCount ) { + // Example: UTF-16: 00DF, UTF-8: c3 9f, LATIN SMALL LETTER SHARP S + keyChar = ( 0x00FF & (uint16_t)(text[0]) ) << 8 | ( 0x00FF & (uint16_t)(text[1]) ); // UTF-16BE + keyString = (*env)->NewStringUTF(env, text); } - javaVKeyNN = X11KeySym2NewtVKey(keySym); - javaVKeyUS = javaVKeyNN; // FIXME! - modifiers |= X11InputState2NewtModifiers(evt.xkey.state, javaVKeyNN, evt.type == KeyPress) | autoRepeatModifiers; + evt.xkey.state = evt.xkey.state & ~ShiftMask; // clear shift + XLookupString(&evt.xkey, text, 0, &unShiftedKeySym, NULL); + // unShiftedKeySym = XLookupKeysym(&evt.xkey, 0 /* index ? */); + + javaVKeyNN = X11KeySym2NewtVKey(unShiftedKeySym); + javaVKeyUS = X11KeySym2NewtVKey(keySym); + modifiers |= X11InputState2NewtModifiers(xkey_state, javaVKeyNN, evt.type == KeyPress) | autoRepeatModifiers; #ifdef DEBUG_KEYS - fprintf(stderr, "NEWT X11 Key: keyCode 0x%X keySym 0x%X (shifted: 0x%X), keyChar '%c', javaVKey[US 0x%X, NN 0x%X], xstate 0x%X %u, jmods 0x%X\n", - (int)keyCode, (int)keySym, (int)shiftedKeySym, keyChar, + fprintf(stderr, "NEWT X11 Key: keyCode 0x%X keySym 0x%X, (0x%X, shifted: 0x%X), keyChar '%c' 0x%X %d, javaVKey[US 0x%X, NN 0x%X], xstate 0x%X %u, jmods 0x%X\n", + (int)keyCode, (int)keySym, (int) unShiftedKeySym, (int)shiftedKeySym, keyChar, keyChar, charCount, (int)javaVKeyUS, (int)javaVKeyNN, - (int)evt.xkey.state, (int)evt.xkey.state, (int)modifiers); + (int)xkey_state, (int)xkey_state, (int)modifiers); #endif } break; @@ -463,13 +499,17 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage modifiers, (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/); break; + case MappingNotify: + DBG_PRINT( "X11: event . MappingNotify call %p type %d\n", (void*)evt.xmapping.window, evt.xmapping.type); + XRefreshKeyboardMapping(&evt.xmapping); + break; case KeyPress: (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jshort) EVENT_KEY_PRESSED, - modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar); + modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar, keyString); break; case KeyRelease: (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jshort) EVENT_KEY_RELEASED, - modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar); + modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar, keyString); break; case DestroyNotify: DBG_PRINT( "X11: event . DestroyNotify call %p, parent %p, child-event: %d\n", diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 202ad6fff..9e96169f5 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -671,7 +671,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWindow0 * Signature: (JJ)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0 - (JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom, jlong windowDeleteAtom) + (JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom, jlong windowDeleteAtom /*, jlong kbdHandle*/) // XKB disabled for now { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; @@ -698,7 +698,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0 XUnmapWindow(dpy, w); // Drain all events related to this window .. - Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom); + Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom /*, kbdHandle */); // XKB disabled for now XDestroyWindow(dpy, w); XSync(dpy, True); // discard all events now, no more handler -- cgit v1.2.3 From 6ebf649d1b87944257fe492e0aef842d1b8debc2 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Mon, 6 May 2013 17:27:09 +0200 Subject: Fix Bug 600 and Bug 721: Adding support for multiple monitors w/ NEWT - Support for all monitor devices and their available modes - X11: Use RandR 1.3 if available - Retrieve information - Changing a monitor device's mode - Support for dedicated and spannig fullscreen - See - TODO: - X11 RandR does _not_ relayout the virtual screen size and neither the CRT's viewport. We may need to relayout them if they were covering a seamless region to achieve same experience! - OSX: No machine to attach a secondary CRT -> TEST! - Tested Manually for Regressions - Linux ARMv6hf (Rasp-Pi/BCM, Panda/X11) - Android (Huawei, Kindle) - Tested Manually and junit: - X11/Linux - NV, ATI-Catalyst w/ 2 CRTs - VBox w/ 4 CRTs - Win/Windows - NV, w/ 2 CRTs - VBox w/ 4 CRTs - X11/OpenIndiana, NV, 1 CRT --- make/build-newt.xml | 1 + make/scripts/java-win64-dbg.bat | 1 + make/scripts/tests-x64.bat | 13 +- make/scripts/tests.sh | 18 +- .../javax/media/nativewindow/util/Dimension.java | 5 + .../javax/media/nativewindow/util/Insets.java | 8 + .../javax/media/nativewindow/util/Point.java | 4 + .../javax/media/nativewindow/util/Rectangle.java | 86 ++- .../nativewindow/util/RectangleImmutable.java | 20 + .../javax/media/nativewindow/util/SurfaceSize.java | 4 +- .../classes/com/jogamp/newt/MonitorDevice.java | 235 ++++++++ src/newt/classes/com/jogamp/newt/MonitorMode.java | 346 ++++++++++++ src/newt/classes/com/jogamp/newt/Screen.java | 93 ++-- src/newt/classes/com/jogamp/newt/ScreenMode.java | 208 ------- src/newt/classes/com/jogamp/newt/Window.java | 38 +- .../com/jogamp/newt/event/MonitorEvent.java | 71 +++ .../com/jogamp/newt/event/MonitorModeListener.java | 37 ++ .../classes/com/jogamp/newt/event/NEWTEvent.java | 7 +- .../classes/com/jogamp/newt/event/OutputEvent.java | 51 ++ .../com/jogamp/newt/event/ScreenModeListener.java | 39 -- .../classes/com/jogamp/newt/opengl/GLWindow.java | 13 + .../classes/com/jogamp/newt/util/MonitorMode.java | 102 ---- .../com/jogamp/newt/util/MonitorModeUtil.java | 247 +++++++++ .../com/jogamp/newt/util/ScreenModeUtil.java | 341 ------------ .../classes/jogamp/newt/MonitorDeviceImpl.java | 147 +++++ src/newt/classes/jogamp/newt/MonitorModeProps.java | 355 ++++++++++++ src/newt/classes/jogamp/newt/OffscreenWindow.java | 13 +- src/newt/classes/jogamp/newt/ScreenImpl.java | 569 ++++++++++---------- src/newt/classes/jogamp/newt/ScreenModeStatus.java | 231 -------- .../classes/jogamp/newt/ScreenMonitorState.java | 195 +++++++ src/newt/classes/jogamp/newt/WindowImpl.java | 201 +++++-- .../jogamp/newt/driver/android/ScreenDriver.java | 99 +++- .../jogamp/newt/driver/android/WindowDriver.java | 16 +- .../jogamp/newt/driver/awt/ScreenDriver.java | 24 +- .../jogamp/newt/driver/bcm/egl/ScreenDriver.java | 56 +- .../jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java | 56 +- .../jogamp/newt/driver/intel/gdl/ScreenDriver.java | 56 +- .../jogamp/newt/driver/kd/ScreenDriver.java | 54 +- .../jogamp/newt/driver/macosx/ScreenDriver.java | 129 ++--- .../jogamp/newt/driver/macosx/WindowDriver.java | 15 +- .../jogamp/newt/driver/windows/ScreenDriver.java | 146 +++-- src/newt/classes/jogamp/newt/driver/x11/RandR.java | 47 +- .../classes/jogamp/newt/driver/x11/RandR11.java | 320 +++++++---- .../classes/jogamp/newt/driver/x11/RandR13.java | 276 +++++++++- .../jogamp/newt/driver/x11/ScreenDriver.java | 146 +++-- src/newt/native/MacWindow.m | 235 ++++---- src/newt/native/NewtMacWindow.h | 1 - src/newt/native/NewtMacWindow.m | 4 +- src/newt/native/ScreenMode.h | 15 +- src/newt/native/Window.h | 17 +- src/newt/native/WindowsWindow.c | 305 ++++++++--- src/newt/native/X11RandR11.c | 44 +- src/newt/native/X11RandR13.c | 597 ++++++++++++--------- src/newt/native/X11Screen.c | 31 +- src/newt/native/X11Screen.h | 1 + src/newt/native/X11Window.c | 18 +- .../opengl/test/android/NEWTElektronActivity.java | 16 +- .../opengl/test/android/NEWTGearsES1Activity.java | 16 +- .../opengl/test/android/NEWTGearsES2Activity.java | 16 +- .../test/android/NEWTGearsES2ActivityLauncher.java | 1 + .../test/android/NEWTGearsES2TransActivity.java | 16 +- .../opengl/test/android/NEWTGraphUI1pActivity.java | 16 +- .../opengl/test/android/NEWTGraphUI2pActivity.java | 16 +- .../test/android/NEWTRedSquareES1Activity.java | 16 +- .../test/android/NEWTRedSquareES2Activity.java | 16 +- .../jogl/demos/es2/newt/TestGearsES2NEWT.java | 16 +- .../test/junit/jogl/glsl/TestRulerNEWT01.java | 16 +- .../test/junit/newt/ManualScreenMode03NEWT.java | 32 +- .../test/junit/newt/TestScreenMode00NEWT.java | 119 ++-- .../test/junit/newt/TestScreenMode00bNEWT.java | 24 +- .../test/junit/newt/TestScreenMode01NEWT.java | 133 ++--- .../test/junit/newt/TestScreenMode01aNEWT.java | 212 ++++++++ .../test/junit/newt/TestScreenMode01bNEWT.java | 210 +++++--- .../test/junit/newt/TestScreenMode01cNEWT.java | 249 +++++++++ .../test/junit/newt/TestScreenMode02NEWT.java | 75 +-- 75 files changed, 5159 insertions(+), 2463 deletions(-) create mode 100644 src/newt/classes/com/jogamp/newt/MonitorDevice.java create mode 100644 src/newt/classes/com/jogamp/newt/MonitorMode.java delete mode 100644 src/newt/classes/com/jogamp/newt/ScreenMode.java create mode 100644 src/newt/classes/com/jogamp/newt/event/MonitorEvent.java create mode 100644 src/newt/classes/com/jogamp/newt/event/MonitorModeListener.java create mode 100644 src/newt/classes/com/jogamp/newt/event/OutputEvent.java delete mode 100644 src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java delete mode 100644 src/newt/classes/com/jogamp/newt/util/MonitorMode.java create mode 100644 src/newt/classes/com/jogamp/newt/util/MonitorModeUtil.java delete mode 100644 src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java create mode 100644 src/newt/classes/jogamp/newt/MonitorDeviceImpl.java create mode 100644 src/newt/classes/jogamp/newt/MonitorModeProps.java delete mode 100644 src/newt/classes/jogamp/newt/ScreenModeStatus.java create mode 100644 src/newt/classes/jogamp/newt/ScreenMonitorState.java create mode 100644 src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01aNEWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01cNEWT.java (limited to 'src/newt/native/X11Window.c') diff --git a/make/build-newt.xml b/make/build-newt.xml index 862b78422..30c2ddfd1 100644 --- a/make/build-newt.xml +++ b/make/build-newt.xml @@ -593,6 +593,7 @@ + diff --git a/make/scripts/java-win64-dbg.bat b/make/scripts/java-win64-dbg.bat index 8669ba8f8..136fe4667 100755 --- a/make/scripts/java-win64-dbg.bat +++ b/make/scripts/java-win64-dbg.bat @@ -52,6 +52,7 @@ REM set D_ARGS="-Dnativewindow.debug.TraceLock" REM set D_ARGS="-Dnewt.debug.Display" "-Dnewt.debug.EDT" "-Dnewt.debug.Window" REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display" "-Dnewt.debug.EDT" "-Djogl.debug.GLContext" REM set D_ARGS="-Dnewt.debug.Screen" "-Dnewt.debug.EDT" "-Dnativewindow.debug=all" +REM set D_ARGS="-Dnewt.debug.Screen" REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display" "-Dnewt.test.Window.reparent.incompatible=true" REM set X_ARGS="-Dsun.java2d.noddraw=true" "-Dsun.java2d.opengl=true" "-Dsun.awt.noerasebackground=true" diff --git a/make/scripts/tests-x64.bat b/make/scripts/tests-x64.bat index 0133859fd..27ecfb2cc 100755 --- a/make/scripts/tests-x64.bat +++ b/make/scripts/tests-x64.bat @@ -55,7 +55,7 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestIsReali REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper %* REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT -time 30000 REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT %* -scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %* +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %* REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 4000 -x 10 -y 10 -width 100 -height 100 -screen 0 REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 40000 -width 100 -height 100 -screen 0 %* REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT -time 5000 @@ -106,10 +106,13 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestFocus01Swin REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot %* REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.nativewindow.TestRecursiveToolkitLockCORE -REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode00NEWT -REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode01NEWT -REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode02NEWT -REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.ManualScreenMode03NEWT +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode00NEWT %* +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode01aNEWT %* +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode01bNEWT %* +scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode01cNEWT %* +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode01NEWT %* +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode02NEWT %* +REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.ManualScreenMode03NEWT %* REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple %* REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube %* diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index b53c2f760..c6f69ab74 100755 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -135,6 +135,8 @@ function jrun() { #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable" #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.X11Util" #D_ARGS="-Djogl.debug.GLDrawable" + #D_ARGS="-Dnewt.debug.Screen" + #D_ARGS="-Dnewt.test.Screen.disableRandR13" #D_ARGS="-Dnewt.test.Screen.disableScreenMode -Dnewt.debug.Screen" #D_ARGS="-Dnewt.debug.Screen -Djogl.debug.Animator" #D_ARGS="-Djogl.debug.ExtensionAvailabilityCache -Djogl.debug=all -Dnativewindow.debug=all -Djogamp.debug.ProcAddressHelper=true -Djogamp.debug.NativeLibrary=true -Djogamp.debug.NativeLibrary.Lookup=true" @@ -284,7 +286,7 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT $* -testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestRedSquareES2NEWT $* #testswt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasSWT $* #testswt com.jogamp.opengl.test.junit.jogl.demos.es2.swt.TestGearsES2SWT $* @@ -384,10 +386,12 @@ testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode00NEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode00bNEWT #testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01NEWT -#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01bNEWT -#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode02NEWT -#testnoawt com.jogamp.opengl.test.junit.newt.ManualScreenMode03NEWT -#testnoawt -Djava.awt.headless=true com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT +#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01aNEWT $* +#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01bNEWT $* +testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01cNEWT $* +#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode02NEWT $* +#testnoawt com.jogamp.opengl.test.junit.newt.ManualScreenMode03NEWT $* +#testnoawt -Djava.awt.headless=true com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT $* # # awt (testawt) @@ -509,7 +513,9 @@ testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* # # Texture / TextureUtils # -#testawt com.jogamp.opengl.test.junit.jogl.util.texture.TestTexture01AWT +#testawt com.jogamp.opengl.test.junit.jogl.util.texture.TestTexture01AWT $* +#testawt com.jogamp.opengl.test.junit.jogl.util.texture.TestTexture02AWT $* + #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestJPEGImage00NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestJPEGImage01NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestJPEGJoglAWTCompareNewtAWT $* diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/Dimension.java b/src/nativewindow/classes/javax/media/nativewindow/util/Dimension.java index 0a5a94565..4fae98f08 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/util/Dimension.java +++ b/src/nativewindow/classes/javax/media/nativewindow/util/Dimension.java @@ -57,7 +57,9 @@ public class Dimension implements Cloneable, DimensionImmutable { } } + @Override public int getWidth() { return width; } + @Override public int getHeight() { return height; } public void setWidth(int width) { @@ -77,10 +79,12 @@ public class Dimension implements Cloneable, DimensionImmutable { return this; } + @Override public String toString() { return new String(width+" x "+height); } + @Override public boolean equals(Object obj) { if(this == obj) { return true; } if (obj instanceof Dimension) { @@ -91,6 +95,7 @@ public class Dimension implements Cloneable, DimensionImmutable { return false; } + @Override public int hashCode() { // 31 * x == (x << 5) - x int hash = 31 + width; diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/Insets.java b/src/nativewindow/classes/javax/media/nativewindow/util/Insets.java index 199ec27cb..f22668f55 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/util/Insets.java +++ b/src/nativewindow/classes/javax/media/nativewindow/util/Insets.java @@ -57,11 +57,17 @@ public class Insets implements Cloneable, InsetsImmutable { } } + @Override public final int getLeftWidth() { return l; } + @Override public final int getRightWidth() { return r; } + @Override public final int getTotalWidth() { return l + r; } + @Override public final int getTopHeight() { return t; } + @Override public final int getBottomHeight() { return b; } + @Override public final int getTotalHeight() { return t + b; } public void setLeftWidth(int left) { l = left; } @@ -69,6 +75,7 @@ public class Insets implements Cloneable, InsetsImmutable { public void setTopHeight(int top) { t = top; } public void setBottomHeight(int bottom) { b = bottom; } + @Override public boolean equals(Object obj) { if(this == obj) { return true; } if (obj instanceof Insets) { @@ -79,6 +86,7 @@ public class Insets implements Cloneable, InsetsImmutable { return false; } + @Override public int hashCode() { int sum1 = l + b; int sum2 = t + r; diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/Point.java b/src/nativewindow/classes/javax/media/nativewindow/util/Point.java index c53b16928..8e6caf72b 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/util/Point.java +++ b/src/nativewindow/classes/javax/media/nativewindow/util/Point.java @@ -54,6 +54,7 @@ public class Point implements Cloneable, PointImmutable { } } + @Override public boolean equals(Object obj) { if(this == obj) { return true; } if (obj instanceof Point) { @@ -63,14 +64,17 @@ public class Point implements Cloneable, PointImmutable { return false; } + @Override public final int getX() { return x; } + @Override public final int getY() { return y; } + @Override public int hashCode() { // 31 * x == (x << 5) - x int hash = 31 + x; diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/Rectangle.java b/src/nativewindow/classes/javax/media/nativewindow/util/Rectangle.java index 8d6bfe48f..8e6fc8e36 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/util/Rectangle.java +++ b/src/nativewindow/classes/javax/media/nativewindow/util/Rectangle.java @@ -28,6 +28,8 @@ package javax.media.nativewindow.util; +import java.util.List; + public class Rectangle implements Cloneable, RectangleImmutable { int x; int y; @@ -57,15 +59,90 @@ public class Rectangle implements Cloneable, RectangleImmutable { } } + @Override public final int getX() { return x; } + @Override public final int getY() { return y; } + @Override public final int getWidth() { return width; } + @Override public final int getHeight() { return height; } - public void setX(int x) { this.x = x; } - public void setY(int y) { this.y = y; } - public void setWidth(int width) { this.width = width; } - public void setHeight(int height) { this.height = height; } + + public final void setX(int x) { this.x = x; } + public final void setY(int y) { this.y = y; } + public final void setWidth(int width) { this.width = width; } + public final void setHeight(int height) { this.height = height; } + @Override + public final RectangleImmutable union(final RectangleImmutable r) { + return union(r.getX(), r.getY(), r.getX() + r.getWidth(), r.getY() + r.getHeight()); + } + @Override + public final RectangleImmutable union(final int rx1, final int ry1, final int rx2, final int ry2) { + final int x1 = Math.min(x, rx1); + final int y1 = Math.min(y, ry1); + final int x2 = Math.max(x + width, rx2); + final int y2 = Math.max(y + height, ry2); + return new Rectangle(x1, y1, x2 - x1, y2 - y1); + } + /** + * Calculates the union of the given rectangles, stores it in this instance and returns this instance. + * @param rectangles given list of rectangles + * @return this instance holding the union of given rectangles. + */ + public final Rectangle union(final List rectangles) { + int x1=Integer.MAX_VALUE, y1=Integer.MAX_VALUE; + int x2=Integer.MIN_VALUE, y2=Integer.MIN_VALUE; + for(int i=rectangles.size()-1; i>=0; i--) { + final RectangleImmutable vp = rectangles.get(i); + x1 = Math.min(x1, vp.getX()); + x2 = Math.max(x2, vp.getX() + vp.getWidth()); + y1 = Math.min(y1, vp.getY()); + y2 = Math.max(y2, vp.getY() + vp.getHeight()); + } + setX(x1); + setY(y1); + setWidth(x2 - x1); + setHeight(y2 - y1); + return this; + } + + @Override + public final RectangleImmutable intersection(RectangleImmutable r) { + return intersection(r.getX(), r.getY(), r.getX() + r.getWidth(), r.getY() + r.getHeight()); + } + @Override + public final RectangleImmutable intersection(final int rx1, final int ry1, final int rx2, final int ry2) { + final int x1 = Math.max(x, rx1); + final int y1 = Math.max(y, ry1); + final int x2 = Math.min(x + width, rx2); + final int y2 = Math.min(y + height, ry2); + final int ix, iy, iwidth, iheight; + if( x2 < x1 ) { + ix = 0; + iwidth = 0; + } else { + ix = x1; + iwidth = x2 - x1; + } + if( y2 < y1 ) { + iy = 0; + iheight = 0; + } else { + iy = y1; + iheight = y2 - y1; + } + return new Rectangle (ix, iy, iwidth, iheight); + } + @Override + public final float coverage(RectangleImmutable r) { + final RectangleImmutable isect = intersection(r); + final float sqI = (float) ( isect.getWidth()*isect.getHeight() ); + final float sqT = (float) ( width*height ); + return sqI / sqT; + } + + @Override public boolean equals(Object obj) { if(this == obj) { return true; } if (obj instanceof Rectangle) { @@ -76,6 +153,7 @@ public class Rectangle implements Cloneable, RectangleImmutable { return false; } + @Override public int hashCode() { int sum1 = x + height; int sum2 = width + y; diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/RectangleImmutable.java b/src/nativewindow/classes/javax/media/nativewindow/util/RectangleImmutable.java index d3b43c864..7531989de 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/util/RectangleImmutable.java +++ b/src/nativewindow/classes/javax/media/nativewindow/util/RectangleImmutable.java @@ -41,6 +41,26 @@ public interface RectangleImmutable extends WriteCloneable { int getY(); + /** Returns the union of this rectangle and the given rectangle. */ + RectangleImmutable union(final RectangleImmutable r); + /** Returns the union of this rectangleand the given coordinates. */ + RectangleImmutable union(final int rx1, final int ry1, final int rx2, final int ry2); + /** Returns the intersection of this rectangleand the given rectangle. */ + RectangleImmutable intersection(RectangleImmutable r); + /** Returns the intersection of this rectangleand the given coordinates. */ + RectangleImmutable intersection(final int rx1, final int ry1, final int rx2, final int ry2); + /** + * Returns the coverage of given rectangle w/ this this one, i.e. between 0.0 and 1.0. + *

+ * Coverage is computed by: + *

+     *    isect = this.intersection(r);
+     *    coverage = area( isect ) / area( this ) ;
+     * 
+ *

+ */ + float coverage(RectangleImmutable r); + /** * Checks whether two rect objects are equal. Two instances * of Rectangle are equal if the four integer values diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java b/src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java index 8f21bc49b..d7e451af8 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java +++ b/src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java @@ -36,8 +36,8 @@ package javax.media.nativewindow.util; * */ public class SurfaceSize { - DimensionImmutable resolution; - int bitsPerPixel; + final DimensionImmutable resolution; + final int bitsPerPixel; public SurfaceSize(DimensionImmutable resolution, int bitsPerPixel) { if(null==resolution || bitsPerPixel<=0) { diff --git a/src/newt/classes/com/jogamp/newt/MonitorDevice.java b/src/newt/classes/com/jogamp/newt/MonitorDevice.java new file mode 100644 index 000000000..fbe4d8cf0 --- /dev/null +++ b/src/newt/classes/com/jogamp/newt/MonitorDevice.java @@ -0,0 +1,235 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.newt; + +import java.util.List; + +import javax.media.nativewindow.util.DimensionImmutable; +import javax.media.nativewindow.util.Rectangle; +import javax.media.nativewindow.util.RectangleImmutable; + +import com.jogamp.common.util.ArrayHashSet; + +/** + * Visual output device, i.e. a CRT, LED ..consisting of it's components:
+ * + *
  • Immutable + *
      + *
    • nativeId
    • + *
    • {@link DimensionImmutable} size in [mm]
    • + *
    • {@link MonitorMode} original mode
    • + *
    • List<MonitorMode> supportedModes
    • + *
  • + *
  • Mutable + *
      + *
    • {@link MonitorMode} current mode
    • + *
    • {@link RectangleImmutable} viewport (rotated)
    • + *
  • + * + */ +public abstract class MonitorDevice { + protected final Screen screen; // backref + protected final int nativeId; // unique monitor device ID + protected final DimensionImmutable sizeMM; // in [mm] + protected final MonitorMode originalMode; + protected final ArrayHashSet supportedModes; // FIXME: May need to support mutable mode, i.e. adding modes on the fly! + protected MonitorMode currentMode; + protected boolean modeChanged; + protected Rectangle viewport; + + protected MonitorDevice(Screen screen, int nativeId, DimensionImmutable sizeMM, Rectangle viewport, MonitorMode currentMode, ArrayHashSet supportedModes) { + this.screen = screen; + this.nativeId = nativeId; + this.sizeMM = sizeMM; + this.originalMode = currentMode; + this.supportedModes = supportedModes; + this.currentMode = currentMode; + this.viewport = viewport; + this.modeChanged = false; + } + + /** Returns the {@link Screen} owning this monitor. */ + public final Screen getScreen() { + return screen; + } + + /** + * Tests equality of two MonitorDevice objects + * by evaluating equality of it's components:
    + *
      + *
    • nativeID
    • + *
    + *
    + */ + public final boolean equals(Object obj) { + if (this == obj) { return true; } + if (obj instanceof MonitorDevice) { + MonitorDevice md = (MonitorDevice)obj; + return md.nativeId == nativeId; + } + return false; + } + + /** + * Returns a combined hash code of it's elements:
    + *
      + *
    • nativeID
    • + *
    + */ + public final int hashCode() { + return nativeId; + } + + /** @return the immutable unique native Id of this monitor device. */ + public final int getId() { return nativeId; } + + /** + * @return the immutable monitor size in millimeters. + */ + public final DimensionImmutable getSizeMM() { + return sizeMM; + } + + /** + * Return the immutable original {@link com.jogamp.newt.MonitorMode}, as used at NEWT initialization. + * @return original {@link MonitorMode} which is element of the list {@link #getSupportedModes()} and {@link Screen#getMonitorModes()}. + */ + public final MonitorMode getOriginalMode() { + return originalMode; + } + + /** + * FIXME: May need to support mutable mode, i.e. adding modes on the fly! + * @return the immutable list of {@link MonitorMode}s supported by this monitor. Use w/ care, it's not a copy! + */ + public final List getSupportedModes() { + return supportedModes.getData(); + } + + /** @return the {@link RectangleImmutable rectangular} portion of the rotated virtual {@link Screen} size represented by this monitor. */ + public final RectangleImmutable getViewport() { + return viewport; + } + + /** Returns true if given coordinates are contained by this {@link #getViewport() viewport}, otherwise false. */ + public final boolean contains(int x, int y) { + return x >= viewport.getX() && + x < viewport.getX() + viewport.getWidth() && + y >= viewport.getY() && + y < viewport.getY() + viewport.getHeight() ; + } + + /** + * Returns the coverage of given rectangle w/ this this {@link #getViewport() viewport}, i.e. between 0.0 and 1.0. + *

    + * Coverage is computed by: + *

    +     *    isect = viewport.intersection(r);
    +     *    coverage = area( isect ) / area( viewport ) ;
    +     * 
    + *

    + */ + public final float coverage(RectangleImmutable r) { + return viewport.coverage(r); + } + + /** + * Returns the union of the given monitor's {@link #getViewport() viewport}. + * @param result storage for result, will be returned + * @param monitors given list of monitors + * @return viewport representing the union of given monitor's viewport. + */ + public static Rectangle unionOfViewports(final Rectangle result, final List monitors) { + int x1=Integer.MAX_VALUE, y1=Integer.MAX_VALUE; + int x2=Integer.MIN_VALUE, y2=Integer.MIN_VALUE; + for(int i=monitors.size()-1; i>=0; i--) { + final RectangleImmutable vp = monitors.get(i).getViewport(); + x1 = Math.min(x1, vp.getX()); + x2 = Math.max(x2, vp.getX() + vp.getWidth()); + y1 = Math.min(y1, vp.getY()); + y2 = Math.max(y2, vp.getY() + vp.getHeight()); + } + result.setX(x1); + result.setY(y1); + result.setWidth(x2 - x1); + result.setHeight(y2 - y1); + return result; + } + + public final boolean isOriginalMode() { + return currentMode.hashCode() == originalMode.hashCode(); + } + + /** + * Returns true if the {@link MonitorMode} + * has been changed programmatic via this API only, otherwise false. + *

    + * Note: We cannot guarantee that we won't interfere w/ another running + * application's screen mode change or vice versa. + *

    + */ + public final boolean isModeChangedByUs() { + return modeChanged && !isOriginalMode(); + } + + /** + * Return the current cached {@link MonitorMode} w/o native query. + *

    + * If {@link MonitorMode}s are not supported for this + * native type {@link com.jogamp.newt.Display#getType()}, it returns one with the current screen size.

    + * + * @return current {@link MonitorMode} which is element of the list {@link #getSupportedModes()} and {@link Screen#getMonitorModes()}. + */ + public final MonitorMode getCurrentMode() { + return currentMode; + } + + /** + * Return the current {@link MonitorMode} including a native query. + *

    + * If {@link MonitorMode}s are not supported for this + * native type {@link com.jogamp.newt.Display#getType()}, it returns one with the current screen size.

    + * + * @return current {@link MonitorMode} which is element of the list {@link #getSupportedModes()} and {@link Screen#getMonitorModes()}. + */ + public abstract MonitorMode queryCurrentMode(); + + /** + * Set the current {@link com.jogamp.newt.MonitorMode}. + * @param mode to be made current, must be element of the list {@link #getSupportedModes()} and {@link Screen#getMonitorModes()}. + * @return true if successful, otherwise false + */ + public abstract boolean setCurrentMode(MonitorMode mode); + + public String toString() { + return "Monitor[Id "+Display.toHexString(nativeId)+", "+sizeMM+" mm, viewport "+viewport+ ", orig "+originalMode+", curr "+currentMode+ + ", modeChanged "+modeChanged+", modeCount "+supportedModes.size()+"]"; + } +} + diff --git a/src/newt/classes/com/jogamp/newt/MonitorMode.java b/src/newt/classes/com/jogamp/newt/MonitorMode.java new file mode 100644 index 000000000..e5b329d47 --- /dev/null +++ b/src/newt/classes/com/jogamp/newt/MonitorMode.java @@ -0,0 +1,346 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.newt; + +import javax.media.nativewindow.util.DimensionImmutable; +import javax.media.nativewindow.util.SurfaceSize; + + +/** Immutable MonitorMode Class, consisting of it's read only components:
    + *
      + *
    • nativeId
    • + *
    • {@link SizeAndRRate}, non rotated surfaceSize and refreshRate
    • + *
    • rotation, measured counter clockwise (CCW)
    • + *
    + * + * Aquire and filter MonitorMode
    + *
      + *
    • A List of read only MonitorModes is being returned by {@link com.jogamp.newt.Screen#getMonitorModes()}.
    • + *
    • You may utilize {@link com.jogamp.newt.util.MonitorModeUtil} to filter and select a desired ScreenMode.
    • + *
    • The current ScreenMode can be obtained via {@link com.jogamp.newt.Screen#getCurrentScreenMode()}.
    • + *
    • The initial original ScreenMode (at startup) can be obtained via {@link com.jogamp.newt.Screen#getOriginalScreenMode()}.
    • + *
    + *
    + * + * Changing ScreenModes
    + * FIXME!!!!! + *
      + *
    • Use {@link com.jogamp.newt.Screen#setCurrentScreenMode(com.jogamp.newt.MonitorMode)}
    • + * to change the current ScreenMode of all Screen's referenced via the full qualified name (FQN) + * {@link com.jogamp.newt.Screen#getFQName()}. + *
    • When the last FQN referenced Screen closes, the original ScreenMode ({@link com.jogamp.newt.Screen#getOriginalScreenMode()}) + * is restored.
    • + *
    + *
    + * Example for changing the ScreenMode: + *
    +        // determine target refresh rate
    +        ScreenMode orig = screen.getOriginalScreenMode();
    +        int freq = orig.getOutputMode().getRefreshRate();
    +
    +        // target resolution
    +        Dimension res = new Dimension(800, 600);
    +
    +        // target rotation
    +        int rot = 0;
    +
    +        // filter available ScreenModes
    +        List screenModes = screen.getScreenModes();
    +        screenModes = ScreenModeUtil.filterByRate(screenModes, freq); // get the nearest ones
    +        screenModes = ScreenModeUtil.filterByRotation(screenModes, rot);
    +        screenModes = ScreenModeUtil.filterByResolution(screenModes, res); // get the nearest ones
    +        screenModes = ScreenModeUtil.getHighestAvailableBpp(screenModes);
    +
    +        // pick 1st one ..
    +        screen.setCurrentScreenMode((ScreenMode) screenModes.get(0)); 
    + * 
    + * + * X11 / AMD just works
    + *
    + * X11 / NVidia difficulties + *
    +    NVidia RANDR RefreshRate Bug
    +        If NVidia's 'DynamicTwinView' is enabled, all refresh rates are
    +        unique, ie consequent numbers starting with the default refresh, ie 50, 51, ..
    +        The only way to workaround it is to disable 'DynamicTwinView'.
    +        Read: http://us.download.nvidia.com/XFree86/Linux-x86/260.19.12/README/configtwinview.html
    +
    +        Check to see if 'DynamicTwinView' is enable:
    +            nvidia-settings -q :0/DynamicTwinview
    +
    +        To disable it (workaround), add the following option to your xorg.conf device section:
    +            Option "DynamicTwinView" "False"
    +
    +    NVidia RANDR Rotation:
    +        To enable it, add the following option to your xorg.conf device section:
    +            Option "RandRRotation" "on"
    + * 
    + * + */ +public class MonitorMode { + /** + * Immutable surfaceSize and refreshRate Class, consisting of it's read only components:
    + *
      + *
    • nativeId
    • + *
    • {@link SurfaceSize} surface memory size
    • + *
    • refresh rate
    • + *
    + */ + public static class SizeAndRRate { + public final SurfaceSize surfaceSize; + public final float refreshRate; + public final int flags; + public final int hashCode; + + public SizeAndRRate(SurfaceSize surfaceSize, float refreshRate, int flags) { + if(null==surfaceSize) { + throw new IllegalArgumentException("surfaceSize must be set ("+surfaceSize+")"); + } + this.surfaceSize=surfaceSize; + this.refreshRate=refreshRate; + this.flags = flags; + this.hashCode = getHashCode(); + } + + private final static String STR_INTERLACE = "Interlace"; + private final static String STR_DOUBLESCAN = "DoubleScan"; + private final static String STR_SEP = ", "; + + public static final StringBuffer flags2String(int flags) { + final StringBuffer sb = new StringBuffer(); + boolean sp = false; + if( 0 != ( flags & FLAG_INTERLACE ) ) { + sb.append(STR_INTERLACE); + sp = true; + } + if( 0 != ( flags & FLAG_DOUBLESCAN ) ) { + if( sp ) { + sb.append(STR_SEP); + } + sb.append(STR_DOUBLESCAN); + sp = true; + } + return sb; + } + public final String toString() { + return new String(surfaceSize+" @ "+refreshRate+" Hz, flags ["+flags2String(flags).toString()+"]"); + } + + /** + * Tests equality of two {@link SizeAndRRate} objects + * by evaluating equality of it's components:
    + *
      + *
    • surfaceSize
    • + *
    • refreshRate
    • + *
    • flags
    • + *
    + */ + public final boolean equals(Object obj) { + if (this == obj) { return true; } + if (obj instanceof SizeAndRRate) { + final SizeAndRRate p = (SizeAndRRate)obj; + return surfaceSize.equals(p.surfaceSize) && + refreshRate == p.refreshRate && + flags == p.flags ; + } + return false; + } + + /** + * Returns a combined hash code of it's elements:
    + *
      + *
    • surfaceSize
    • + *
    • refreshRate
    • + *
    • flags
    • + *
    + */ + public final int hashCode() { + return hashCode; + } + private final int getHashCode() { + // 31 * x == (x << 5) - x + int hash = 31 + surfaceSize.hashCode(); + hash = ((hash << 5) - hash) + (int)(refreshRate*100.0f); + hash = ((hash << 5) - hash) + flags; + return hash; + } + } + + /** zero rotation, compared to normal settings */ + public static final int ROTATE_0 = 0; + + /** 90 degrees CCW rotation */ + public static final int ROTATE_90 = 90; + + /** 180 degrees CCW rotation */ + public static final int ROTATE_180 = 180; + + /** 270 degrees CCW rotation */ + public static final int ROTATE_270 = 270; + + /** Frame is split into two fields. See {@link #getFlags()}. */ + public static final int FLAG_INTERLACE = 1 << 0; + + /** Lines are doubled. See {@link #getFlags()}. */ + public static final int FLAG_DOUBLESCAN = 1 << 1; + + /** The immutable native Id of this instance, which may not be unique. */ + private final int nativeId; + private final SizeAndRRate sizeAndRRate; + private final int rotation; + private final int hashCode; + + public static boolean isRotationValid(int rotation) { + return rotation == MonitorMode.ROTATE_0 || rotation == MonitorMode.ROTATE_90 || + rotation == MonitorMode.ROTATE_180 || rotation == MonitorMode.ROTATE_270 ; + } + + /** + * @param sizeAndRRate the surface size and refresh rate mode + * @param rotation the screen rotation, measured counter clockwise (CCW) + */ + public MonitorMode(int nativeId, SizeAndRRate sizeAndRRate, int rotation) { + if ( !isRotationValid(rotation) ) { + throw new RuntimeException("invalid rotation: "+rotation); + } + this.nativeId = nativeId; + this.sizeAndRRate = sizeAndRRate; + this.rotation = rotation; + this.hashCode = getHashCode(); + } + + /** + * Creates a user instance w/o {@link #getId() identity} to filter our matching modes w/ identity. + *

    + * See {@link com.jogamp.newt.util.MonitorModeUtil} for filter utilities. + *

    + * @param surfaceSize + * @param refreshRate + * @param flags + * @param rotation + */ + public MonitorMode(SurfaceSize surfaceSize, float refreshRate, int flags, int rotation) { + this(0, new SizeAndRRate(surfaceSize, refreshRate, flags), rotation); + } + + /** @return the immutable native Id of this mode, may not be unique, may be 0. */ + public final int getId() { return nativeId; } + + /** Returns the surfaceSize and refreshRate instance. */ + public final SizeAndRRate getSizeAndRRate() { + return sizeAndRRate; + } + + /** Returns the unrotated {@link SurfaceSize} */ + public final SurfaceSize getSurfaceSize() { + return sizeAndRRate.surfaceSize; + } + + public final float getRefreshRate() { + return sizeAndRRate.refreshRate; + } + + /** Returns bitfield w/ flags, i.e. {@link #FLAG_DOUBLESCAN}, {@link #FLAG_INTERLACE}, .. */ + public final int getFlags() { + return sizeAndRRate.flags; + } + + /** Returns the CCW rotation of this mode */ + public final int getRotation() { + return rotation; + } + + /** Returns the rotated screen width, + * derived from getMonitorMode().getSurfaceSize().getResolution() + * and getRotation() + */ + public final int getRotatedWidth() { + return getRotatedWH(true); + } + + /** Returns the rotated screen height, + * derived from getMonitorMode().getSurfaceSize().getResolution() + * and getRotation() + */ + public final int getRotatedHeight() { + return getRotatedWH(false); + } + + public final String toString() { + return "[Id "+Display.toHexString(nativeId)+", " + sizeAndRRate + ", " + rotation + " degr]"; + } + + /** + * Tests equality of two {@link MonitorMode} objects + * by evaluating equality of it's components:
    + *
      + *
    • nativeId
    • + *
    • sizeAndRRate
    • + *
    • rotation
    • + *
    + */ + public final boolean equals(Object obj) { + if (this == obj) { return true; } + if (obj instanceof MonitorMode) { + MonitorMode sm = (MonitorMode)obj; + return sm.nativeId == this.nativeId && + sm.sizeAndRRate.equals(sizeAndRRate) && + sm.rotation == this.rotation ; + } + return false; + } + + /** + * Returns a combined hash code of it's elements:
    + *
      + *
    • nativeId
    • + *
    • sizeAndRRate
    • + *
    • rotation
    • + *
    + */ + public final int hashCode() { + return hashCode; + } + private final int getHashCode() { + // 31 * x == (x << 5) - x + int hash = 31 + getId(); + hash = ((hash << 5) - hash) + sizeAndRRate.hashCode(); + hash = ((hash << 5) - hash) + getRotation(); + return hash; + } + + private final int getRotatedWH(boolean width) { + final DimensionImmutable d = sizeAndRRate.surfaceSize.getResolution(); + final boolean swap = MonitorMode.ROTATE_90 == rotation || MonitorMode.ROTATE_270 == rotation ; + if ( ( width && swap ) || ( !width && !swap ) ) { + return d.getHeight(); + } + return d.getWidth(); + } +} diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java index a09748d52..81a62d898 100644 --- a/src/newt/classes/com/jogamp/newt/Screen.java +++ b/src/newt/classes/com/jogamp/newt/Screen.java @@ -27,14 +27,19 @@ */ package com.jogamp.newt; -import com.jogamp.newt.event.ScreenModeListener; +import com.jogamp.newt.event.MonitorModeListener; import jogamp.newt.Debug; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.util.Rectangle; +import javax.media.nativewindow.util.RectangleImmutable; +/** + * A screen may span multiple {@link MonitorDevice}s representing their combined virtual size. + */ public abstract class Screen { /** @@ -122,25 +127,30 @@ public abstract class Screen { public abstract int getIndex(); /** - * @return the x position of the virtual top-left origin. + * @return the x position of the virtual viewport's top-left origin. */ public abstract int getX(); /** - * @return the y position of the virtual top-left origin. + * @return the y position of the virtual viewport's top-left origin. */ public abstract int getY(); /** - * @return the rotated virtual width. + * @return the rotated virtual viewport's width. */ public abstract int getWidth(); /** - * @return the rotated virtual height. + * @return the rotated virtual viewport's height. */ public abstract int getHeight(); + /** + * @return the rotated virtual viewport, i.e. origin and size. + */ + public abstract RectangleImmutable getViewport(); + /** * @return the associated Display */ @@ -152,48 +162,68 @@ public abstract class Screen { */ public abstract String getFQName(); - /** - * @param sml ScreenModeListener to be added for ScreenMode change events - */ - public abstract void addScreenModeListener(ScreenModeListener sml); - - /** - * @param sml ScreenModeListener to be removed from ScreenMode change events + /** + * Return a list of all available {@link MonitorMode}s for all {@link MonitorDevice}s. + *

    + * If {@link com.jogamp.newt.MonitorMode ScreenMode}s are not supported for this + * native type {@link com.jogamp.newt.Display#getType()}, it returns a list of size one with the current screen size.

    */ - public abstract void removeScreenModeListener(ScreenModeListener sml); + public abstract List getMonitorModes(); /** - * Return a list of available {@link com.jogamp.newt.ScreenMode ScreenMode}s. + * Return a list of all available {@link MonitorDevice}s. *

    - * If {@link com.jogamp.newt.ScreenMode ScreenMode}s are not supported for this + * If {@link com.jogamp.newt.MonitorMode ScreenMode}s are not supported for this * native type {@link com.jogamp.newt.Display#getType()}, it returns a list of size one with the current screen size.

    - * - * @return a shallow copy of the internal immutable {@link com.jogamp.newt.ScreenMode ScreenMode}s. */ - public abstract List getScreenModes(); + public abstract List getMonitorDevices(); /** - * Return the original {@link com.jogamp.newt.ScreenMode}, as used at NEWT initialization. - * @return original ScreenMode which is element of the list {@link #getScreenModes()}. + * Returns the {@link MonitorDevice} which {@link MonitorDevice#getViewport() viewport} + * {@link MonitorDevice#coverage(RectangleImmutable) covers} the given rectangle the most. + *

    + * If no coverage is detected the first {@link MonitorDevice} is returned. + *

    */ - public abstract ScreenMode getOriginalScreenMode(); + public final MonitorDevice getMainMonitor(RectangleImmutable r) { + MonitorDevice res = null; + float maxCoverage = Float.MIN_VALUE; + final List monitors = getMonitorDevices(); + for(int i=monitors.size()-1; i>=0; i--) { + final MonitorDevice monitor = monitors.get(i); + final float coverage = monitor.coverage(r); + if( coverage > maxCoverage ) { + maxCoverage = coverage; + res = monitor; + } + } + if( maxCoverage > 0.0f && null != res ) { + return res; + } + return monitors.get(0); + } /** - * Return the current {@link com.jogamp.newt.ScreenMode}. + * Returns the union of all monitor's {@link MonitorDevice#getViewport() viewport}. *

    - * If {@link com.jogamp.newt.ScreenMode ScreenMode}s are not supported for this - * native type {@link com.jogamp.newt.Display#getType()}, it returns one with the current screen size.

    - * - * @return current ScreenMode which is element of the list {@link #getScreenModes()}. + * Should be equal to {@link #getX()}, {@link #getY()}, {@link #getWidth()} and {@link #getHeight()}, + * however, some native toolkits may choose a different virtual screen area. + *

    + * @param result storage for result, will be returned + */ + public final Rectangle unionOfMonitorViewportSize(final Rectangle result) { + return MonitorDevice.unionOfViewports(result, getMonitorDevices()); + } + + /** + * @param sml {@link MonitorModeListener} to be added for {@link MonitorEvent} */ - public abstract ScreenMode getCurrentScreenMode(); + public abstract void addMonitorModeListener(MonitorModeListener sml); /** - * Set the current {@link com.jogamp.newt.ScreenMode}. - * @param screenMode to be made current, must be element of the list {@link #getScreenModes()}. - * @return true if successful, otherwise false + * @param sml {@link MonitorModeListener} to be removed from {@link MonitorEvent} */ - public abstract boolean setCurrentScreenMode(ScreenMode screenMode); + public abstract void removeMonitorModeListener(MonitorModeListener sml); // Global Screens protected static ArrayList screenList = new ArrayList(); @@ -236,6 +266,7 @@ public abstract class Screen { return null; } /** Returns the global display collection */ + @SuppressWarnings("unchecked") public static Collection getAllScreens() { ArrayList list; synchronized(screenList) { diff --git a/src/newt/classes/com/jogamp/newt/ScreenMode.java b/src/newt/classes/com/jogamp/newt/ScreenMode.java deleted file mode 100644 index 1f12217bb..000000000 --- a/src/newt/classes/com/jogamp/newt/ScreenMode.java +++ /dev/null @@ -1,208 +0,0 @@ -/** - * Copyright 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ - -package com.jogamp.newt; - -import javax.media.nativewindow.util.DimensionImmutable; - -import com.jogamp.newt.util.MonitorMode; - -/** Immutable ScreenMode Class, consisting of it's read only components:
    - *
      - *
    • {@link com.jogamp.newt.util.MonitorMode}, non rotated values
    • - *
    • rotation, measured counter clockwise (CCW)
    • - *
    - * - * Aquire and filter ScreenModes
    - *
      - *
    • A List of read only ScreenMode's is being returned by {@link com.jogamp.newt.Screen#getScreenModes()}.
    • - *
    • You may utilize {@link com.jogamp.newt.util.ScreenModeUtil} to filter and select a desired ScreenMode.
    • - *
    • The current ScreenMode can be obtained via {@link com.jogamp.newt.Screen#getCurrentScreenMode()}.
    • - *
    • The initial original ScreenMode (at startup) can be obtained via {@link com.jogamp.newt.Screen#getOriginalScreenMode()}.
    • - *
    - *
    - * - * Changing ScreenModes
    - *
      - *
    • Use {@link com.jogamp.newt.Screen#setCurrentScreenMode(com.jogamp.newt.ScreenMode)}
    • - * to change the current ScreenMode of all Screen's referenced via the full qualified name (FQN) - * {@link com.jogamp.newt.Screen#getFQName()}. - *
    • When the last FQN referenced Screen closes, the original ScreenMode ({@link com.jogamp.newt.Screen#getOriginalScreenMode()}) - * is restored.
    • - *
    - *
    - * Example for changing the ScreenMode: - *
    -        // determine target refresh rate
    -        ScreenMode orig = screen.getOriginalScreenMode();
    -        int freq = orig.getMonitorMode().getRefreshRate();
    -
    -        // target resolution
    -        Dimension res = new Dimension(800, 600);
    -
    -        // target rotation
    -        int rot = 0;
    -
    -        // filter available ScreenModes
    -        List screenModes = screen.getScreenModes();
    -        screenModes = ScreenModeUtil.filterByRate(screenModes, freq); // get the nearest ones
    -        screenModes = ScreenModeUtil.filterByRotation(screenModes, rot);
    -        screenModes = ScreenModeUtil.filterByResolution(screenModes, res); // get the nearest ones
    -        screenModes = ScreenModeUtil.getHighestAvailableBpp(screenModes);
    -
    -        // pick 1st one ..
    -        screen.setCurrentScreenMode((ScreenMode) screenModes.get(0)); 
    - * 
    - * - * X11 / AMD just works
    - *
    - * X11 / NVidia difficulties - *
    -    NVidia RANDR RefreshRate Bug
    -        If NVidia's 'DynamicTwinView' is enabled, all refresh rates are
    -        unique, ie consequent numbers starting with the default refresh, ie 50, 51, ..
    -        The only way to workaround it is to disable 'DynamicTwinView'.
    -        Read: http://us.download.nvidia.com/XFree86/Linux-x86/260.19.12/README/configtwinview.html
    -
    -        Check to see if 'DynamicTwinView' is enable:
    -            nvidia-settings -q :0/DynamicTwinview
    -
    -        To disable it (workaround), add the following option to your xorg.conf device section:
    -            Option "DynamicTwinView" "False"
    -
    -    NVidia RANDR Rotation:
    -        To enable it, add the following option to your xorg.conf device section:
    -            Option "RandRRotation" "on"
    - * 
    - * - */ -public class ScreenMode { - /** zero rotation, compared to normal settings */ - public static final int ROTATE_0 = 0; - - /** 90 degrees CCW rotation */ - public static final int ROTATE_90 = 90; - - /** 180 degrees CCW rotation */ - public static final int ROTATE_180 = 180; - - /** 270 degrees CCW rotation */ - public static final int ROTATE_270 = 270; - - MonitorMode monitorMode; - int rotation; - - public static boolean isRotationValid(int rotation) { - return rotation == ScreenMode.ROTATE_0 || rotation == ScreenMode.ROTATE_90 || - rotation == ScreenMode.ROTATE_180 || rotation == ScreenMode.ROTATE_270 ; - } - - /** - * @param monitorMode the monitor mode - * @param rotation the screen rotation, measured counter clockwise (CCW) - */ - public ScreenMode(MonitorMode monitorMode, int rotation) { - if ( !isRotationValid(rotation) ) { - throw new RuntimeException("invalid rotation: "+rotation); - } - this.monitorMode = monitorMode; - this.rotation = rotation; - } - - /** Returns the unrotated MonitorMode */ - public final MonitorMode getMonitorMode() { - return monitorMode; - } - - /** Returns the CCW rotation of this mode */ - public final int getRotation() { - return rotation; - } - - /** Returns the rotated screen width, - * derived from getMonitorMode().getSurfaceSize().getResolution() - * and getRotation() - */ - public final int getRotatedWidth() { - return getRotatedWH(true); - } - - /** Returns the rotated screen height, - * derived from getMonitorMode().getSurfaceSize().getResolution() - * and getRotation() - */ - public final int getRotatedHeight() { - return getRotatedWH(false); - } - - public final String toString() { - return "[ " + getMonitorMode() + ", " + rotation + " degr ]"; - } - - /** - * Tests equality of two ScreenMode objects - * by evaluating equality of it's components:
    - *
      - *
    • monitorMode
    • - *
    • rotation
    • - *
    - *
    - */ - public final boolean equals(Object obj) { - if (this == obj) { return true; } - if (obj instanceof ScreenMode) { - ScreenMode sm = (ScreenMode)obj; - return sm.getMonitorMode().equals(getMonitorMode()) && - sm.getRotation() == this.getRotation() ; - } - return false; - } - - /** - * Returns a combined hash code of it's elements:
    - *
      - *
    • monitorMode
    • - *
    • rotation
    • - *
    - */ - public final int hashCode() { - // 31 * x == (x << 5) - x - int hash = 31 + getMonitorMode().hashCode(); - hash = ((hash << 5) - hash) + getRotation(); - return hash; - } - - private final int getRotatedWH(boolean width) { - final DimensionImmutable d = getMonitorMode().getSurfaceSize().getResolution(); - final boolean swap = ScreenMode.ROTATE_90 == rotation || ScreenMode.ROTATE_270 == rotation ; - if ( ( width && swap ) || ( !width && !swap ) ) { - return d.getHeight(); - } - return d.getWidth(); - } -} diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index ab1eef308..0bebf330a 100644 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -28,6 +28,8 @@ package com.jogamp.newt; +import java.util.List; + import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.event.WindowListener; import com.jogamp.newt.event.KeyListener; @@ -41,6 +43,7 @@ import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.WindowClosingProtocol; +import javax.media.nativewindow.util.RectangleImmutable; /** * Specifying NEWT's Window functionality: @@ -80,10 +83,19 @@ public interface Window extends NativeWindow, WindowClosingProtocol { boolean isNativeValid(); /** - * @return The associated Screen + * @return The associated {@link Screen} */ Screen getScreen(); + /** + * Returns the {@link MonitorDevice} which {@link MonitorDevice#getViewport() viewport} + * {@link MonitorDevice#coverage(RectangleImmutable) covers} this window the most. + *

    + * If no coverage is detected the first {@link MonitorDevice} is returned. + *

    + */ + MonitorDevice getMainMonitor(); + /** * Set the CapabilitiesChooser to help determine the native visual type. * @@ -344,8 +356,32 @@ public interface Window extends NativeWindow, WindowClosingProtocol { ReparentOperation reparentWindow(NativeWindow newParent, boolean forceDestroyCreate); + /** + * Enable or disable fullscreen mode for this window. + *

    + * Fullscreen mode is established on the {@link #getMainMonitor() main monitor}. + *

    + * @param fullscreen enable or disable fullscreen mode + * @return success + * @see #setFullscreen(List) + * @see #isFullscreen() + */ boolean setFullscreen(boolean fullscreen); + /** + * Enable fullscreen mode for this window spanning across the given {@link MonitorDevice}s + * or across all {@link MonitorDevice}s. + *

    + * Disable fullscreen via {@link #setFullscreen(boolean)}. + *

    + * @param monitors if null fullscreen will be spanned across all {@link MonitorDevice}s, + * otherwise across the given list of {@link MonitorDevice}. + * @return success + * @see #setFullscreen(boolean) + * @see #isFullscreen() + */ + boolean setFullscreen(List monitors); + boolean isFullscreen(); static interface FocusRunnable { diff --git a/src/newt/classes/com/jogamp/newt/event/MonitorEvent.java b/src/newt/classes/com/jogamp/newt/event/MonitorEvent.java new file mode 100644 index 000000000..c47936a7a --- /dev/null +++ b/src/newt/classes/com/jogamp/newt/event/MonitorEvent.java @@ -0,0 +1,71 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.newt.event; + +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; + +@SuppressWarnings("serial") +public class MonitorEvent extends OutputEvent { + public static final short EVENT_MONITOR_MODE_CHANGE_NOTIFY = 600; + public static final short EVENT_MONITOR_MODE_CHANGED = 601; + + private final MonitorMode mode; + + public MonitorEvent (short eventType, MonitorDevice source, long when, MonitorMode mode) { + super(eventType, source, when); + this.mode = mode; + } + + /** Returns the {@link #getSource() source}, which is a {@link MonitorDevice}. */ + public final MonitorDevice getMonitor() { return (MonitorDevice)source; } + + public final MonitorMode getMode() { return mode; } + + public static String getEventTypeString(short type) { + switch(type) { + case EVENT_MONITOR_MODE_CHANGE_NOTIFY: return "EVENT_MONITOR_MODE_CHANGE_NOTIFY"; + case EVENT_MONITOR_MODE_CHANGED: return "EVENT_MONITOR_MODE_CHANGED"; + default: return "unknown (" + type + ")"; + } + } + + public final String toString() { + return toString(null).toString(); + } + + public final StringBuilder toString(StringBuilder sb) { + if(null == sb) { + sb = new StringBuilder(); + } + sb.append("MonitorEvent[").append(getEventTypeString(getEventType())).append(", source ").append(source) + .append(", mode ").append(mode).append(", "); + return super.toString(sb).append("]"); + } +} diff --git a/src/newt/classes/com/jogamp/newt/event/MonitorModeListener.java b/src/newt/classes/com/jogamp/newt/event/MonitorModeListener.java new file mode 100644 index 000000000..11e23def1 --- /dev/null +++ b/src/newt/classes/com/jogamp/newt/event/MonitorModeListener.java @@ -0,0 +1,37 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.newt.event; + +public interface MonitorModeListener { + /** called before the monitor mode will be changed */ + void monitorModeChangeNotify(MonitorEvent me); + + /** called after the monitor mode has been changed */ + void monitorModeChanged(MonitorEvent me, boolean success); +} diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java index ea96f634f..c1bc791d8 100644 --- a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java @@ -41,9 +41,10 @@ package com.jogamp.newt.event; * * Event type registry:
    *
      - *
    • WindowEvent 100..10x
    • - *
    • MouseEvent 200..20x
    • - *
    • KeyEvent 300..30x
    • + *
    • WindowEvent 100..10x
    • + *
    • MouseEvent 200..20x
    • + *
    • KeyEvent 300..30x
    • + *
    • MonitorEvent 600..60x
    • *

    */ @SuppressWarnings("serial") diff --git a/src/newt/classes/com/jogamp/newt/event/OutputEvent.java b/src/newt/classes/com/jogamp/newt/event/OutputEvent.java new file mode 100644 index 000000000..86fa95877 --- /dev/null +++ b/src/newt/classes/com/jogamp/newt/event/OutputEvent.java @@ -0,0 +1,51 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.newt.event; + +@SuppressWarnings("serial") +public abstract class OutputEvent extends NEWTEvent +{ + protected OutputEvent(short eventType, Object source, long when) { + super(eventType, source, when); + } + + /** + public String toString() { + return toString(null).toString(); + } + + public StringBuilder toString(StringBuilder sb) { + if(null == sb) { + sb = new StringBuilder(); + } + sb.append("OutputEvent["); + super.toString(sb).append("]"); + return sb; + } */ +} diff --git a/src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java b/src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java deleted file mode 100644 index 7bca23cfe..000000000 --- a/src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ - -package com.jogamp.newt.event; - -import com.jogamp.newt.ScreenMode; - -public interface ScreenModeListener { - /** called before the screen mode will be changed */ - void screenModeChangeNotify(ScreenMode sm); - - /** called after the screen mode has been changed */ - void screenModeChanged(ScreenMode sm, boolean success); -} diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index de62747be..1500d48e6 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -34,6 +34,8 @@ package com.jogamp.newt.opengl; +import java.util.List; + import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; @@ -64,6 +66,7 @@ import jogamp.opengl.GLDrawableImpl; import com.jogamp.common.GlueGenVersion; import com.jogamp.common.util.VersionUtil; import com.jogamp.common.util.locks.RecursiveLock; +import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Screen; import com.jogamp.newt.Window; @@ -224,6 +227,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind return window.getScreen(); } + @Override + public final MonitorDevice getMainMonitor() { + return window.getMainMonitor(); + } + @Override public final void setTitle(String title) { window.setTitle(title); @@ -341,6 +349,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind public final boolean setFullscreen(boolean fullscreen) { return window.setFullscreen(fullscreen); } + + @Override + public boolean setFullscreen(List monitors) { + return window.setFullscreen(monitors); + } @Override public final boolean isFullscreen() { diff --git a/src/newt/classes/com/jogamp/newt/util/MonitorMode.java b/src/newt/classes/com/jogamp/newt/util/MonitorMode.java deleted file mode 100644 index 8104f207a..000000000 --- a/src/newt/classes/com/jogamp/newt/util/MonitorMode.java +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Copyright 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ - -package com.jogamp.newt.util; - -import javax.media.nativewindow.util.*; - -/** Immutable MonitorMode Class, consisting of it's read only components:
    - *
      - *
    • {@link javax.media.nativewindow.util.SurfaceSize} surface memory size
    • - *
    • {@link javax.media.nativewindow.util.DimensionImmutable} size in [mm]
    • - *
    • refresh rate
    • - *
    - */ -public class MonitorMode { - SurfaceSize surfaceSize; - DimensionImmutable screenSizeMM; // in [mm] - int refreshRate; - - public MonitorMode(SurfaceSize surfaceSize, DimensionImmutable screenSizeMM, int refreshRate) { - // Don't validate screenSizeMM and refreshRate, since they may not be supported by the OS - if(null==surfaceSize) { - throw new IllegalArgumentException("surfaceSize must be set ("+surfaceSize+")"); - } - this.surfaceSize=surfaceSize; - this.screenSizeMM=screenSizeMM; - this.refreshRate=refreshRate; - } - - public final SurfaceSize getSurfaceSize() { - return surfaceSize; - } - - public final DimensionImmutable getScreenSizeMM() { - return screenSizeMM; - } - - public final int getRefreshRate() { - return refreshRate; - } - - public final String toString() { - return new String("[ "+surfaceSize+" x "+refreshRate+" Hz, "+screenSizeMM+" mm ]"); - } - - /** - * Checks whether two size objects are equal. Two instances - * of MonitorMode are equal if the three components - * surfaceSize and refreshRate - * are equal. screenSizeMM is kept out intentional to reduce the requirements for finding the current mode. - * @return true if the two dimensions are equal; - * otherwise false. - */ - public final boolean equals(Object obj) { - if (this == obj) { return true; } - if (obj instanceof MonitorMode) { - MonitorMode p = (MonitorMode)obj; - return getSurfaceSize().equals(p.getSurfaceSize()) && - /* getScreenSizeMM().equals(p.getScreenSizeMM()) && */ - getRefreshRate() == p.getRefreshRate() ; - } - return false; - } - - /** - * returns a hash code over surfaceSize and refreshRate. - * screenSizeMM is kept out intentional to reduce the requirements for finding the current mode. - */ - public final int hashCode() { - // 31 * x == (x << 5) - x - int hash = 31 + getSurfaceSize().hashCode(); - /* hash = ((hash << 5) - hash) + getScreenSizeMM().hashCode(); */ - hash = ((hash << 5) - hash) + getRefreshRate(); - return hash; - } -} - diff --git a/src/newt/classes/com/jogamp/newt/util/MonitorModeUtil.java b/src/newt/classes/com/jogamp/newt/util/MonitorModeUtil.java new file mode 100644 index 000000000..16ffe754f --- /dev/null +++ b/src/newt/classes/com/jogamp/newt/util/MonitorModeUtil.java @@ -0,0 +1,247 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.newt.util; + +import com.jogamp.newt.MonitorMode; + +import java.util.ArrayList; +import java.util.List; +import javax.media.nativewindow.util.DimensionImmutable; +import javax.media.nativewindow.util.SurfaceSize; + +/** + * Convenient {@link com.jogamp.newt.MonitorMode} utility methods, + * filters etc. + */ +public class MonitorModeUtil { + + public static int getIndex(List monitorModes, MonitorMode search) { + return monitorModes.indexOf(search); + } + + public static int getIndexByHashCode(List monitorModes, MonitorMode search) { + if( null!=monitorModes && monitorModes.size()>0 ) { + for (int i=0; i monitorModes, MonitorMode.SizeAndRRate sizeAndRate, int modeId, int rotation) { + if( null!=monitorModes && monitorModes.size()>0 ) { + for (int i=0; i filterBySurfaceSize(List monitorModes, SurfaceSize surfaceSize) { + final List out = new ArrayList(); + if( null!=monitorModes && monitorModes.size()>0 ) { + for (int i=0; null!=monitorModes && i filterByRotation(List monitorModes, int rotation) { + final List out = new ArrayList(); + if( null!=monitorModes && monitorModes.size()>0 ) { + for (int i=0; null!=monitorModes && i filterByBpp(List monitorModes, int bitsPerPixel) { + final List out = new ArrayList(); + if( null!=monitorModes && monitorModes.size()>0 ) { + for (int i=0; null!=monitorModes && i filterByFlags(List monitorModes, int flags) { + final List out = new ArrayList(); + if( null!=monitorModes && monitorModes.size()>0 ) { + for (int i=0; null!=monitorModes && i filterByResolution(List monitorModes, DimensionImmutable resolution) { + final List out = new ArrayList(); + if( null!=monitorModes && monitorModes.size()>0 ) { + final int resolution_sq = resolution.getHeight()*resolution.getWidth(); + int mode_dsq=Integer.MAX_VALUE, mode_dsq_idx=0; + + for (int i=0; null!=monitorModes && i filterByRate(List monitorModes, float refreshRate) { + final List out = new ArrayList(); + if( null!=monitorModes && monitorModes.size()>0 ) { + float mode_dr = Float.MAX_VALUE; + int mode_dr_idx = -1; + for (int i=0; null!=monitorModes && i getHighestAvailableBpp(List monitorModes) { + if( null!=monitorModes && monitorModes.size()>0 ) { + int highest = -1; + for (int i=0; null!=monitorModes && i < monitorModes.size(); i++) { + final MonitorMode mode = monitorModes.get(i); + final int bpp = mode.getSurfaceSize().getBitsPerPixel(); + if (bpp > highest) { + highest = bpp; + } + } + return filterByBpp(monitorModes, highest); + } + return new ArrayList(); + } + + /** + * + * @param monitorModes + * @return modes with highest available refresh rate. May return zero sized list for non. + */ + public static List getHighestAvailableRate(List monitorModes) { + if( null!=monitorModes && monitorModes.size()>0 ) { + float highest = -1; + for (int i=0; null!=monitorModes && i < monitorModes.size(); i++) { + final MonitorMode mode = monitorModes.get(i); + final float rate = mode.getRefreshRate(); + if (rate > highest) { + highest = rate; + } + } + return filterByRate(monitorModes, highest); + } + return new ArrayList(); + } + +} diff --git a/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java b/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java deleted file mode 100644 index 93797c5fb..000000000 --- a/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java +++ /dev/null @@ -1,341 +0,0 @@ -/** - * Copyright 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ - -package com.jogamp.newt.util; - -import com.jogamp.common.util.ArrayHashSet; -import com.jogamp.newt.ScreenMode; -import java.util.ArrayList; -import java.util.List; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.DimensionImmutable; -import javax.media.nativewindow.util.SurfaceSize; - -/** - * Convenient {@link com.jogamp.newt.ScreenMode} utility methods, - * filters etc. - */ -public class ScreenModeUtil { - /** WARNING: must be synchronized with ScreenMode.h, native implementation - * 2: width and height - */ - public static final int NUM_RESOLUTION_PROPERTIES = 2; - - /** WARNING: must be synchronized with ScreenMode.h, native implementation - * 1: bpp - */ - public static final int NUM_SURFACE_SIZE_PROPERTIES = 1; - - /** WARNING: must be synchronized with ScreenMode.h, native implementation - * 3: ScreenSizeMM[width, height], refresh-rate - */ - public static final int NUM_MONITOR_MODE_PROPERTIES = 3; - - /** WARNING: must be synchronized with ScreenMode.h, native implementation - * 1: rotation, native_mode_id - */ - public static final int NUM_SCREEN_MODE_PROPERTIES = 1; - - /** WARNING: must be synchronized with ScreenMode.h, native implementation - * count + all the above - */ - public static final int NUM_SCREEN_MODE_PROPERTIES_ALL = 8; - - public static int getIndex(List screenModes, ScreenMode search) { - return screenModes.indexOf(search); - } - - public static int getIndexByHashCode(List screenModes, ScreenMode search) { - for (int i=0; null!=screenModes && i filterByResolution(List screenModes, DimensionImmutable resolution) { - if(null==screenModes || screenModes.size()==0) { - return null; - } - List out = new ArrayList(); - int resolution_sq = resolution.getHeight()*resolution.getWidth(); - int sm_dsq=resolution_sq, sm_dsq_idx=0; - - for (int i=0; null!=screenModes && i0) { - return out; - } - // nearest .. - resolution = screenModes.get(sm_dsq_idx).getMonitorMode().getSurfaceSize().getResolution(); - return filterByResolution(screenModes, resolution); - } - - public static List filterBySurfaceSize(List screenModes, SurfaceSize surfaceSize) { - if(null==screenModes || screenModes.size()==0) { - return null; - } - List out = new ArrayList(); - for (int i=0; null!=screenModes && i0 ? out : null; - } - - public static List filterByRotation(List screenModes, int rotation) { - if(null==screenModes || screenModes.size()==0) { - return null; - } - List out = new ArrayList(); - for (int i=0; null!=screenModes && i0 ? out : null; - } - - public static List filterByBpp(List screenModes, int bitsPerPixel) { - if(null==screenModes || screenModes.size()==0) { - return null; - } - List out = new ArrayList(); - for (int i=0; null!=screenModes && i0 ? out : null; - } - - /** - * - * @param screenModes - * @param refreshRate - * @return modes with nearest refreshRate, or matching ones - */ - public static List filterByRate(List screenModes, int refreshRate) { - if(null==screenModes || screenModes.size()==0) { - return null; - } - int sm_dr = refreshRate; - int sm_dr_idx = -1; - List out = new ArrayList(); - for (int i=0; null!=screenModes && i0) { - return out; - } - refreshRate = screenModes.get(sm_dr_idx).getMonitorMode().getRefreshRate(); - return filterByRate(screenModes, refreshRate); - } - - public static List getHighestAvailableBpp(List screenModes) { - if(null==screenModes || screenModes.size()==0) { - return null; - } - int highest = -1; - for (int i=0; null!=screenModes && i < screenModes.size(); i++) { - ScreenMode sm = screenModes.get(i); - int bpp = sm.getMonitorMode().getSurfaceSize().getBitsPerPixel(); - if (bpp > highest) { - highest = bpp; - } - } - return filterByBpp(screenModes, highest); - } - - public static List getHighestAvailableRate(List screenModes) { - if(null==screenModes || screenModes.size()==0) { - return null; - } - int highest = -1; - for (int i=0; null!=screenModes && i < screenModes.size(); i++) { - ScreenMode sm = screenModes.get(i); - int rate = sm.getMonitorMode().getRefreshRate(); - if (rate > highest) { - highest = rate; - } - } - return filterByRate(screenModes, highest); - } - - /** WARNING: must be synchronized with ScreenMode.h, native implementation */ - public static DimensionImmutable streamInResolution(int[] resolutionProperties, int offset) { - Dimension resolution = new Dimension(resolutionProperties[offset++], resolutionProperties[offset++]); - return resolution; - } - - /** WARNING: must be synchronized with ScreenMode.h, native implementation */ - public static SurfaceSize streamInSurfaceSize(DimensionImmutable resolution, int[] sizeProperties, int offset) { - SurfaceSize surfaceSize = new SurfaceSize(resolution, sizeProperties[offset++]); - return surfaceSize; - } - - /** WARNING: must be synchronized with ScreenMode.h, native implementation */ - public static MonitorMode streamInMonitorMode(SurfaceSize surfaceSize, DimensionImmutable screenSizeMM, int[] monitorProperties, int offset) { - int refreshRate = monitorProperties[offset++]; - return new MonitorMode(surfaceSize, screenSizeMM, refreshRate); - } - - /** WARNING: must be synchronized with ScreenMode.h, native implementation */ - public static ScreenMode streamInScreenMode(MonitorMode monitorMode, int[] modeProperties, int offset) { - int rotation = modeProperties[offset++]; - return new ScreenMode(monitorMode, rotation); - } - - /** - * WARNING: must be synchronized with ScreenMode.h, native implementation - * - * @param modeProperties the input data - * @param offset the offset to the input data - * @return ScreenMode element matching the input modeProperties, - * or null if input could not be processed. - */ - public static ScreenMode streamIn(int[] modeProperties, int offset) { - return streamInImpl(null, null, null, null, null, modeProperties, offset); - } - - /** - * WARNING: must be synchronized with ScreenMode.h, native implementation - * - * @param resolutionPool hash array of unique resolutions, no duplicates - * @param surfaceSizePool hash array of unique SurfaceSize, no duplicates - * @param monitorModePool hash array of unique MonitorMode, no duplicates - * @param screenModePool hash array of unique ScreenMode, no duplicates - * @param modeProperties the input data - * @param offset the offset to the input data - * @return index of the identical (old or new) ScreenMode element in screenModePool, - * matching the input modeProperties, or -1 if input could not be processed. - */ - public static int streamIn(ArrayHashSet resolutionPool, - ArrayHashSet surfaceSizePool, - ArrayHashSet screenSizeMMPool, - ArrayHashSet monitorModePool, - ArrayHashSet screenModePool, - int[] modeProperties, int offset) { - ScreenMode screenMode = streamInImpl(resolutionPool, surfaceSizePool, screenSizeMMPool, monitorModePool, screenModePool, - modeProperties, offset); - return screenModePool.indexOf(screenMode); - } - - - private static ScreenMode streamInImpl(ArrayHashSet resolutionPool, - ArrayHashSet surfaceSizePool, - ArrayHashSet screenSizeMMPool, - ArrayHashSet monitorModePool, - ArrayHashSet screenModePool, - int[] modeProperties, int offset) { - int count = modeProperties[offset]; - if(NUM_SCREEN_MODE_PROPERTIES_ALL != count) { - throw new RuntimeException("NUM_SCREEN_MODE_PROPERTIES should be "+NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+count+", len "+(modeProperties.length-offset)); - } - if(NUM_SCREEN_MODE_PROPERTIES_ALL > modeProperties.length-offset) { - throw new RuntimeException("properties array too short, should be >= "+NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+(modeProperties.length-offset)); - } - offset++; - DimensionImmutable resolution = ScreenModeUtil.streamInResolution(modeProperties, offset); - offset += ScreenModeUtil.NUM_RESOLUTION_PROPERTIES; - if(null!=resolutionPool) { - resolution = resolutionPool.getOrAdd(resolution); - } - - SurfaceSize surfaceSize = ScreenModeUtil.streamInSurfaceSize(resolution, modeProperties, offset); - offset += ScreenModeUtil.NUM_SURFACE_SIZE_PROPERTIES; - if(null!=surfaceSizePool) { - surfaceSize = surfaceSizePool.getOrAdd(surfaceSize); - } - - DimensionImmutable screenSizeMM = ScreenModeUtil.streamInResolution(modeProperties, offset); - offset += ScreenModeUtil.NUM_RESOLUTION_PROPERTIES; - if(null!=screenSizeMMPool) { - screenSizeMM = screenSizeMMPool.getOrAdd(screenSizeMM); - } - - MonitorMode monitorMode = ScreenModeUtil.streamInMonitorMode(surfaceSize, screenSizeMM, modeProperties, offset); - offset += ScreenModeUtil.NUM_MONITOR_MODE_PROPERTIES - ScreenModeUtil.NUM_RESOLUTION_PROPERTIES; - if(null!=monitorModePool) { - monitorMode = monitorModePool.getOrAdd(monitorMode); - } - - ScreenMode screenMode = ScreenModeUtil.streamInScreenMode(monitorMode, modeProperties, offset); - if(null!=screenModePool) { - screenMode = screenModePool.getOrAdd(screenMode); - } - return screenMode; - } - - /** WARNING: must be synchronized with ScreenMode.h, native implementation */ - public static int[] streamOut (ScreenMode screenMode) { - int[] data = new int[NUM_SCREEN_MODE_PROPERTIES_ALL]; - int idx=0; - data[idx++] = NUM_SCREEN_MODE_PROPERTIES_ALL; - data[idx++] = screenMode.getMonitorMode().getSurfaceSize().getResolution().getWidth(); - data[idx++] = screenMode.getMonitorMode().getSurfaceSize().getResolution().getHeight(); - data[idx++] = screenMode.getMonitorMode().getSurfaceSize().getBitsPerPixel(); - data[idx++] = screenMode.getMonitorMode().getScreenSizeMM().getWidth(); - data[idx++] = screenMode.getMonitorMode().getScreenSizeMM().getHeight(); - data[idx++] = screenMode.getMonitorMode().getRefreshRate(); - data[idx++] = screenMode.getRotation(); - if(NUM_SCREEN_MODE_PROPERTIES_ALL != idx) { - throw new InternalError("wrong number of attributes: got "+idx+" != should "+NUM_SCREEN_MODE_PROPERTIES_ALL); - } - return data; - } - -} diff --git a/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java b/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java new file mode 100644 index 000000000..96daed54a --- /dev/null +++ b/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java @@ -0,0 +1,147 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.newt; + +import javax.media.nativewindow.util.DimensionImmutable; +import javax.media.nativewindow.util.Rectangle; + +import com.jogamp.common.util.ArrayHashSet; +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; +import com.jogamp.newt.Screen; + +public class MonitorDeviceImpl extends MonitorDevice { + + public MonitorDeviceImpl(ScreenImpl screen, int nativeId, DimensionImmutable sizeMM, Rectangle viewport, MonitorMode currentMode, ArrayHashSet supportedModes) { + super(screen, nativeId, sizeMM, viewport, currentMode, supportedModes); + } + + @Override + public final MonitorMode queryCurrentMode() { + final ScreenImpl screenImpl = (ScreenImpl)screen; + final ScreenMonitorState sms = screenImpl.getScreenMonitorStatus(true); + sms.lock(); + try { + final MonitorMode mm0 = screenImpl.queryCurrentMonitorModeIntern(this); + if(null == mm0) { + throw new InternalError("getCurrentMonitorModeIntern() == null"); + } + MonitorMode mmU = supportedModes.get(mm0); // unified instance + if( null == mmU ) { + // add new mode avoiding exception! + mmU = sms.getMonitorModes().getOrAdd(mm0); + mmU = supportedModes.getOrAdd(mmU); + if( Screen.DEBUG ) { + System.err.println("Adding new mode: "+mm0+" -> "+mmU); + } + } + // if mode has changed somehow, update it .. + if( getCurrentMode().hashCode() != mmU.hashCode() ) { + setCurrentModeValue(mmU); + sms.fireScreenModeChanged(this, mmU, true); + } + return mmU; + } finally { + sms.unlock(); + } + } + + @Override + public final boolean setCurrentMode(MonitorMode mode) { + if(Screen.DEBUG) { + System.err.println("Screen.setCurrentScreenMode.0: "+this+" -> "+mode); + } + final ScreenImpl screenImpl = (ScreenImpl)screen; + final ScreenMonitorState sms = screenImpl.getScreenMonitorStatus(true); + sms.lock(); + try { + final MonitorMode mmC = queryCurrentMode(); + final MonitorMode mmU = supportedModes.get(mode); // unify via value hash + if( null == mmU ) { + throw new IllegalArgumentException("Given mode not in set of modes. Current mode "+mode+", "+this); + } + if( mmU.equals( mmC ) ) { + if(Screen.DEBUG) { + System.err.println("Screen.setCurrentScreenMode: 0.0 is-current (skip) "+mmU+" == "+mmC); + } + return true; + } + final long tStart; + if(Screen.DEBUG) { + tStart = System.nanoTime(); + } else { + tStart = 0; + } + + sms.fireScreenModeChangeNotify(this, mmU); + if(Screen.DEBUG) { + System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): fireScreenModeChangeNotify() "+mmU); + } + + boolean success = screenImpl.setCurrentMonitorModeImpl(this, mmU); + if(success) { + if(Screen.DEBUG) { + System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentScreenModeImpl() "+mmU+", success(1): "+success); + } + } else { + // 2nd attempt validate! + final MonitorMode queriedCurrent = queryCurrentMode(); // may fireScreenModeChanged(..) if successful and differs! + success = queriedCurrent.hashCode() == mmU.hashCode() ; + if(Screen.DEBUG) { + System.err.println("Screen.setCurrentScreenMode.2: queried "+queriedCurrent); + System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentScreenModeImpl() "+mmU+", success(2): "+success); + } + } + if( success ) { + setCurrentModeValue(mmU); + modeChanged = !isOriginalMode(); + } + sms.fireScreenModeChanged(this, mmU, success); + if(Screen.DEBUG) { + System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): X.X "+this+", success: "+success); + } + return success; + } finally { + sms.unlock(); + } + } + + private final void setCurrentModeValue(MonitorMode currentMode) { + this.currentMode = currentMode; + } + + /* pp */ final void setViewportValue(Rectangle viewport) { + this.viewport = viewport; + } + + /* pp */ ArrayHashSet getSupportedModesImpl() { + return supportedModes; + } + +} \ No newline at end of file diff --git a/src/newt/classes/jogamp/newt/MonitorModeProps.java b/src/newt/classes/jogamp/newt/MonitorModeProps.java new file mode 100644 index 000000000..820807e15 --- /dev/null +++ b/src/newt/classes/jogamp/newt/MonitorModeProps.java @@ -0,0 +1,355 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.newt; + +import com.jogamp.common.util.ArrayHashSet; +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; + +import java.util.List; +import javax.media.nativewindow.util.Dimension; +import javax.media.nativewindow.util.DimensionImmutable; +import javax.media.nativewindow.util.Rectangle; +import javax.media.nativewindow.util.SurfaceSize; + +import jogamp.newt.MonitorDeviceImpl; +import jogamp.newt.ScreenImpl; + +/** + * Encodes and decodes {@link MonitorMode} and {@link MonitorDevice} properties. + */ +public class MonitorModeProps { + /** WARNING: must be synchronized with ScreenMode.h, native implementation + * 2: width, height + */ + public static final int NUM_RESOLUTION_PROPERTIES = 2; + + /** WARNING: must be synchronized with ScreenMode.h, native implementation + * 1: bpp + */ + public static final int NUM_SURFACE_SIZE_PROPERTIES = 1; + + /** WARNING: must be synchronized with ScreenMode.h, native implementation + * 2: refresh-rate (Hz*100), flags + */ + public static final int NUM_SIZEANDRATE_PROPERTIES = 2; + + /** WARNING: must be synchronized with ScreenMode.h, native implementation + * 2: id, rotation + */ + public static final int NUM_MONITOR_MODE_PROPERTIES = 2; + + /** WARNING: must be synchronized with ScreenMode.h, native implementation + * count + all the above + */ + public static final int NUM_MONITOR_MODE_PROPERTIES_ALL = 8; + + public static final int IDX_MONITOR_MODE_BPP = 1 // count + + MonitorModeProps.NUM_RESOLUTION_PROPERTIES + ; + public static final int IDX_MONITOR_MODE_ROT = 1 // count + + MonitorModeProps.NUM_RESOLUTION_PROPERTIES + + MonitorModeProps.NUM_SURFACE_SIZE_PROPERTIES + + MonitorModeProps.NUM_SIZEANDRATE_PROPERTIES + + 1 // id of MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES + ; + + /** WARNING: must be synchronized with ScreenMode.h, native implementation + * 10: count + id, ScreenSizeMM[width, height], rotated Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+ + */ + public static final int MIN_MONITOR_DEVICE_PROPERTIES = 11; + + public static final int IDX_MONITOR_DEVICE_VIEWPORT = 1 // count + + 1 // native mode + + MonitorModeProps.NUM_RESOLUTION_PROPERTIES // sizeMM + ; + + public static class Cache { + public final ArrayHashSet resolutions = new ArrayHashSet(); + public final ArrayHashSet surfaceSizes = new ArrayHashSet(); + public final ArrayHashSet sizeAndRates = new ArrayHashSet(); + public final ArrayHashSet monitorModes = new ArrayHashSet(); + public final ArrayHashSet monitorDevices = new ArrayHashSet(); + } + + /** WARNING: must be synchronized with ScreenMode.h, native implementation */ + private static DimensionImmutable streamInResolution(int[] resolutionProperties, int offset) { + Dimension resolution = new Dimension(resolutionProperties[offset++], resolutionProperties[offset++]); + return resolution; + } + + /** WARNING: must be synchronized with ScreenMode.h, native implementation */ + private static SurfaceSize streamInSurfaceSize(DimensionImmutable resolution, int[] sizeProperties, int offset) { + SurfaceSize surfaceSize = new SurfaceSize(resolution, sizeProperties[offset++]); + return surfaceSize; + } + + /** WARNING: must be synchronized with ScreenMode.h, native implementation */ + private static MonitorMode.SizeAndRRate streamInSizeAndRRate(SurfaceSize surfaceSize, int[] sizeAndRRateProperties, int offset) { + final float refreshRate = sizeAndRRateProperties[offset++]/100.0f; + final int flags = sizeAndRRateProperties[offset++]; + return new MonitorMode.SizeAndRRate(surfaceSize, refreshRate, flags); + } + + /** WARNING: must be synchronized with ScreenMode.h, native implementation */ + private static MonitorMode streamInMonitorMode0(MonitorMode.SizeAndRRate sizeAndRate, int[] modeProperties, int offset) { + final int id = modeProperties[offset++]; + final int rotation = modeProperties[offset++]; + return new MonitorMode(id, sizeAndRate, rotation); + } + + /** + * WARNING: must be synchronized with ScreenMode.h, native implementation + * + * @param mode_idx if not null and cache is given, returns the index of resulting {@link MonitorMode} within {@link Cache#monitorModes}. + * @param cache optional hash arrays of unique {@link MonitorMode} components and {@link MonitorDevice}s, allowing to avoid duplicates + * @param modeProperties the input data + * @param offset the offset to the input data + * @return {@link MonitorMode} of the identical (old or new) element in {@link Cache#monitorModes}, + * matching the input modeProperties, or null if input could not be processed. + */ + public static MonitorMode streamInMonitorMode(int[] mode_idx, Cache cache, + int[] modeProperties, int offset) { + final int count = modeProperties[offset]; + if(NUM_MONITOR_MODE_PROPERTIES_ALL != count) { + throw new RuntimeException("property count should be "+NUM_MONITOR_MODE_PROPERTIES_ALL+", but is "+count+", len "+(modeProperties.length-offset)); + } + if(NUM_MONITOR_MODE_PROPERTIES_ALL > modeProperties.length-offset) { + throw new RuntimeException("properties array too short, should be >= "+NUM_MONITOR_MODE_PROPERTIES_ALL+", is "+(modeProperties.length-offset)); + } + offset++; + DimensionImmutable resolution = MonitorModeProps.streamInResolution(modeProperties, offset); + offset += MonitorModeProps.NUM_RESOLUTION_PROPERTIES; + if(null!=cache) { + resolution = cache.resolutions.getOrAdd(resolution); + } + + SurfaceSize surfaceSize = MonitorModeProps.streamInSurfaceSize(resolution, modeProperties, offset); + offset += MonitorModeProps.NUM_SURFACE_SIZE_PROPERTIES; + if(null!=cache) { + surfaceSize = cache.surfaceSizes.getOrAdd(surfaceSize); + } + + MonitorMode.SizeAndRRate sizeAndRate = MonitorModeProps.streamInSizeAndRRate(surfaceSize, modeProperties, offset); + offset += MonitorModeProps.NUM_SIZEANDRATE_PROPERTIES; + if(null!=cache) { + sizeAndRate = cache.sizeAndRates.getOrAdd(sizeAndRate); + } + + MonitorMode monitorMode = MonitorModeProps.streamInMonitorMode0(sizeAndRate, modeProperties, offset); + if(null!=cache) { + monitorMode = cache.monitorModes.getOrAdd(monitorMode); + } + if( null != mode_idx && null!=cache) { + int _modeIdx = cache.monitorModes.indexOf(monitorMode); + if( 0 > _modeIdx ) { + throw new InternalError("Invalid index of current unified mode "+monitorMode); + } + mode_idx[0] = _modeIdx; + } + return monitorMode; + } + + /** WARNING: must be synchronized with ScreenMode.h, native implementation */ + public static int[] streamOutMonitorMode (MonitorMode monitorMode) { + int[] data = new int[NUM_MONITOR_MODE_PROPERTIES_ALL]; + int idx=0; + data[idx++] = NUM_MONITOR_MODE_PROPERTIES_ALL; + data[idx++] = monitorMode.getSurfaceSize().getResolution().getWidth(); + data[idx++] = monitorMode.getSurfaceSize().getResolution().getHeight(); + data[idx++] = monitorMode.getSurfaceSize().getBitsPerPixel(); + data[idx++] = (int)(monitorMode.getRefreshRate()*100.0f); // Hz*100 + data[idx++] = monitorMode.getFlags(); + data[idx++] = monitorMode.getId(); + data[idx++] = monitorMode.getRotation(); + if(NUM_MONITOR_MODE_PROPERTIES_ALL != idx) { + throw new InternalError("wrong number of attributes: got "+idx+" != should "+NUM_MONITOR_MODE_PROPERTIES_ALL); + } + return data; + } + + /** + * WARNING: must be synchronized with ScreenMode.h, native implementation + *

    + * Note: This variant only works for impl. w/ a unique mode key pair modeId, rotation. + *

    + * @param mode_idx if not null, returns the index of resulting {@link MonitorDevice} within {@link Cache#monitorDevices}. + * @param cache hash arrays of unique {@link MonitorMode} components and {@link MonitorDevice}s, allowing to avoid duplicates + * @param modeProperties the input data + * @param offset the offset to the input data + * @return {@link MonitorDevice} of the identical (old or new) element in {@link Cache#monitorDevices}, + * matching the input modeProperties, or null if input could not be processed. + */ + public static MonitorDevice streamInMonitorDevice(int[] monitor_idx, Cache cache, ScreenImpl screen, int[] monitorProperties, int offset) { + // min 11: count, id, ScreenSizeMM[width, height], Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+ + final int count = monitorProperties[offset]; + if(MIN_MONITOR_DEVICE_PROPERTIES > count) { + throw new RuntimeException("property count should be >= "+MIN_MONITOR_DEVICE_PROPERTIES+", but is "+count+", len "+(monitorProperties.length-offset)); + } + if(MIN_MONITOR_DEVICE_PROPERTIES > monitorProperties.length-offset) { + throw new RuntimeException("properties array too short (min), should be >= "+MIN_MONITOR_DEVICE_PROPERTIES+", is "+(monitorProperties.length-offset)); + } + if(count > monitorProperties.length-offset) { + throw new RuntimeException("properties array too short (count), should be >= "+count+", is "+(monitorProperties.length-offset)); + } + final int limit = offset + count; + offset++; + final List allMonitorModes = cache.monitorModes.getData(); + final int id = monitorProperties[offset++]; + final DimensionImmutable sizeMM = streamInResolution(monitorProperties, offset); offset+=NUM_RESOLUTION_PROPERTIES; + final Rectangle viewport = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]); + final MonitorMode currentMode; + { + final int modeId = monitorProperties[offset++]; + final int rotation = monitorProperties[offset++]; + currentMode = getByNativeIdAndRotation(allMonitorModes, modeId, rotation); + } + final ArrayHashSet supportedModes = new ArrayHashSet(); + while( offset < limit ) { + final int modeId = monitorProperties[offset++]; + for (int i=0; i _monitorIdx ) { + throw new InternalError("Invalid index of current unified mode "+monitorDevice); + } + monitor_idx[0] = _monitorIdx; + } + return monitorDevice; + } + private static MonitorMode getByNativeIdAndRotation(List monitorModes, int modeId, int rotation) { + if( null!=monitorModes && monitorModes.size()>0 ) { + for (int i=0; i + * This variant expects count to be {@link MIN_MONITOR_DEVICE_PROPERTIES} - 1 - {@link NUM_MONITOR_MODE_PROPERTIES}, + * due to lack of supported mode and current mode. + *

    + * + * @param mode_idx if not null, returns the index of resulting {@link MonitorDevice} within {@link Cache#monitorDevices}. + * @param cache hash arrays of unique {@link MonitorMode} components and {@link MonitorDevice}s, allowing to avoid duplicates + * @param supportedModes pre-assembled list of supported {@link MonitorMode}s from cache. + * @param currentMode pre-fetched current {@link MonitorMode}s from cache. + * @param modeProperties the input data minus supported modes! + * @param offset the offset to the input data + * @return {@link MonitorDevice} of the identical (old or new) element in {@link Cache#monitorDevices}, + * matching the input modeProperties, or null if input could not be processed. + */ + public static MonitorDevice streamInMonitorDevice(int[] monitor_idx, Cache cache, ScreenImpl screen, ArrayHashSet supportedModes, MonitorMode currentMode, int[] monitorProperties, int offset) { + // min 11: count, id, ScreenSizeMM[width, height], Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+ + final int count = monitorProperties[offset]; + if(MIN_MONITOR_DEVICE_PROPERTIES - 1 - NUM_MONITOR_MODE_PROPERTIES != count) { + throw new RuntimeException("property count should be == "+(MIN_MONITOR_DEVICE_PROPERTIES-1-NUM_MONITOR_MODE_PROPERTIES)+", but is "+count+", len "+(monitorProperties.length-offset)); + } + if(MIN_MONITOR_DEVICE_PROPERTIES - 1 - NUM_MONITOR_MODE_PROPERTIES > monitorProperties.length-offset) { + throw new RuntimeException("properties array too short (min), should be >= "+(MIN_MONITOR_DEVICE_PROPERTIES-1-NUM_MONITOR_MODE_PROPERTIES)+", is "+(monitorProperties.length-offset)); + } + if(count > monitorProperties.length-offset) { + throw new RuntimeException("properties array too short (count), should be >= "+count+", is "+(monitorProperties.length-offset)); + } + offset++; + final int id = monitorProperties[offset++]; + final DimensionImmutable sizeMM = streamInResolution(monitorProperties, offset); offset+=NUM_RESOLUTION_PROPERTIES; + final Rectangle viewport = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]); + MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, sizeMM, viewport, currentMode, supportedModes); + if(null!=cache) { + monitorDevice = cache.monitorDevices.getOrAdd(monitorDevice); + } + if( null != monitor_idx ) { + int _monitorIdx = cache.monitorDevices.indexOf(monitorDevice); + if( 0 > _monitorIdx ) { + throw new InternalError("Invalid index of current unified mode "+monitorDevice); + } + monitor_idx[0] = _monitorIdx; + } + return monitorDevice; + } + + /** WARNING: must be synchronized with ScreenMode.h, native implementation */ + public static int[] streamOutMonitorDevice (MonitorDevice monitorDevice) { + // min 11: count, id, ScreenSizeMM[width, height], Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+ + int supportedModeCount = monitorDevice.getSupportedModes().size(); + if( 0 == supportedModeCount ) { + throw new RuntimeException("no supported modes: "+monitorDevice); + } + int[] data = new int[MIN_MONITOR_DEVICE_PROPERTIES + supportedModeCount - 1]; + int idx=0; + data[idx++] = data.length; + data[idx++] = monitorDevice.getId(); + data[idx++] = monitorDevice.getSizeMM().getWidth(); + data[idx++] = monitorDevice.getSizeMM().getHeight(); + data[idx++] = monitorDevice.getViewport().getX(); + data[idx++] = monitorDevice.getViewport().getY(); + data[idx++] = monitorDevice.getViewport().getWidth(); + data[idx++] = monitorDevice.getViewport().getHeight(); + data[idx++] = monitorDevice.getCurrentMode().getId(); + data[idx++] = monitorDevice.getCurrentMode().getRotation(); + final List supportedModes = monitorDevice.getSupportedModes(); + for(int i=0; i monitors) { + return false; // nop + } + + protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) { sizeChanged(false, width, height, false); if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) { diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java index 1282e5dc5..4d20fdb83 100644 --- a/src/newt/classes/jogamp/newt/ScreenImpl.java +++ b/src/newt/classes/jogamp/newt/ScreenImpl.java @@ -43,22 +43,19 @@ import java.util.List; import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.DimensionImmutable; -import javax.media.nativewindow.util.Point; -import javax.media.nativewindow.util.SurfaceSize; - +import javax.media.nativewindow.util.Rectangle; +import javax.media.nativewindow.util.RectangleImmutable; import com.jogamp.common.util.ArrayHashSet; -import com.jogamp.common.util.IntIntHashMap; import com.jogamp.newt.Display; +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Screen; -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.event.ScreenModeListener; -import com.jogamp.newt.util.MonitorMode; -import com.jogamp.newt.util.ScreenModeUtil; +import com.jogamp.newt.event.MonitorEvent; +import com.jogamp.newt.event.MonitorModeListener; -public abstract class ScreenImpl extends Screen implements ScreenModeListener { +public abstract class ScreenImpl extends Screen implements MonitorModeListener { protected static final boolean DEBUG_TEST_SCREENMODE_DISABLED = Debug.isPropertyDefined("newt.test.Screen.disableScreenMode", true); public static final int default_sm_bpp = 32; @@ -73,11 +70,11 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { protected int hashCode; protected AbstractGraphicsScreen aScreen; protected int refCount; // number of Screen references by Window - protected Point vOrigin = new Point(0, 0); // virtual top-left origin - protected Dimension vSize = new Dimension(0, 0); // virtual rotated screen size + protected Rectangle vOriginSize = new Rectangle(0, 0, 0, 0); // virtual rotated screen origin and size protected static Dimension usrSize = null; // property values: newt.ws.swidth and newt.ws.sheight protected static volatile boolean usrSizeQueried = false; - private ArrayList referencedScreenModeListener = new ArrayList(); + private ArrayList referencedScreenModeListener = new ArrayList(); + private long tCreated; // creationTime static { @@ -160,10 +157,12 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { return true; } + @Override public int hashCode() { return hashCode; } + @Override public synchronized final void createNative() throws NativeWindowException { @@ -182,8 +181,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { throw new NativeWindowException("Screen.createNative() failed to instanciate an AbstractGraphicsScreen"); } - initScreenModeStatus(); - updateVirtualScreenOriginAndSize(); + initScreenMonitorState(); if(DEBUG) { System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+"), total "+ (System.nanoTime()-tCreated)/1e6 +"ms"); } @@ -191,10 +189,11 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { screensActive++; } } - ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName()); + ScreenMonitorState sms = ScreenMonitorState.getScreenMonitorState(this.getFQName()); sms.addListener(this); } + @Override public synchronized final void destroy() { releaseScreenModeStatus(); @@ -213,6 +212,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { display.removeReference(); } + @Override public synchronized final int addReference() throws NativeWindowException { if(DEBUG) { System.err.println("Screen.addReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount+1)); @@ -227,6 +227,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { return ++refCount; } + @Override public synchronized final int removeReference() { if(DEBUG) { System.err.println("Screen.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1)); @@ -240,6 +241,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { return refCount; } + @Override public synchronized final int getReferenceCount() { return refCount; } @@ -259,14 +261,20 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { /** * Stores the virtual origin and virtual rotated screen size. *

    - * This method is called after the ScreenMode has been set, + * This method is called after the ScreenMode has been set or changed, * hence you may utilize it. - *

    - * @param virtualOrigin the store for the virtual origin - * @param virtualSize the store for the virtual rotated size + *

    + *

    + * Default implementation uses the union of all monitor's viewport, + * calculated via {@link #unionOfMonitorViewportSize()}. + *

    + * @param vOriginSize storage for result */ - protected abstract void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize); + protected void calcVirtualScreenOriginAndSize(final Rectangle vOriginSize) { + unionOfMonitorViewportSize(vOriginSize); + } + @Override public final String getFQName() { return fqname; } @@ -275,258 +283,227 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { * Updates the rotated virtual ScreenSize using the native impl. */ protected void updateVirtualScreenOriginAndSize() { - getVirtualScreenOriginAndSize(vOrigin, vSize); - if(DEBUG) { - System.err.println("Detected virtual screen origin "+vOrigin+", size "+vSize); + if(null != usrSize ) { + vOriginSize.setX(0); + vOriginSize.setY(0); + vOriginSize.setWidth(usrSize.getWidth()); + vOriginSize.setHeight(usrSize.getHeight()); + if(DEBUG) { + System.err.println("User virtual screen viewport "+vOriginSize); + } + } else { + calcVirtualScreenOriginAndSize(vOriginSize); + if(DEBUG) { + System.err.println("Detected virtual screen viewport "+vOriginSize); + } } } + @Override public final Display getDisplay() { return display; } + @Override public final int getIndex() { return screen_idx; } + @Override public final AbstractGraphicsScreen getGraphicsScreen() { return aScreen; } + @Override public synchronized final boolean isNativeValid() { return null != aScreen; } - public int getX() { return vOrigin.getX(); } - public int getY() { return vOrigin.getY(); } - - public final int getWidth() { - return (null != usrSize) ? usrSize.getWidth() : vSize.getWidth(); - } - - public final int getHeight() { - return (null != usrSize) ? usrSize.getHeight() : vSize.getHeight(); - } + @Override + public final int getX() { return vOriginSize.getX(); } + @Override + public final int getY() { return vOriginSize.getY(); } + @Override + public final int getWidth() { return vOriginSize.getWidth(); } + @Override + public final int getHeight() { return vOriginSize.getHeight(); } + @Override + public final RectangleImmutable getViewport() { return vOriginSize; } @Override public String toString() { - return "NEWT-Screen["+getFQName()+", idx "+screen_idx+", refCount "+refCount+", "+getWidth()+"x"+getHeight()+", "+aScreen+", "+display+"]"; + return "NEWT-Screen["+getFQName()+", idx "+screen_idx+", refCount "+refCount+", vsize "+vOriginSize+", "+aScreen+", "+display+ + ", monitors: "+getMonitorDevices()+"]"; } - public final List getScreenModes() { - ArrayHashSet screenModes = getScreenModesOrig(); - if(null != screenModes && 0 < screenModes.size()) { - return screenModes.toArrayList(); - } - return null; + // + // MonitorDevice and MonitorMode + // + + /** + * To be implemented by the native specification.
    + * Is called within a thread safe environment.
    + * Is called only to collect the {@link MonitorMode}s and {@link MonitorDevice}s, usually at startup setting up modes.
    + *
    + * WARNING: must be synchronized with + *
      + *
    • {@link MonitorModeProps#NUM_SCREEN_MODE_PROPERTIES} and
    • + *
    • {@link MonitorModeProps#MIN_MONITOR_DEVICE_PROPERTIES}
    • + *
    , i.e. + *
      + *
    • {@link MonitorModeProps#streamInMonitorDevice(int[], jogamp.newt.MonitorModeProps.Cache, ScreenImpl, int[], int)}
    • + *
    • {@link MonitorModeProps#streamInMonitorDevice(int[], jogamp.newt.MonitorModeProps.Cache, ScreenImpl, ArrayHashSet, int[], int)}
    • + *
    • {@link MonitorModeProps#streamInMonitorMode(int[], jogamp.newt.MonitorModeProps.Cache, int[], int)}
    • + *
    + * @param cache memory pool caching the result + */ + protected abstract void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache); + + protected Rectangle getNativeMonitorDeviceViewportImpl(MonitorDevice monitor) { return null; } + + /** + * To be implemented by the native specification.
    + * Is called within a thread safe environment.
    + *

    + * Implementation shall not unify the result w/ monitor's supported modes or a locally + * saved {@link MonitorModeProps.Cache}, since caller will perform such tasks. + *

    + */ + protected abstract MonitorMode queryCurrentMonitorModeImpl(MonitorDevice monitor); + + /** + * To be implemented by the native specification.
    + * Is called within a thread safe environment.
    + */ + protected abstract boolean setCurrentMonitorModeImpl(MonitorDevice monitor, MonitorMode mode); + + @Override + public final List getMonitorModes() { + final ScreenMonitorState sms = getScreenMonitorStatus(false); + return null != sms ? sms.getMonitorModes().getData() : null; + } + + @Override + public final List getMonitorDevices() { + final ScreenMonitorState sms = getScreenMonitorStatus(false); + return null != sms ? sms.getMonitorDevices().getData() : null; } - private final ScreenModeStatus getScreenModeStatus(boolean throwException) { + final ScreenMonitorState getScreenMonitorStatus(boolean throwException) { final String key = this.getFQName(); - final ScreenModeStatus res = ScreenModeStatus.getScreenModeStatus(key); + final ScreenMonitorState res = ScreenMonitorState.getScreenMonitorState(key); if(null == res & throwException) { - throw new InternalError("ScreenModeStatus.getScreenModeStatus("+key+") == null"); + throw new InternalError("ScreenMonitorStatus.getScreenModeStatus("+key+") == null"); } return res; } - public ScreenMode getOriginalScreenMode() { - final ScreenModeStatus sms = getScreenModeStatus(false); - return ( null != sms ) ? sms.getOriginalScreenMode() : null ; - } - - public ScreenMode getCurrentScreenMode() { - ScreenMode smU = null; - final ScreenModeStatus sms = getScreenModeStatus(true); - final ScreenMode sm0 = getCurrentScreenModeIntern(); - if(null == sm0) { - throw new InternalError("getCurrentScreenModeImpl() == null"); + @Override + public void monitorModeChangeNotify(MonitorEvent me) { + if(DEBUG) { + System.err.println("monitorModeChangeNotify: "+me); } - sms.lock(); - try { - smU = sms.getScreenModes().getOrAdd(sm0); // unified instance, maybe new - - // if mode has changed somehow, update it .. - if( sms.getCurrentScreenMode().hashCode() != smU.hashCode() ) { - sms.fireScreenModeChanged(smU, true); - } - } finally { - sms.unlock(); + for(int i=0; i monitors = getMonitorDevices(); + for(int i=monitors.size()-1; i>=0; i--) { + final MonitorDeviceImpl monitor = (MonitorDeviceImpl) monitors.get(i); + final Rectangle newViewport = getNativeMonitorDeviceViewportImpl(monitor); + if( DEBUG ) { + System.err.println("Screen.updateMonitorViewport["+i+"]: "+monitor.getViewport()+" -> "+newViewport); } - - sms.fireScreenModeChangeNotify(smU); - if(DEBUG) { - System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): fireScreenModeChangeNotify() "+smU); + if( null != newViewport ) { + monitor.setViewportValue(newViewport); } - - success = setCurrentScreenModeImpl(smU); - if(success) { - if(DEBUG) { - System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentScreenModeImpl() "+smU+", success(1): "+success); - } - } else { - // 2nd attempt validate! - final ScreenMode queriedCurrent = getCurrentScreenMode(); // may fireScreenModeChanged(..) if successful and differs! - final ScreenMode smsCurrent = sms.getCurrentScreenMode(); - success = smsCurrent.hashCode() == smU.hashCode() && queriedCurrent.hashCode() == smU.hashCode() ; - if(DEBUG) { - System.err.println("Screen.setCurrentScreenMode.2: queried "+queriedCurrent); - System.err.println("Screen.setCurrentScreenMode.2: SMS "+smsCurrent); - System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentScreenModeImpl() "+smU+", success(2): "+success); - } - } - sms.fireScreenModeChanged(smU, success); - if(DEBUG) { - System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): X.X "+smU+", success: "+success); - } - } finally { - sms.unlock(); - } - return success; + } } - - public void screenModeChangeNotify(ScreenMode sm) { - for(int i=0; i getScreenModesOrig() { - ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName()); - if(null!=sms) { - return sms.getScreenModes(); - } - return null; - } - - /** ScreenModeStatus bridge to native implementation */ - protected final IntIntHashMap getScreenModesIdx2NativeIdx() { - ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName()); - if(null!=sms) { - return sms.getScreenModesIdx2NativeIdx(); - } - return null; - } - - /** - * To be implemented by the native specification.
    - * Is called within a thread safe environment.
    - * Is called only to collect the ScreenModes, usually at startup setting up modes.
    - *
    - * WARNING: must be synchronized with {@link com.jogamp.newt.util.ScreenModeUtil#NUM_SCREEN_MODE_PROPERTIES}, - * ie {@link com.jogamp.newt.util.ScreenModeUtil#streamIn(com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, int[], int)}
    - *
    - * Note: Additional 1st element is native mode id. - */ - protected int[] getScreenModeFirstImpl() { - return null; - } - - /** - * To be implemented by the native specification.
    - * Is called within a thread safe environment.
    - * Is called only to collect the ScreenModes, usually at startup setting up modes.
    - *
    - * WARNING: must be synchronized with {@link com.jogamp.newt.util.ScreenModeUtil#NUM_SCREEN_MODE_PROPERTIES}, - * ie {@link com.jogamp.newt.util.ScreenModeUtil#streamIn(com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, int[], int)}
    - *
    - * Note: Additional 1st element is native mode id. - */ - protected int[] getScreenModeNextImpl() { - return null; + + private final MonitorMode getVirtualMonitorMode(int modeId) { + final int[] props = new int[MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL]; + int i = 0; + props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL; + props[i++] = getWidth(); // width + props[i++] = getHeight(); // height + props[i++] = default_sm_bpp; + props[i++] = default_sm_rate * 100; + props[i++] = 0; // flags + props[i++] = modeId; + props[i++] = default_sm_rotation; + if( MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL != i ) { + throw new InternalError("XX"); + } + return MonitorModeProps.streamInMonitorMode(null, null, props, 0); } - - /** - * To be implemented by the native specification.
    - * Is called within a thread safe environment.
    - */ - protected ScreenMode getCurrentScreenModeImpl() { - return null; + + private final MonitorDevice getVirtualMonitorDevice(int monitorId, MonitorMode currentMode) { + int[] props = new int[MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES]; + int i = 0; + props[i++] = MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES; + props[i++] = monitorId; + props[i++] = default_sm_widthmm; + props[i++] = default_sm_heightmm; + props[i++] = 0; // rotated viewport x + props[i++] = 0; // rotated viewport y + props[i++] = currentMode.getRotatedWidth(); // rotated viewport width + props[i++] = currentMode.getRotatedHeight(); // rotated viewport height + props[i++] = currentMode.getId(); // current mode id + props[i++] = currentMode.getRotation(); + props[i++] = currentMode.getId(); // supported mode id #1 + if( MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES != i ) { + throw new InternalError("XX"); + } + return MonitorModeProps.streamInMonitorDevice(null, null, this, props, 0); } /** - * Utilizes {@link #getCurrentScreenModeImpl()}, if the latter returns null it uses + * Utilizes {@link #getCurrentMonitorModeImpl()}, if the latter returns null it uses * the current screen size and dummy values. */ - protected ScreenMode getCurrentScreenModeIntern() { - ScreenMode res; + protected final MonitorMode queryCurrentMonitorModeIntern(MonitorDevice monitor) { + MonitorMode res; if(DEBUG_TEST_SCREENMODE_DISABLED) { res = null; } else { - res = getCurrentScreenModeImpl(); + res = queryCurrentMonitorModeImpl(monitor); } if(null == res) { if( 0>=getWidth() || 0>=getHeight() ) { updateVirtualScreenOriginAndSize(); } - int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL]; - int i = 0; - props[i++] = 0; // set later for verification of iterator - props[i++] = getWidth(); // width - props[i++] = getHeight(); // height - props[i++] = default_sm_bpp; - props[i++] = default_sm_widthmm; - props[i++] = default_sm_heightmm; - props[i++] = default_sm_rate; - props[i++] = default_sm_rotation; - props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i; // count - res = ScreenModeUtil.streamIn(props, 0); + res = getVirtualMonitorMode(monitor.getCurrentMode().getId()); } return res; } - /** - * To be implemented by the native specification.
    - * Is called within a thread safe environment.
    - */ - protected boolean setCurrentScreenModeImpl(ScreenMode screenMode) { - return false; - } - - private ScreenModeStatus initScreenModeStatus() { + private final ScreenMonitorState initScreenMonitorState() { long t0; if(DEBUG) { t0 = System.nanoTime(); @@ -535,138 +512,139 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener { t0 = 0; } - ScreenModeStatus sms; - ScreenModeStatus.lockScreenModeStatus(); + boolean vScrnSizeUpdated = false; + ScreenMonitorState sms; + ScreenMonitorState.lockScreenMonitorState(); try { - sms = ScreenModeStatus.getScreenModeStatus(this.getFQName()); - if(null==sms) { - IntIntHashMap screenModesIdx2NativeIdx = new IntIntHashMap(); - final ScreenMode currentSM = getCurrentScreenModeIntern(); - if(null == currentSM) { - throw new InternalError("getCurrentScreenModeImpl() == null"); + sms = ScreenMonitorState.getScreenMonitorState(this.getFQName()); + if(null==sms) { + final MonitorModeProps.Cache cache = new MonitorModeProps.Cache(); + if( 0 >= collectNativeMonitorModes(cache) ) { + updateVirtualScreenOriginAndSize(); + vScrnSizeUpdated = true; + final MonitorMode mode = getVirtualMonitorMode(0); + cache.monitorModes.getOrAdd(mode); + final MonitorDevice monitor = getVirtualMonitorDevice(0, mode); + cache.monitorDevices.getOrAdd(monitor); } - - ArrayHashSet screenModes = collectNativeScreenModes(screenModesIdx2NativeIdx); - screenModes.getOrAdd(currentSM); if(DEBUG) { int i=0; - for(Iterator iter=screenModes.iterator(); iter.hasNext(); i++) { - System.err.println(i+": "+iter.next()); + for(Iterator iMode=cache.monitorModes.iterator(); iMode.hasNext(); i++) { + System.err.println("All["+i+"]: "+iMode.next()); + } + i=0; + for(Iterator iMonitor=cache.monitorDevices.iterator(); iMonitor.hasNext(); i++) { + final MonitorDevice crt = iMonitor.next(); + System.err.println("["+i+"]: "+crt); + int j=0; + for(Iterator iMode=crt.getSupportedModes().iterator(); iMode.hasNext(); j++) { + System.err.println("["+i+"]["+j+"]: "+iMode.next()); + } } } - - sms = new ScreenModeStatus(screenModes, screenModesIdx2NativeIdx); - ScreenMode originalScreenMode0 = screenModes.get(currentSM); // unify via value hash - if(null == originalScreenMode0) { - throw new RuntimeException(currentSM+" could not be hashed from ScreenMode list"); - } - sms.setOriginalScreenMode(originalScreenMode0); - ScreenModeStatus.mapScreenModeStatus(this.getFQName(), sms); + sms = new ScreenMonitorState(cache.monitorDevices, cache.monitorModes); + ScreenMonitorState.mapScreenMonitorState(this.getFQName(), sms); } } finally { - ScreenModeStatus.unlockScreenModeStatus(); + ScreenMonitorState.unlockScreenMonitorState(); } if(DEBUG) { System.err.println("Screen.initScreenModeStatus() END dt "+ (System.nanoTime()-t0)/1e6 +"ms"); } + if( !vScrnSizeUpdated ) { + updateVirtualScreenOriginAndSize(); + } + return sms; } - /** ignores bpp < 15 */ - private ArrayHashSet collectNativeScreenModes(IntIntHashMap screenModesIdx2NativeId) { - ArrayHashSet resolutionPool = new ArrayHashSet(); - ArrayHashSet surfaceSizePool = new ArrayHashSet(); - ArrayHashSet screenSizeMMPool = new ArrayHashSet(); - ArrayHashSet monitorModePool = new ArrayHashSet(); - ArrayHashSet screenModePool = new ArrayHashSet(); - - int[] smProps = null; - int num = 0; - final int idxBpp = 1 // native mode - + 1 // count - + ScreenModeUtil.NUM_RESOLUTION_PROPERTIES - + ScreenModeUtil.NUM_SURFACE_SIZE_PROPERTIES - - 1 ; // index 0 based - do { - if(DEBUG_TEST_SCREENMODE_DISABLED) { - smProps = null; - } else if(0 == num) { - smProps = getScreenModeFirstImpl(); - } else { - smProps = getScreenModeNextImpl(); - } - if(null != smProps && 0 < smProps.length && smProps[idxBpp] >= 15) { - int nativeId = smProps[0]; - int screenModeIdx = ScreenModeUtil.streamIn(resolutionPool, surfaceSizePool, screenSizeMMPool, - monitorModePool, screenModePool, smProps, 1); - if(DEBUG) { - System.err.println("ScreenImpl.collectNativeScreenModes: #"+num+": idx: "+nativeId+" native -> "+screenModeIdx+" newt"); + /** + * Returns the number of successful collected {@link MonitorDevice}s. + *

    + * Collects {@link MonitorDevice}s and {@link MonitorMode}s within the given cache. + *

    + */ + private final int collectNativeMonitorModes(MonitorModeProps.Cache cache) { + if(!DEBUG_TEST_SCREENMODE_DISABLED) { + collectNativeMonitorModesAndDevicesImpl(cache); + } + // filter out insufficient modes + for(int i=cache.monitorModes.size()-1; i>=0; i--) { + final MonitorMode mode = cache.monitorModes.get(i); + if( 16 > mode.getSurfaceSize().getBitsPerPixel() ) { + boolean keep = false; + for(int j=cache.monitorDevices.size()-1; !keep && j>=0; j--) { + final MonitorDevice monitor = cache.monitorDevices.get(j); + keep = monitor.getCurrentMode().equals(mode); } - - if(screenModeIdx >= 0) { - screenModesIdx2NativeId.put(screenModeIdx, nativeId); + if(!keep) { + cache.monitorModes.remove(i); + for(int j=cache.monitorDevices.size()-1; j>=0; j--) { + final MonitorDeviceImpl monitor = (MonitorDeviceImpl) cache.monitorDevices.get(j); + monitor.getSupportedModesImpl().remove(mode); + } } - } else if(DEBUG) { - System.err.println("ScreenImpl.collectNativeScreenModes: #"+num+": smProps: "+(null!=smProps)+ - ", len: "+(null != smProps ? smProps.length : 0)+ - ", bpp: "+(null != smProps && 0 < smProps.length ? smProps[idxBpp] : 0)+ - " - DROPPING"); } - num++; - } while ( null != smProps && 0 < smProps.length ); - - if(DEBUG) { - System.err.println("ScreenImpl.collectNativeScreenModes: ScreenMode number : "+screenModePool.size()); - System.err.println("ScreenImpl.collectNativeScreenModes: MonitorMode number : "+monitorModePool.size()); - System.err.println("ScreenImpl.collectNativeScreenModes: ScreenSizeMM number: "+screenSizeMMPool.size()); - System.err.println("ScreenImpl.collectNativeScreenModes: SurfaceSize number : "+surfaceSizePool.size()); - System.err.println("ScreenImpl.collectNativeScreenModes: Resolution number : "+resolutionPool.size()); } - - return screenModePool; + if( DEBUG ) { + System.err.println("ScreenImpl.collectNativeMonitorModes: MonitorDevice number : "+cache.monitorDevices.size()); + System.err.println("ScreenImpl.collectNativeMonitorModes: MonitorMode number : "+cache.monitorModes.size()); + System.err.println("ScreenImpl.collectNativeMonitorModes: SizeAndRate number : "+cache.sizeAndRates.size()); + System.err.println("ScreenImpl.collectNativeMonitorModes: SurfaceSize number : "+cache.surfaceSizes.size()); + System.err.println("ScreenImpl.collectNativeMonitorModes: Resolution number : "+cache.resolutions.size()); + } + return cache.monitorDevices.size(); } private void releaseScreenModeStatus() { - ScreenModeStatus sms; - ScreenModeStatus.lockScreenModeStatus(); + ScreenMonitorState sms; + ScreenMonitorState.lockScreenMonitorState(); try { - sms = ScreenModeStatus.getScreenModeStatus(getFQName()); + sms = ScreenMonitorState.getScreenMonitorState(getFQName()); if(null != sms) { sms.lock(); try { if(0 == sms.removeListener(this)) { - if(sms.isOriginalModeChangedByOwner()) { - System.err.println("Screen.destroy(): "+sms.getCurrentScreenMode()+" -> "+sms.getOriginalScreenMode()); - try { - setCurrentScreenMode(sms.getOriginalScreenMode()); - } catch (Throwable t) { - // be verbose but continue - t.printStackTrace(); + final ArrayList monitorDevices = sms.getMonitorDevices().getData(); + for(int i=0; i "+sms.getOriginalScreenMode()); - setCurrentScreenModeImpl(sms.getOriginalScreenMode()); - } catch (Throwable t) { - // be quiet .. shutdown + final ArrayList monitorDevices = sms.getMonitorDevices().getData(); + for(int i=0; i screenModes; - private IntIntHashMap screenModesIdx2NativeIdx; - private ScreenMode currentScreenMode; - private ScreenMode originalScreenMode; - private boolean screenModeChangedByOwner; - private ArrayList listener = new ArrayList(); - - private static HashMap screenFQN2ScreenModeStatus = new HashMap(); - private static RecursiveLock screen2ScreenModeStatusLock = LockFactory.createRecursiveLock(); - - protected static void mapScreenModeStatus(String screenFQN, ScreenModeStatus sms) { - screen2ScreenModeStatusLock.lock(); - try { - ScreenModeStatus _sms = screenFQN2ScreenModeStatus.get(screenFQN); - if( null != _sms ) { - throw new RuntimeException("ScreenModeStatus "+_sms+" already mapped to "+screenFQN); - } - screenFQN2ScreenModeStatus.put(screenFQN, sms); - if(DEBUG) { - System.err.println("ScreenModeStatus.map "+screenFQN+" -> "+sms); - } - } finally { - screen2ScreenModeStatusLock.unlock(); - } - } - - /** - * @param screen the prev user - * @return true if mapping is empty, ie no more usage of the mapped ScreenModeStatus - */ - protected static void unmapScreenModeStatus(String screenFQN) { - screen2ScreenModeStatusLock.lock(); - try { - unmapScreenModeStatusUnlocked(screenFQN); - } finally { - screen2ScreenModeStatusLock.unlock(); - } - } - protected static void unmapScreenModeStatusUnlocked(String screenFQN) { - ScreenModeStatus sms = screenFQN2ScreenModeStatus.remove(screenFQN); - if(DEBUG) { - System.err.println("ScreenModeStatus.unmap "+screenFQN+" -> "+sms); - } - } - - protected static ScreenModeStatus getScreenModeStatus(String screenFQN) { - screen2ScreenModeStatusLock.lock(); - try { - return getScreenModeStatusUnlocked(screenFQN); - } finally { - screen2ScreenModeStatusLock.unlock(); - } - } - protected static ScreenModeStatus getScreenModeStatusUnlocked(String screenFQN) { - return screenFQN2ScreenModeStatus.get(screenFQN); - } - - protected static void lockScreenModeStatus() { - screen2ScreenModeStatusLock.lock(); - } - - protected static void unlockScreenModeStatus() { - screen2ScreenModeStatusLock.unlock(); - } - - public ScreenModeStatus(ArrayHashSet screenModes, - IntIntHashMap screenModesIdx2NativeIdx) { - this.screenModes = screenModes; - this.screenModesIdx2NativeIdx = screenModesIdx2NativeIdx; - this.screenModeChangedByOwner = false; - } - - protected final void setOriginalScreenMode(ScreenMode originalScreenMode) { - this.originalScreenMode = originalScreenMode; - this.currentScreenMode = originalScreenMode; - } - - public final ScreenMode getOriginalScreenMode() { - return originalScreenMode; - } - - public final ScreenMode getCurrentScreenMode() { - lock(); - try { - return currentScreenMode; - } finally { - unlock(); - } - } - - /** - * We cannot guarantee that we won't interfere w/ another running - * application's screen mode change. - *

    - * At least we only return true if the owner, ie. the Screen, - * has changed the screen mode and if the original screen mode - * is not current the current one. - *

    - * @return - */ - public final boolean isOriginalModeChangedByOwner() { - lock(); - try { - return screenModeChangedByOwner && !isCurrentModeOriginalMode(); - } finally { - unlock(); - } - } - - protected final boolean isCurrentModeOriginalMode() { - if(null != currentScreenMode && null != originalScreenMode) { - return currentScreenMode.hashCode() == originalScreenMode.hashCode(); - } - return true; - } - - protected final ArrayHashSet getScreenModes() { - return screenModes; - } - - protected final IntIntHashMap getScreenModesIdx2NativeIdx() { - return screenModesIdx2NativeIdx; - } - - protected final int addListener(ScreenModeListener l) { - lock(); - try { - listener.add(l); - if(DEBUG) { - System.err.println("ScreenModeStatus.addListener (size: "+listener.size()+"): "+l); - } - return listener.size(); - } finally { - unlock(); - } - } - - protected final int removeListener(ScreenModeListener l) { - lock(); - try { - if(!listener.remove(l)) { - throw new RuntimeException("ScreenModeListener "+l+" not contained"); - } - if(DEBUG) { - System.err.println("ScreenModeStatus.removeListener (size: "+listener.size()+"): "+l); - } - return listener.size(); - } finally { - unlock(); - } - } - - protected final void fireScreenModeChangeNotify(ScreenMode desiredScreenMode) { - lock(); - try { - for(int i=0; i allMonitors; + private final ArrayHashSet allMonitorModes; + private ArrayList listener = new ArrayList(); + + private static HashMap screenFQN2ScreenMonitorState = new HashMap(); + private static RecursiveLock screen2ScreenMonitorState = LockFactory.createRecursiveLock(); + + protected static void mapScreenMonitorState(String screenFQN, ScreenMonitorState sms) { + screen2ScreenMonitorState.lock(); + try { + ScreenMonitorState _sms = screenFQN2ScreenMonitorState.get(screenFQN); + if( null != _sms ) { + throw new RuntimeException("ScreenMonitorState "+_sms+" already mapped to "+screenFQN); + } + screenFQN2ScreenMonitorState.put(screenFQN, sms); + if(DEBUG) { + System.err.println("ScreenMonitorState.map "+screenFQN+" -> "+sms); + } + } finally { + screen2ScreenMonitorState.unlock(); + } + } + + /** + * @param screen the prev user + * @return true if mapping is empty, ie no more usage of the mapped ScreenMonitorState + */ + protected static void unmapScreenMonitorState(String screenFQN) { + screen2ScreenMonitorState.lock(); + try { + unmapScreenMonitorStateUnlocked(screenFQN); + } finally { + screen2ScreenMonitorState.unlock(); + } + } + protected static void unmapScreenMonitorStateUnlocked(String screenFQN) { + ScreenMonitorState sms = screenFQN2ScreenMonitorState.remove(screenFQN); + if(DEBUG) { + System.err.println("ScreenMonitorState.unmap "+screenFQN+" -> "+sms); + } + } + + protected static ScreenMonitorState getScreenMonitorState(String screenFQN) { + screen2ScreenMonitorState.lock(); + try { + return getScreenMonitorStateUnlocked(screenFQN); + } finally { + screen2ScreenMonitorState.unlock(); + } + } + protected static ScreenMonitorState getScreenMonitorStateUnlocked(String screenFQN) { + return screenFQN2ScreenMonitorState.get(screenFQN); + } + + protected static void lockScreenMonitorState() { + screen2ScreenMonitorState.lock(); + } + + protected static void unlockScreenMonitorState() { + screen2ScreenMonitorState.unlock(); + } + + public ScreenMonitorState(ArrayHashSet allMonitors, + ArrayHashSet allMonitorModes) { + this.allMonitors = allMonitors; + this.allMonitorModes = allMonitorModes; + } + + protected ArrayHashSet getMonitorDevices() { + return allMonitors; + } + + protected ArrayHashSet getMonitorModes() { + return allMonitorModes; + } + + protected final int addListener(MonitorModeListener l) { + lock(); + try { + listener.add(l); + if(DEBUG) { + System.err.println("ScreenMonitorState.addListener (size: "+listener.size()+"): "+l); + } + return listener.size(); + } finally { + unlock(); + } + } + + protected final int removeListener(MonitorModeListener l) { + lock(); + try { + if(!listener.remove(l)) { + throw new RuntimeException("ScreenModeListener "+l+" not contained"); + } + if(DEBUG) { + System.err.println("ScreenMonitorState.removeListener (size: "+listener.size()+"): "+l); + } + return listener.size(); + } finally { + unlock(); + } + } + + protected final MonitorDevice getMonitor(MonitorDevice monitor) { + return allMonitors.get(monitor); + } + + protected final void validateMonitor(MonitorDevice monitor) { + final MonitorDevice md = allMonitors.get(monitor); + if( null == md ) { + throw new InternalError("Monitor unknown: "+monitor); + } + } + + protected final void fireScreenModeChangeNotify(MonitorDevice monitor, MonitorMode desiredMode) { + lock(); + try { + validateMonitor(monitor); + final MonitorEvent me = new MonitorEvent(MonitorEvent.EVENT_MONITOR_MODE_CHANGE_NOTIFY, monitor, System.currentTimeMillis(), desiredMode); + for(int i=0; i default - private boolean fullscreen = false, brokenFocusChange = false; + private boolean fullscreen = false, brokenFocusChange = false; + private List fullscreenMonitors = null; + private boolean fullscreenUseMainMonitor = true; private boolean autoPosition = true; // default: true (allow WM to choose top-level position, if not set by user) private int nfs_width, nfs_height, nfs_x, nfs_y; // non fullscreen client-area size/pos w/o insets @@ -294,19 +298,40 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer screenReferenceAdded = true; } if(canCreateNativeImpl()) { + final int wX, wY; + final boolean usePosition; + if( autoPosition ) { + wX = 0; + wY = 0; + usePosition = false; + } else { + wX = getX(); + wY = getY(); + usePosition = true; + } + final long t0 = System.currentTimeMillis(); createNativeImpl(); - screen.addScreenModeListener(screenModeListenerImpl); + screen.addMonitorModeListener(screenModeListenerImpl); setTitleImpl(title); setPointerVisibleImpl(pointerVisible); confinePointerImpl(pointerConfined); setKeyboardVisible(keyboardVisible); - if(waitForVisible(true, false)) { + final long remainingV = waitForVisible(true, false); + if( 0 <= remainingV ) { if(isFullscreen()) { synchronized(fullScreenAction) { fullscreen = false; // trigger a state change - fullScreenAction.init(true); + fullScreenAction.init(true, fullscreenUseMainMonitor, fullscreenMonitors); + fullscreenMonitors = null; // release references ASAP + fullscreenUseMainMonitor = true; fullScreenAction.run(); } + } else { + // Wait until position is reached within tolerances, either auto-position or custom position. + waitForPosition(usePosition, wX, wY, Window.TIMEOUT_NATIVEWINDOW); + } + if (DEBUG_IMPLEMENTATION) { + System.err.println("Window.createNative(): elapsed "+(System.currentTimeMillis()-t0)+" ms"); } postParentlockFocus = true; } @@ -463,8 +488,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public static final int FLAG_HAS_PARENT = 1 << 8; public static final int FLAG_IS_UNDECORATED = 1 << 9; public static final int FLAG_IS_FULLSCREEN = 1 << 10; - public static final int FLAG_IS_ALWAYSONTOP = 1 << 11; - public static final int FLAG_IS_VISIBLE = 1 << 12; + public static final int FLAG_IS_FULLSCREEN_SPAN = 1 << 11; + public static final int FLAG_IS_ALWAYSONTOP = 1 << 12; + public static final int FLAG_IS_VISIBLE = 1 << 13; /** * The native implementation should invoke the referenced java state callbacks @@ -509,6 +535,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } sb.append("FS_"); sb.append(0 != ( FLAG_IS_FULLSCREEN & flags)); + sb.append("_span_"); + sb.append(0 != ( FLAG_IS_FULLSCREEN_SPAN & flags)); sb.append(", "); if( 0 != ( FLAG_CHANGE_DECORATION & flags) ) { @@ -718,6 +746,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer return screen; } + @Override + public final MonitorDevice getMainMonitor() { + return screen.getMainMonitor(new Rectangle(getX(), getY(), getWidth(), getHeight())); + } + protected final void setVisibleImpl(boolean visible, int x, int y, int width, int height) { reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(FLAG_CHANGE_VISIBILITY, visible)); } @@ -904,7 +937,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } if( isNativeValid() ) { - screen.removeScreenModeListener(screenModeListenerImpl); + screen.removeMonitorModeListener(screenModeListenerImpl); closeNativeImpl(); final AbstractGraphicsDevice cfgADevice = config.getScreen().getDevice(); if( cfgADevice != screen.getDisplay().getGraphicsDevice() ) { // don't pull display's device @@ -929,6 +962,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer setWindowHandle(0); visible = false; fullscreen = false; + fullscreenMonitors = null; + fullscreenUseMainMonitor = true; hasFocus = false; parentWindowHandle = 0; @@ -1212,7 +1247,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer display.dispatchMessagesNative(); // status up2date if(wasVisible) { setVisibleImpl(true, x, y, width, height); - ok = WindowImpl.this.waitForVisible(true, false); + ok = 0 <= WindowImpl.this.waitForVisible(true, false); if(ok) { ok = WindowImpl.this.waitForSize(width, height, false, TIMEOUT_NATIVEWINDOW); } @@ -1735,6 +1770,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if(isNativeValid()) { // this.x/this.y will be set by sizeChanged, triggered by windowing event system reconfigureWindowImpl(x, y, getWidth(), getHeight(), getReconfigureFlags(0, isVisible())); + + // Wait until custom position is reached within tolerances + waitForPosition(true, x, y, Window.TIMEOUT_NATIVEWINDOW); } else { definePosition(x, y); // set pos for createNative(..) } @@ -1758,13 +1796,25 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private class FullScreenAction implements Runnable { boolean fullscreen; + List monitors; + boolean useMainMonitor; - private boolean init(boolean fullscreen) { + private boolean init(boolean fullscreen, boolean useMainMonitor, List monitors) { if(isNativeValid()) { this.fullscreen = fullscreen; - return isFullscreen() != fullscreen; + if( isFullscreen() != fullscreen ) { + this.monitors = monitors; + this.useMainMonitor = useMainMonitor; + return true; + } else { + this.monitors = null; + this.useMainMonitor = true; + return false; + } } else { WindowImpl.this.fullscreen = fullscreen; // set current state for createNative(..) + WindowImpl.this.fullscreenMonitors = monitors; + WindowImpl.this.fullscreenUseMainMonitor = useMainMonitor; return false; } } @@ -1777,19 +1827,32 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer // set current state WindowImpl.this.fullscreen = fullscreen; - final ScreenMode sm = screen.getCurrentScreenMode(); int x,y,w,h; + final RectangleImmutable viewport; + final int fs_span_flag; if(fullscreen) { + if( null == monitors ) { + if( useMainMonitor ) { + monitors = new ArrayList(); + monitors.add( getMainMonitor() ); + } else { + monitors = getScreen().getMonitorDevices(); + } + } + fs_span_flag = monitors.size() > 1 ? FLAG_IS_FULLSCREEN_SPAN : 0 ; + viewport = MonitorDevice.unionOfViewports(new Rectangle(), monitors); nfs_x = getX(); nfs_y = getY(); nfs_width = getWidth(); nfs_height = getHeight(); - x = screen.getX(); - y = screen.getY(); - w = sm.getRotatedWidth(); - h = sm.getRotatedHeight(); + x = viewport.getX(); + y = viewport.getY(); + w = viewport.getWidth(); + h = viewport.getHeight(); } else { + fs_span_flag = 0; + viewport = null; x = nfs_x; y = nfs_y; w = nfs_width; @@ -1809,9 +1872,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } } + monitors = null; // clear references ASAP + useMainMonitor = true; if(DEBUG_IMPLEMENTATION) { System.err.println("Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+ - ", virtl-size: "+screen.getWidth()+"x"+screen.getHeight()+", SM "+sm.getRotatedWidth()+"x"+sm.getRotatedHeight()); + ", virtl-size: "+screen.getWidth()+"x"+screen.getHeight()+", monitorsViewport "+viewport); } DisplayImpl display = (DisplayImpl) screen.getDisplay(); @@ -1831,7 +1896,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer try { reconfigureWindowImpl(x, y, w, h, getReconfigureFlags( ( ( null != parentWindowLocked ) ? FLAG_CHANGE_PARENTING : 0 ) | - FLAG_CHANGE_FULLSCREEN | FLAG_CHANGE_DECORATION, wasVisible) ); + fs_span_flag | FLAG_CHANGE_FULLSCREEN | FLAG_CHANGE_DECORATION, wasVisible) ); } finally { if(null!=parentWindowLocked) { parentWindowLocked.unlockSurface(); @@ -1860,8 +1925,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer @Override public boolean setFullscreen(boolean fullscreen) { + return setFullscreenImpl(fullscreen, true, null); + } + + @Override + public boolean setFullscreen(List monitors) { + return setFullscreenImpl(true, false, monitors); + } + + private boolean setFullscreenImpl(boolean fullscreen, boolean useMainMonitor, List monitors) { synchronized(fullScreenAction) { - if( fullScreenAction.init(fullscreen) ) { + if( fullScreenAction.init(fullscreen, useMainMonitor, monitors) ) { if(fullScreenAction.fsOn() && isOffscreenInstance(WindowImpl.this, parentWindow)) { // enable fullscreen on offscreen instance if(null != parentWindow) { @@ -1887,13 +1961,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer return this.fullscreen; } } - - private class ScreenModeListenerImpl implements ScreenModeListener { + + private class ScreenModeListenerImpl implements MonitorModeListener { boolean animatorPaused = false; - public void screenModeChangeNotify(ScreenMode sm) { + public void monitorModeChangeNotify(MonitorEvent me) { if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.screenModeChangeNotify: "+sm); + System.err.println("Window.screenModeChangeNotify: "+me); } if(null!=lifecycleHook) { @@ -1901,9 +1975,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } - public void screenModeChanged(ScreenMode sm, boolean success) { + public void monitorModeChanged(MonitorEvent me, boolean success) { if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.screenModeChanged: "+sm+", success: "+success); + System.err.println("Window.screenModeChanged: "+me+", success: "+success); } if(success) { @@ -1911,10 +1985,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer // Didn't pass above notify method. probably detected screen change after it happened. animatorPaused = lifecycleHook.pauseRenderingAction(); } - DimensionImmutable screenSize = sm.getMonitorMode().getSurfaceSize().getResolution(); - if ( getHeight() > screenSize.getHeight() || - getWidth() > screenSize.getWidth() ) { - setSize(screenSize.getWidth(), screenSize.getHeight()); + if( !fullscreen ) { + // FIXME: Need to take all covered monitors into account + final MonitorDevice mainMonitor = getMainMonitor(); + final MonitorDevice eventMonitor = me.getMonitor(); + if( mainMonitor == eventMonitor ) { + final RectangleImmutable rect = new Rectangle(getX(), getY(), getWidth(), getHeight()); + final RectangleImmutable viewport = mainMonitor.getViewport(); + final RectangleImmutable isect = viewport.intersection(rect); + if ( getHeight() > isect.getHeight() || + getWidth() > isect.getWidth() ) { + setSize(isect.getWidth(), isect.getHeight()); + } + } } } @@ -2563,14 +2646,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } - private boolean waitForVisible(boolean visible, boolean failFast) { + /** Returns -1 if failed, otherwise remaining time until {@link #TIMEOUT_NATIVEWINDOW}, maybe zero. */ + private long waitForVisible(boolean visible, boolean failFast) { return waitForVisible(visible, failFast, TIMEOUT_NATIVEWINDOW); } - private boolean waitForVisible(boolean visible, boolean failFast, long timeOut) { + /** Returns -1 if failed, otherwise remaining time until timeOut, maybe zero. */ + private long waitForVisible(boolean visible, boolean failFast, long timeOut) { final DisplayImpl display = (DisplayImpl) screen.getDisplay(); display.dispatchMessagesNative(); // status up2date - for(long sleep = timeOut; 0 + * Since WM may not obey our positional request exactly, we allow a tolerance of 2 times insets[left/top], or 64 pixels, whatever is greater. + *

    + */ + private boolean waitForPosition(boolean useCustomPosition, int x, int y, long timeOut) { + final DisplayImpl display = (DisplayImpl) screen.getDisplay(); + final int maxDX, maxDY; + { + final InsetsImmutable insets = getInsets(); + maxDX = Math.max(64, insets.getLeftWidth() * 2); + maxDY = Math.max(64, insets.getTopHeight() * 2); + } + long remaining = timeOut; + boolean ok; + do { + if( useCustomPosition ) { + ok = Math.abs(x - getX()) <= maxDX && Math.abs(y - getY()) <= maxDY ; + } else { + ok = !autoPosition; + } + if( !ok ) { + try { Thread.sleep(10); } catch (InterruptedException ie) {} + display.dispatchMessagesNative(); // status up2date + remaining-=10; + } + } while ( 0getX() || 0>getY()) { diff --git a/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java index 6b1283a00..8e584fc58 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java @@ -35,12 +35,15 @@ package jogamp.newt.driver.awt; import java.awt.DisplayMode; +import jogamp.newt.MonitorModeProps.Cache; import jogamp.newt.ScreenImpl; import javax.media.nativewindow.util.Dimension; import javax.media.nativewindow.util.Point; import com.jogamp.nativewindow.awt.AWTGraphicsDevice; import com.jogamp.nativewindow.awt.AWTGraphicsScreen; +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; public class ScreenDriver extends ScreenImpl { public ScreenDriver() { @@ -68,14 +71,19 @@ public class ScreenDriver extends ScreenImpl { return idx; // pass through ... } - protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { - final DisplayMode mode = ((AWTGraphicsDevice)getDisplay().getGraphicsDevice()).getGraphicsDevice().getDisplayMode(); - if(null != mode) { - virtualOrigin.setX(0); - virtualOrigin.setY(0); - virtualSize.setWidth(mode.getWidth()); - virtualSize.setHeight(mode.getHeight()); - } + @Override + protected void collectNativeMonitorModesAndDevicesImpl(Cache cache) { + final DisplayMode mode = ((AWTGraphicsDevice)getDisplay().getGraphicsDevice()).getGraphicsDevice().getDisplayMode(); + } + + @Override + protected MonitorMode queryCurrentMonitorModeImpl(MonitorDevice monitor) { + return null; + } + + @Override + protected boolean setCurrentMonitorModeImpl(MonitorDevice monitor, MonitorMode mode) { + return false; } } diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java index deb2a534b..afaedffe3 100644 --- a/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java @@ -35,8 +35,13 @@ package jogamp.newt.driver.bcm.egl; import javax.media.nativewindow.DefaultGraphicsScreen; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.Point; +import javax.media.nativewindow.util.Rectangle; + +import jogamp.newt.MonitorModeProps; +import jogamp.newt.ScreenImpl; + +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; public class ScreenDriver extends jogamp.newt.ScreenImpl { @@ -58,11 +63,48 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl { return 0; // only one screen available } - protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { - virtualOrigin.setX(0); - virtualOrigin.setY(0); - virtualSize.setWidth(fixedWidth); // FIXME - virtualSize.setHeight(fixedHeight); // FIXME + @Override + protected final void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) { + int[] props = new int[ MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL ]; + int i = 0; + props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL; + props[i++] = fixedWidth; // FIXME + props[i++] = fixedHeight; // FIXME + props[i++] = ScreenImpl.default_sm_bpp; // FIXME + props[i++] = ScreenImpl.default_sm_rate * 100; // FIXME + props[i++] = 0; // flags + props[i++] = 0; // mode_idx + props[i++] = 0; // rotation + final MonitorMode currentMode = MonitorModeProps.streamInMonitorMode(null, cache, props, 0); + + props = new int[MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES - 1 - MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES]; + i = 0; + props[i++] = props.length; + props[i++] = 0; // crt_idx + props[i++] = ScreenImpl.default_sm_widthmm; // FIXME + props[i++] = ScreenImpl.default_sm_heightmm; // FIXME + props[i++] = 0; // rotated viewport x + props[i++] = 0; // rotated viewport y + props[i++] = fixedWidth; // FIXME rotated viewport width + props[i++] = fixedHeight; // FIXME rotated viewport height + MonitorModeProps.streamInMonitorDevice(null, cache, this, cache.monitorModes, currentMode, props, 0); + } + + @Override + protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) { + return monitor.getSupportedModes().get(0); + } + + @Override + protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) { + return false; + } + + protected void calcVirtualScreenOriginAndSize(Rectangle vOriginSize) { + vOriginSize.setX(0); + vOriginSize.setY(0); + vOriginSize.setWidth(fixedWidth); // FIXME + vOriginSize.setHeight(fixedHeight); // FIXME } //---------------------------------------------------------------------- diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java index 787d1a1b4..f7973def8 100644 --- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java @@ -29,9 +29,12 @@ package jogamp.newt.driver.bcm.vc.iv; import javax.media.nativewindow.DefaultGraphicsScreen; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.Point; +import javax.media.nativewindow.util.Rectangle; +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; + +import jogamp.newt.MonitorModeProps; import jogamp.newt.ScreenImpl; public class ScreenDriver extends ScreenImpl { @@ -53,13 +56,52 @@ public class ScreenDriver extends ScreenImpl { return 0; // only one screen available } - protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { - virtualOrigin.setX(0); - virtualOrigin.setY(0); - virtualSize.setWidth(cachedWidth); - virtualSize.setHeight(cachedHeight); + @Override + protected final void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) { + int[] props = new int[ MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL ]; + int i = 0; + props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL; + props[i++] = cachedWidth; // width + props[i++] = cachedHeight; // height + props[i++] = ScreenImpl.default_sm_bpp; // FIXME + props[i++] = ScreenImpl.default_sm_rate * 100; // FIXME + props[i++] = 0; // flags + props[i++] = 0; // mode_idx + props[i++] = 0; // rotation + final MonitorMode currentMode = MonitorModeProps.streamInMonitorMode(null, cache, props, 0); + + props = new int[MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES - 1 - MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES]; + i = 0; + props[i++] = props.length; + props[i++] = 0; // crt_idx + props[i++] = ScreenImpl.default_sm_widthmm; // FIXME + props[i++] = ScreenImpl.default_sm_heightmm; // FIXME + props[i++] = 0; // rotated viewport x + props[i++] = 0; // rotated viewport y + props[i++] = cachedWidth; // rotated viewport width + props[i++] = cachedWidth; // rotated viewport height + MonitorModeProps.streamInMonitorDevice(null, cache, this, cache.monitorModes, currentMode, props, 0); + } + + @Override + protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) { + return monitor.getSupportedModes().get(0); + } + + @Override + protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) { + return false; + } + + @Override + protected void calcVirtualScreenOriginAndSize(Rectangle vOriginSize) { + vOriginSize.setX(0); + vOriginSize.setY(0); + vOriginSize.setWidth(cachedWidth); + vOriginSize.setHeight(cachedHeight); } + /** Called from {@link #initNative()}. */ protected void setScreenSize(int width, int height) { cachedWidth = width; cachedHeight = height; diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java index 8eed14dde..4c47eb0d8 100644 --- a/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java @@ -36,8 +36,13 @@ package jogamp.newt.driver.intel.gdl; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.DefaultGraphicsScreen; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.Point; +import javax.media.nativewindow.util.Rectangle; + +import jogamp.newt.MonitorModeProps; +import jogamp.newt.ScreenImpl; + +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; public class ScreenDriver extends jogamp.newt.ScreenImpl { @@ -60,11 +65,48 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl { return 0; // only one screen available } - protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { - virtualOrigin.setX(0); - virtualOrigin.setY(0); - virtualSize.setWidth(cachedWidth); - virtualSize.setHeight(cachedHeight); + @Override + protected final void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) { + int[] props = new int[ MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL ]; + int i = 0; + props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL; + props[i++] = cachedWidth; // width + props[i++] = cachedHeight; // height + props[i++] = ScreenImpl.default_sm_bpp; // FIXME + props[i++] = ScreenImpl.default_sm_rate * 100; // FIXME + props[i++] = 0; // flags + props[i++] = 0; // mode_idx + props[i++] = 0; // rotation + final MonitorMode currentMode = MonitorModeProps.streamInMonitorMode(null, cache, props, 0); + + props = new int[MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES - 1 - MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES]; + i = 0; + props[i++] = props.length; + props[i++] = 0; // crt_idx + props[i++] = ScreenImpl.default_sm_widthmm; // FIXME + props[i++] = ScreenImpl.default_sm_heightmm; // FIXME + props[i++] = 0; // rotated viewport x + props[i++] = 0; // rotated viewport y + props[i++] = cachedWidth; // rotated viewport width + props[i++] = cachedWidth; // rotated viewport height + MonitorModeProps.streamInMonitorDevice(null, cache, this, cache.monitorModes, currentMode, props, 0); + } + + @Override + protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) { + return monitor.getSupportedModes().get(0); + } + + @Override + protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) { + return false; + } + + protected void calcVirtualScreenOriginAndSize(Rectangle vOriginSize) { + vOriginSize.setX(0); + vOriginSize.setY(0); + vOriginSize.setWidth(cachedWidth); + vOriginSize.setHeight(cachedHeight); } //---------------------------------------------------------------------- diff --git a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java index 656bcf5c9..dc87c3c08 100644 --- a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java @@ -35,9 +35,12 @@ package jogamp.newt.driver.kd; import javax.media.nativewindow.DefaultGraphicsScreen; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.Point; +import javax.media.nativewindow.util.Rectangle; +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; + +import jogamp.newt.MonitorModeProps; import jogamp.newt.ScreenImpl; public class ScreenDriver extends ScreenImpl { @@ -58,11 +61,48 @@ public class ScreenDriver extends ScreenImpl { return 0; // only one screen available } - protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { - virtualOrigin.setX(0); - virtualOrigin.setY(0); - virtualSize.setWidth(cachedWidth); - virtualSize.setHeight(cachedHeight); + @Override + protected final void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) { + int[] props = new int[ MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL ]; + int i = 0; + props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL; + props[i++] = cachedWidth; // width + props[i++] = cachedHeight; // height + props[i++] = ScreenImpl.default_sm_bpp; // FIXME + props[i++] = ScreenImpl.default_sm_rate * 100; // FIXME + props[i++] = 0; // flags + props[i++] = 0; // mode_idx + props[i++] = 0; // rotation + final MonitorMode currentMode = MonitorModeProps.streamInMonitorMode(null, cache, props, 0); + + props = new int[MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES - 1 - MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES]; + i = 0; + props[i++] = props.length; + props[i++] = 0; // crt_idx + props[i++] = ScreenImpl.default_sm_widthmm; // FIXME + props[i++] = ScreenImpl.default_sm_heightmm; // FIXME + props[i++] = 0; // rotated viewport x + props[i++] = 0; // rotated viewport y + props[i++] = cachedWidth; // rotated viewport width + props[i++] = cachedWidth; // rotated viewport height + MonitorModeProps.streamInMonitorDevice(null, cache, this, cache.monitorModes, currentMode, props, 0); + } + + @Override + protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) { + return monitor.getSupportedModes().get(0); + } + + @Override + protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) { + return false; + } + + protected void calcVirtualScreenOriginAndSize(Rectangle vOriginSize) { + vOriginSize.setX(0); + vOriginSize.setY(0); + vOriginSize.setWidth(cachedWidth); + vOriginSize.setHeight(cachedHeight); } protected void sizeChanged(int w, int h) { diff --git a/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java index 24e60ba0a..a3bb26731 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java @@ -34,28 +34,19 @@ package jogamp.newt.driver.macosx; -import java.util.List; - import javax.media.nativewindow.DefaultGraphicsScreen; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.DimensionImmutable; -import javax.media.nativewindow.util.Point; +import jogamp.newt.MonitorModeProps; import jogamp.newt.ScreenImpl; -import com.jogamp.common.util.IntObjectHashMap; -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.util.ScreenModeUtil; +import com.jogamp.common.util.ArrayHashSet; +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; public class ScreenDriver extends ScreenImpl { - // caching native CGDisplayScreenSize() results, since it's ridiculous slow (~6 ms each call) - private static IntObjectHashMap/**/ scrnIdx2Dimension; - static { DisplayDriver.initSingleton(); - scrnIdx2Dimension = new IntObjectHashMap(); - scrnIdx2Dimension.setKeyNotFoundValue(null); } public ScreenDriver() { @@ -67,77 +58,67 @@ public class ScreenDriver extends ScreenImpl { protected void closeNativeImpl() { } - private static native int getWidthImpl0(int scrn_idx); - private static native int getHeightImpl0(int scrn_idx); - - private int[] getScreenModeIdx(int idx) { - // caching native CGDisplayScreenSize() results, since it's ridiculous slow (~6 ms each call) - DimensionImmutable dim = (DimensionImmutable) scrnIdx2Dimension.get(screen_idx); - if(null == dim) { - int[] res = getScreenSizeMM0(screen_idx); - if(null == res || 0 == res.length) { - return null; - } - dim = new Dimension(res[0], res[1]); - scrnIdx2Dimension.put(screen_idx, dim); - } - - int[] modeProps = getScreenMode0(screen_idx, idx, dim.getWidth(), dim.getHeight()); - if (null == modeProps || 0 == modeProps.length) { - return null; + private MonitorMode getMonitorModeImpl(MonitorModeProps.Cache cache, int crt_idx, int mode_idx) { + final int[] modeProps = getMonitorMode0(crt_idx, mode_idx); + final MonitorMode res; + if (null == modeProps || 0 >= modeProps.length) { + res = null; + } else { + res = MonitorModeProps.streamInMonitorMode(null, cache, modeProps, 0); } - if(modeProps.length < ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL) { - throw new RuntimeException("properties array too short, should be >= "+ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+modeProps.length); - } - return modeProps; + return res; } - - private int nativeModeIdx; - protected int[] getScreenModeFirstImpl() { - nativeModeIdx = 0; - return getScreenModeNextImpl(); - } - - protected int[] getScreenModeNextImpl() { - int[] modeProps = getScreenModeIdx(nativeModeIdx); - if (null != modeProps && 0 < modeProps.length) { - nativeModeIdx++; - return modeProps; - } - return null; + @Override + protected final void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) { + int crtIdx = 0; + int modeIdx = 0; + ArrayHashSet supportedModes = new ArrayHashSet(); + do { + final MonitorMode mode = getMonitorModeImpl(cache, crtIdx, modeIdx); + if( null != mode ) { + supportedModes.getOrAdd(mode); + // next mode on same monitor + modeIdx++; + } else if( 0 < modeIdx ) { + // end of monitor modes - got at least one mode + final MonitorMode currentMode = getMonitorModeImpl(cache, crtIdx, -1); + if ( null == currentMode ) { + throw new InternalError("Could not gather current mode of device "+crtIdx+", but gathered "+modeIdx+" modes"); + } + final int[] monitorProps = getMonitorProps0(crtIdx); + if ( null == monitorProps ) { + throw new InternalError("Could not gather device "+crtIdx+", but gathered "+modeIdx+" modes"); + } + // merge monitor-props + supported modes + MonitorModeProps.streamInMonitorDevice(null, cache, this, supportedModes, currentMode, monitorProps, 0); + + // next monitor, 1st mode + supportedModes= new ArrayHashSet(); + crtIdx++; + modeIdx=0; + } else { + // end of monitor + break; + } + } while ( true ); } - protected ScreenMode getCurrentScreenModeImpl() { - int[] modeProps = getScreenModeIdx(-1); - if (null != modeProps && 0 < modeProps.length) { - return ScreenModeUtil.streamIn(modeProps, 0); - } - return null; + @Override + protected MonitorMode queryCurrentMonitorModeImpl(MonitorDevice monitor) { + return getMonitorModeImpl(null, monitor.getId(), -1); } - protected boolean setCurrentScreenModeImpl(final ScreenMode screenMode) { - final List screenModes = this.getScreenModesOrig(); - final int screenModeIdx = screenModes.indexOf(screenMode); - if(0>screenModeIdx) { - throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode); - } - final int nativeModeIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx); - return setScreenMode0(screen_idx, nativeModeIdx); + @Override + protected boolean setCurrentMonitorModeImpl(MonitorDevice monitor, MonitorMode mode) { + return setMonitorMode0(monitor.getId(), mode.getId(), mode.getRotation()); } protected int validateScreenIndex(int idx) { - return idx; + return 0; // big-desktop w/ multiple monitor attached, only one screen available } - protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { - virtualOrigin.setX(0); - virtualOrigin.setY(0); - virtualSize.setWidth(getWidthImpl0(screen_idx)); - virtualSize.setHeight(getHeightImpl0(screen_idx)); - } - - private native int[] getScreenSizeMM0(int screen_idx); - private native int[] getScreenMode0(int screen_index, int mode_index, int widthMM, int heightMM); - private native boolean setScreenMode0(int screen_index, int mode_idx); + private native int[] getMonitorProps0(int crt_idx); + private native int[] getMonitorMode0(int crt_index, int mode_idx); + private native boolean setMonitorMode0(int crt_index, int nativeId, int rot); } diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java index bb72350e3..6370782df 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java @@ -478,7 +478,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl if( 0 != surfaceHandle ) { throw new NativeWindowException("Internal Error - create w/o window, but has Newt NSView"); } - surfaceHandle = createView0(pS.getX(), pS.getY(), width, height, fullscreen, getScreen().getIndex()); + surfaceHandle = createView0(pS.getX(), pS.getY(), width, height, fullscreen); if( 0 == surfaceHandle ) { throw new NativeWindowException("Could not create native view "+Thread.currentThread().getName()+" "+this); } @@ -487,7 +487,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl final long newWin = createWindow0( pS.getX(), pS.getY(), width, height, fullscreen, ( isUndecorated() || offscreenInstance ) ? NSBorderlessWindowMask : NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask, - NSBackingStoreBuffered, getScreen().getIndex(), surfaceHandle); + NSBackingStoreBuffered, surfaceHandle); if ( newWin == 0 ) { throw new NativeWindowException("Could not create native window "+Thread.currentThread().getName()+" "+this); } @@ -497,9 +497,8 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl // Non blocking initialization on main-thread! OSXUtil.RunOnMainThread(false, new Runnable() { public void run() { - initWindow0( parentWin, newWin, - pS.getX(), pS.getY(), width, height, - isOpaque, fullscreen, visible && !offscreenInstance, getScreen().getIndex(), surfaceHandle); + initWindow0( parentWin, newWin, pS.getX(), pS.getY(), width, height, + isOpaque, fullscreen, visible && !offscreenInstance, surfaceHandle); if( offscreenInstance ) { orderOut0(0!=parentWin ? parentWin : newWin); } else { @@ -514,11 +513,11 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl } protected static native boolean initIDs0(); - private native long createView0(int x, int y, int w, int h, boolean fullscreen, int screen_idx); - private native long createWindow0(int x, int y, int w, int h, boolean fullscreen, int windowStyle, int backingStoreType, int screen_idx, long view); + private native long createView0(int x, int y, int w, int h, boolean fullscreen); + private native long createWindow0(int x, int y, int w, int h, boolean fullscreen, int windowStyle, int backingStoreType, long view); /** Must be called on Main-Thread */ private native void initWindow0(long parentWindow, long window, int x, int y, int w, int h, - boolean opaque, boolean fullscreen, boolean visible, int screen_idx, long view); + boolean opaque, boolean fullscreen, boolean visible, long view); private native boolean lockSurface0(long window, long view); private native boolean unlockSurface0(long window, long view); /** Must be called on Main-Thread */ diff --git a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java index 948b29460..342829691 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java @@ -34,91 +34,143 @@ package jogamp.newt.driver.windows; import javax.media.nativewindow.DefaultGraphicsScreen; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.Point; +import javax.media.nativewindow.util.Rectangle; +import jogamp.newt.MonitorModeProps; import jogamp.newt.ScreenImpl; -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.util.ScreenModeUtil; +import com.jogamp.common.util.ArrayHashSet; +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; +import com.jogamp.newt.Screen; public class ScreenDriver extends ScreenImpl { static { DisplayDriver.initSingleton(); + if( Screen.DEBUG ) { + dumpMonitorInfo0(); + } } public ScreenDriver() { } + @Override protected void createNativeImpl() { aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx); } + @Override protected void closeNativeImpl() { } - private int[] getScreenModeIdx(int idx) { - int[] modeProps = getScreenMode0(screen_idx, idx); - if (null == modeProps || 0 == modeProps.length) { + private final String getAdapterName(int crt_idx) { + return getAdapterName0(crt_idx); + } + private final String getActiveMonitorName(String adapterName, int monitor_idx) { + return getActiveMonitorName0(adapterName, monitor_idx); + } + + private final MonitorMode getMonitorModeImpl(MonitorModeProps.Cache cache, String adapterName, int crtModeIdx) { + if( null == adapterName ) { return null; } - if(modeProps.length < ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL) { - throw new RuntimeException("properties array too short, should be >= "+ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+modeProps.length); + final String activeMonitorName = getActiveMonitorName(adapterName, 0); + final int[] modeProps = null != activeMonitorName ? getMonitorMode0(adapterName, crtModeIdx) : null; + if ( null == modeProps || 0 >= modeProps.length) { + return null; } - return modeProps; + return MonitorModeProps.streamInMonitorMode(null, cache, modeProps, 0); } - private int nativeModeIdx; - - protected int[] getScreenModeFirstImpl() { - nativeModeIdx = 0; - return getScreenModeNextImpl(); - } - - protected int[] getScreenModeNextImpl() { - int[] modeProps = getScreenModeIdx(nativeModeIdx); - if (null != modeProps && 0 < modeProps.length) { - nativeModeIdx++; - return modeProps; + @Override + protected void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) { + int crtIdx = 0; + ArrayHashSet supportedModes = new ArrayHashSet(); + String adapterName = getAdapterName(crtIdx); + while( null != adapterName ) { + int crtModeIdx = 0; + MonitorMode mode; + do { + mode = getMonitorModeImpl(cache, adapterName, crtModeIdx); + if( null != mode ) { + supportedModes.getOrAdd(mode); + // next mode on same monitor + crtModeIdx++; + } + } while( null != mode); + if( 0 < crtModeIdx ) { + // has at least one mode -> add device + final MonitorMode currentMode = getMonitorModeImpl(cache, adapterName, -1); + if ( null != currentMode ) { // enabled + final int[] monitorProps = getMonitorDevice0(adapterName, crtIdx); + // merge monitor-props + supported modes + MonitorModeProps.streamInMonitorDevice(null, cache, this, supportedModes, currentMode, monitorProps, 0); + + // next monitor, 1st mode + supportedModes= new ArrayHashSet(); + } + } + crtIdx++; + adapterName = getAdapterName(crtIdx); } - return null; } - - protected ScreenMode getCurrentScreenModeImpl() { - int[] modeProps = getScreenModeIdx(-1); - if (null != modeProps && 0 < modeProps.length) { - return ScreenModeUtil.streamIn(modeProps, 0); + + @Override + protected Rectangle getNativeMonitorDeviceViewportImpl(MonitorDevice monitor) { + final String adapterName = getAdapterName(monitor.getId()); + if( null != adapterName ) { + final String activeMonitorName = getActiveMonitorName(adapterName, 0); + if( null != activeMonitorName ) { + final int[] monitorProps = getMonitorDevice0(adapterName, monitor.getId()); + int offset = MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT; + return new Rectangle(monitorProps[offset++], monitorProps[offset++], monitorProps[offset++], monitorProps[offset++]); + } } return null; } - protected boolean setCurrentScreenModeImpl(ScreenMode sm) { - return setScreenMode0(screen_idx, - sm.getMonitorMode().getSurfaceSize().getResolution().getWidth(), - sm.getMonitorMode().getSurfaceSize().getResolution().getHeight(), - sm.getMonitorMode().getSurfaceSize().getBitsPerPixel(), - sm.getMonitorMode().getRefreshRate(), - sm.getRotation()); + @Override + protected MonitorMode queryCurrentMonitorModeImpl(MonitorDevice monitor) { + return getMonitorModeImpl(null, getAdapterName(monitor.getId()), -1); + } + + @Override + protected boolean setCurrentMonitorModeImpl(MonitorDevice monitor, MonitorMode mode) { + return setMonitorMode0(monitor.getId(), + -1, -1, // no fixed position! + mode.getSurfaceSize().getResolution().getWidth(), + mode.getSurfaceSize().getResolution().getHeight(), + mode.getSurfaceSize().getBitsPerPixel(), + (int)mode.getRefreshRate(), // simply cut-off, orig is int + mode.getFlags(), + mode.getRotation()); } + @Override protected int validateScreenIndex(int idx) { - return 0; // big-desktop, only one screen available + return 0; // big-desktop w/ multiple monitor attached, only one screen available } - protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) { - virtualOrigin.setX(getOriginX0(screen_idx)); - virtualOrigin.setY(getOriginY0(screen_idx)); - virtualSize.setWidth(getWidthImpl0(screen_idx)); - virtualSize.setHeight(getHeightImpl0(screen_idx)); + @Override + protected void calcVirtualScreenOriginAndSize(Rectangle vOriginSize) { + vOriginSize.setX(getVirtualOriginX0()); + vOriginSize.setY(getVirtualOriginY0()); + vOriginSize.setWidth(getVirtualWidthImpl0()); + vOriginSize.setHeight(getVirtualHeightImpl0()); } // Native calls - private native int getOriginX0(int screen_idx); - private native int getOriginY0(int screen_idx); - private native int getWidthImpl0(int scrn_idx); - private native int getHeightImpl0(int scrn_idx); + private native int getVirtualOriginX0(); + private native int getVirtualOriginY0(); + private native int getVirtualWidthImpl0(); + private native int getVirtualHeightImpl0(); - private native int[] getScreenMode0(int screen_index, int mode_index); - private native boolean setScreenMode0(int screen_index, int width, int height, int bits, int freq, int rot); + private static native void dumpMonitorInfo0(); + private native String getAdapterName0(int crt_index); + private native String getActiveMonitorName0(String adapterName, int crtModeIdx); + private native int[] getMonitorMode0(String adapterName, int crtModeIdx); + private native int[] getMonitorDevice0(String adapterName, int monitor_index); + private native boolean setMonitorMode0(int monitor_index, int x, int y, int width, int height, int bits, int freq, int flags, int rot); } diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR.java b/src/newt/classes/jogamp/newt/driver/x11/RandR.java index 485d976ec..c569e5fd8 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/RandR.java +++ b/src/newt/classes/jogamp/newt/driver/x11/RandR.java @@ -27,13 +27,50 @@ */ package jogamp.newt.driver.x11; -import com.jogamp.newt.ScreenMode; +import java.util.List; + +import jogamp.newt.MonitorModeProps; + +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; public interface RandR { - int[] getScreenModeFirstImpl(final long dpy, final int screen_idx); - int[] getScreenModeNextImpl(final long dpy, final int screen_idx); - ScreenMode getCurrentScreenModeImpl(final long dpy, final int screen_idx); - boolean setCurrentScreenModeImpl(final long dpy, final int screen_idx, final ScreenMode screenMode, final int screenModeIdx, final int resolutionIdx); + void dumpInfo(final long dpy, final int screen_idx); + + /** + * Encapsulate initial device query allowing caching of internal data structures. + * Methods covered: + *
      + *
    • {@link #getMonitorDeviceCount(long, ScreenDriver)}
    • + *
    • {@link #getAvailableRotations(long, ScreenDriver, int)}
    • + *
    • {@link #getMonitorModeProps(long, ScreenDriver, int)}
    • + *
    • {@link #getCurrentMonitorModeProps(long, ScreenDriver, int)
    • + *
    • {@link #getMonitorDeviceProps(long, ScreenDriver, List, int, MonitorMode)}
    • + *
    + *

    + * Above methods may be called w/o begin/end, in which case no + * internal data structures can be cached: + *

    + * @param dpy TODO + * @param screen TODO + * @return TODO + */ + boolean beginInitialQuery(long dpy, ScreenDriver screen); + void endInitialQuery(long dpy, ScreenDriver screen); + int getMonitorDeviceCount(final long dpy, final ScreenDriver screen); + int[] getAvailableRotations(final long dpy, final ScreenDriver screen, final int crt_idx); + /** + * + * @param dpy + * @param screen + * @param mode_idx w/o indexing rotation + * @return props w/o actual rotation + */ + int[] getMonitorModeProps(final long dpy, final ScreenDriver screen, final int mode_idx); + int[] getMonitorDeviceProps(final long dpy, final ScreenDriver screen, MonitorModeProps.Cache cache, final int crt_idx); + int[] getMonitorDeviceViewport(final long dpy, final ScreenDriver screen, final int crt_idx); + int[] getCurrentMonitorModeProps(final long dpy, final ScreenDriver screen, final int crt_idx); + boolean setCurrentMonitorMode(final long dpy, final ScreenDriver screen, MonitorDevice monitor, final MonitorMode mode); } diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR11.java b/src/newt/classes/jogamp/newt/driver/x11/RandR11.java index ee67bd304..a938b4064 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/RandR11.java +++ b/src/newt/classes/jogamp/newt/driver/x11/RandR11.java @@ -27,139 +27,257 @@ */ package jogamp.newt.driver.x11; +import jogamp.newt.MonitorModeProps; import jogamp.newt.ScreenImpl; -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.util.ScreenModeUtil; +import com.jogamp.common.util.VersionNumber; +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; public class RandR11 implements RandR { private static final boolean DEBUG = ScreenDriver.DEBUG; - private int[] nrotations; - private int nrotation_index; - private int nres_number; - private int nres_index; - private int[] nrates; - private int nrate_index; - private int nmode_number; + public static VersionNumber version = new VersionNumber(1, 1, 0); + + public static RandR11 createInstance(VersionNumber rAndRVersion) { + if( rAndRVersion.compareTo(version) >= 0 ) { + return new RandR11(); + } + return null; + } + private RandR11() { + } + + @Override + public void dumpInfo(final long dpy, final int screen_idx) { + // NOP + } + + private int widthMM=0, heightMM=0; + private int modeCount = 0; + private int resolutionCount = 0; + private int[][] nrates = null; // [nres_number][nrate_number] + private int[] idx_rate = null, idx_res = null; @Override - public int[] getScreenModeFirstImpl(final long dpy, final int screen_idx) { + public boolean beginInitialQuery(long dpy, ScreenDriver screen) { // initialize iterators and static data - nrotations = getAvailableScreenModeRotations0(dpy, screen_idx); - if(null==nrotations || 0==nrotations.length) { - return null; + final int screen_idx = screen.getIndex(); + resolutionCount = getNumScreenResolutions0(dpy, screen_idx); + if(0==resolutionCount) { + endInitialQuery(dpy, screen); + return false; } - nrotation_index = 0; - nres_number = getNumScreenModeResolutions0(dpy, screen_idx); - if(0==nres_number) { - return null; + nrates = new int[resolutionCount][]; + for(int i=0; i= modeCount ) { + return null; + } + final int screen_idx = screen.getIndex(); + + final int nres_index = idx_res[mode_idx]; + final int nrate_index = idx_rate[mode_idx]; + + final int[] res = getScreenResolution0(dpy, screen_idx, nres_index); if(null==res || 0==res.length) { return null; } if(0>=res[0] || 0>=res[1]) { - throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_index+"/"+nres_number); + throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_index+"/"+resolutionCount); + } + if( res[2] > widthMM ) { + widthMM = res[2]; } - int rate = nrates[nrate_index]; + if( res[3] > heightMM ) { + heightMM = res[3]; + } + + int rate = nrates[nres_index][nrate_index]; if(0>=rate) { rate = ScreenImpl.default_sm_rate; if(DEBUG) { System.err.println("Invalid rate: "+rate+" at index "+nrate_index+"/"+nrates.length+", using default: "+ScreenImpl.default_sm_rate); } } - int rotation = nrotations[nrotation_index]; - int[] props = new int[ 1 + ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL ]; + int[] props = new int[ MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL ]; int i = 0; - props[i++] = nres_index; // use resolution index, not unique for native -> ScreenMode - props[i++] = 0; // set later for verification of iterator + props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL; props[i++] = res[0]; // width props[i++] = res[1]; // height - props[i++] = ScreenImpl.default_sm_bpp; // FIXME - props[i++] = res[2]; // widthmm - props[i++] = res[3]; // heightmm - props[i++] = rate; // rate - props[i++] = rotation; - props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i - 1; // count without extra element - - nmode_number++; - - // iteration: r -> f -> bpp -> [w x h] - nrotation_index++; - if(nrotation_index == nrotations.length) { - nrotation_index=0; - nrate_index++; - if(null == nrates || nrate_index == nrates.length){ - nres_index++; - if(nres_index == nres_number) { - // done - nrates=null; - nrotations=null; - return null; - } - - nrates = getScreenModeRates0(dpy, screen_idx, nres_index); - if(null==nrates || 0==nrates.length) { - return null; - } - nrate_index = 0; - } + props[i++] = ScreenImpl.default_sm_bpp; // bpp n/a in RandR11 + props[i++] = rate*100; // rate (Hz*100) + props[i++] = 0; // flags; + props[i++] = nres_index; + props[i++] = -1; // rotation placeholder; + if( MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL != i ) { + throw new InternalError("XX"); + } + return props; + } + + @Override + public int[] getMonitorDeviceProps(final long dpy, final ScreenDriver screen, final MonitorModeProps.Cache cache, final int crt_idx) { + if( 0 < crt_idx ) { + // RandR11 only supports 1 CRT + return null; + } + final int[] currentModeProps = getCurrentMonitorModeProps(dpy, screen, crt_idx); + if( null == currentModeProps) { // disabled + return null; + } + final MonitorMode currentMode = MonitorModeProps.streamInMonitorMode(null, cache, currentModeProps, 0); + final int allModesCount = cache.monitorModes.size(); + final int[] props = new int[MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES - 1 + allModesCount]; + int i = 0; + props[i++] = props.length; + props[i++] = crt_idx; + props[i++] = widthMM; + props[i++] = heightMM; + props[i++] = 0; // rotated viewport x + props[i++] = 0; // rotated viewport y + props[i++] = currentMode.getRotatedWidth(); // rotated viewport width + props[i++] = currentMode.getRotatedHeight(); // rotated viewport height + props[i++] = currentMode.getId(); // current mode id + props[i++] = currentMode.getRotation(); + for(int j=0; jnres_idx) { + return null; + } + if(nres_idx>=resNumber) { + throw new RuntimeException("Invalid resolution index: ! "+nres_idx+" < "+resNumber); + } + res = getScreenResolution0(dpy, screen_idx, nres_idx); + if(null==res || 0==res.length) { + return null; + } + if(0>=res[0] || 0>=res[1]) { + throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_idx+"/"+resNumber); + } + } finally { + freeScreenConfiguration0(screenConfigHandle); + } + int[] props = new int[4]; + int i = 0; + props[i++] = 0; + props[i++] = 0; + props[i++] = res[0]; // width + props[i++] = res[1]; // height + return props; + } + @Override - public ScreenMode getCurrentScreenModeImpl(final long dpy, final int screen_idx) { + public int[] getCurrentMonitorModeProps(final long dpy, final ScreenDriver screen, final int crt_idx) { + if( 0 < crt_idx ) { + // RandR11 only supports 1 CRT + return null; + } + final int screen_idx = screen.getIndex(); long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx); if(0 == screenConfigHandle) { return null; } int[] res; int rate, rot; + final int nres_idx; try { - int resNumber = getNumScreenModeResolutions0(dpy, screen_idx); + int resNumber = getNumScreenResolutions0(dpy, screen_idx); if(0==resNumber) { return null; } - int resIdx = getCurrentScreenResolutionIndex0(screenConfigHandle); - if(0>resIdx) { + nres_idx = getCurrentScreenResolutionIndex0(screenConfigHandle); + if(0>nres_idx) { return null; } - if(resIdx>=resNumber) { - throw new RuntimeException("Invalid resolution index: ! "+resIdx+" < "+resNumber); + if(nres_idx>=resNumber) { + throw new RuntimeException("Invalid resolution index: ! "+nres_idx+" < "+resNumber); } - res = getScreenModeResolution0(dpy, screen_idx, resIdx); + res = getScreenResolution0(dpy, screen_idx, nres_idx); if(null==res || 0==res.length) { return null; } if(0>=res[0] || 0>=res[1]) { - throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+resIdx+"/"+resNumber); + throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_idx+"/"+resNumber); } rate = getCurrentScreenRate0(screenConfigHandle); if(0>rate) { @@ -172,40 +290,42 @@ public class RandR11 implements RandR { } finally { freeScreenConfiguration0(screenConfigHandle); } - int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL]; + int[] props = new int[ MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL ]; int i = 0; - props[i++] = 0; // set later for verification of iterator + props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL; props[i++] = res[0]; // width props[i++] = res[1]; // height - props[i++] = ScreenImpl.default_sm_bpp; // FIXME - props[i++] = res[2]; // widthmm - props[i++] = res[3]; // heightmm - props[i++] = rate; // rate + props[i++] = ScreenImpl.default_sm_bpp; + props[i++] = rate*100; // rate (Hz*100) + props[i++] = 0; // flags; + props[i++] = nres_idx; // mode_idx; props[i++] = rot; - props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i; // count - return ScreenModeUtil.streamIn(props, 0); + if( MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL != i ) { + throw new InternalError("XX"); + } + return props; } @Override - public boolean setCurrentScreenModeImpl(final long dpy, final int screen_idx, final ScreenMode screenMode, final int screenModeIdx, final int resolutionIdx) { + public boolean setCurrentMonitorMode(final long dpy, final ScreenDriver screen, MonitorDevice monitor, final MonitorMode mode) { final long t0 = System.currentTimeMillis(); boolean done = false; + final int screen_idx = screen.getIndex(); long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx); if(0 == screenConfigHandle) { return Boolean.valueOf(done); } try { - int resNumber = getNumScreenModeResolutions0(dpy, screen_idx); - if(0>resolutionIdx || resolutionIdx>=resNumber) { - throw new RuntimeException("Invalid resolution index: ! 0 < "+resolutionIdx+" < "+resNumber+", screenMode["+screenModeIdx+"] "+screenMode); - } - - final int f = screenMode.getMonitorMode().getRefreshRate(); - final int r = screenMode.getRotation(); + final int resId = mode.getId(); + if(0>resId || resId>=resolutionCount) { + throw new RuntimeException("Invalid resolution index: ! 0 < "+resId+" < "+resolutionCount+", "+monitor+", "+mode); + } + final int f = (int)mode.getRefreshRate(); // simply cut-off, orig is int + final int r = mode.getRotation(); - if( setCurrentScreenModeStart0(dpy, screen_idx, screenConfigHandle, resolutionIdx, f, r) ) { + if( setCurrentScreenModeStart0(dpy, screen_idx, screenConfigHandle, resId, f, r) ) { while(!done && System.currentTimeMillis()-t0 < ScreenImpl.SCREEN_MODE_CHANGE_TIMEOUT) { - done = setCurrentScreenModePollEnd0(dpy, screen_idx, resolutionIdx, f, r); + done = setCurrentScreenModePollEnd0(dpy, screen_idx, resId, f, r); if(!done) { try { Thread.sleep(10); } catch (InterruptedException e) { } } @@ -218,14 +338,14 @@ public class RandR11 implements RandR { } /** @return int[] { rot1, .. } */ - private static native int[] getAvailableScreenModeRotations0(long display, int screen_index); + private static native int[] getAvailableScreenRotations0(long display, int screen_index); - private static native int getNumScreenModeResolutions0(long display, int screen_index); + private static native int getNumScreenResolutions0(long display, int screen_index); /** @return int[] { width, height, widthmm, heightmm } */ - private static native int[] getScreenModeResolution0(long display, int screen_index, int mode_index); + private static native int[] getScreenResolution0(long display, int screen_index, int mode_index); - private static native int[] getScreenModeRates0(long display, int screen_index, int mode_index); + private static native int[] getScreenRates0(long display, int screen_index, int mode_index); private static native long getScreenConfiguration0(long display, int screen_index); private static native void freeScreenConfiguration0(long screenConfiguration); diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR13.java b/src/newt/classes/jogamp/newt/driver/x11/RandR13.java index 24c9806af..d10591381 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/RandR13.java +++ b/src/newt/classes/jogamp/newt/driver/x11/RandR13.java @@ -27,25 +27,283 @@ */ package jogamp.newt.driver.x11; -import com.jogamp.newt.ScreenMode; +import java.util.Iterator; +import jogamp.newt.MonitorModeProps; + +import com.jogamp.common.util.IntLongHashMap; +import com.jogamp.common.util.VersionNumber; +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; + +/** + * Mapping details: + *
    + * MonitorMode.id   == XRR mode-id (not index)
    + * MonitorDevice.id == XRR monitor-idx (not id)
    + * 
    + */ public class RandR13 implements RandR { + private static final boolean DEBUG = ScreenDriver.DEBUG; + + public static VersionNumber version = new VersionNumber(1, 3, 0); - public int[] getScreenModeFirstImpl(final long dpy, final int screen_idx) { + public static RandR13 createInstance(VersionNumber rAndRVersion) { + if( rAndRVersion.compareTo(version) >= 0 ) { + return new RandR13(); + } return null; + } + private RandR13() { + } + + @Override + public void dumpInfo(final long dpy, final int screen_idx) { + long screenResources = getScreenResources0(dpy, screen_idx); + if(0 == screenResources) { + return; + } + try { + dumpInfo0(dpy, screen_idx, screenResources); + } finally { + freeScreenResources0(screenResources); + } + } + + long sessionScreenResources = 0; + IntLongHashMap crtInfoHandleMap = null; + + @Override + public boolean beginInitialQuery(long dpy, ScreenDriver screen) { + final int screen_idx = screen.getIndex(); + sessionScreenResources = getScreenResources0(dpy, screen_idx); + if( 0 != sessionScreenResources ) { + crtInfoHandleMap = new IntLongHashMap(); + crtInfoHandleMap.setKeyNotFoundValue(0); + return true; + } else { + return false; + } + } + + @Override + public void endInitialQuery(long dpy, ScreenDriver screen) { + if( null != crtInfoHandleMap ) { + for(Iterator iter = crtInfoHandleMap.iterator(); iter.hasNext(); ) { + final IntLongHashMap.Entry entry = iter.next(); + freeMonitorInfoHandle0(entry.value); + } + crtInfoHandleMap.clear(); + crtInfoHandleMap = null; + } + if( 0 != sessionScreenResources ) { + freeScreenResources0( sessionScreenResources ); + sessionScreenResources = 0; + } } - public int[] getScreenModeNextImpl(final long dpy, final int screen_idx) { - return null; + + private final long getScreenResourceHandle(final long dpy, final int screen_idx) { + if( 0 != sessionScreenResources ) { + return sessionScreenResources; + } + return getScreenResources0(dpy, screen_idx); + } + private final void releaseScreenResourceHandle(final long screenResourceHandle) { + if( 0 == sessionScreenResources ) { + freeScreenResources0( screenResourceHandle ); + } } - public ScreenMode getCurrentScreenModeImpl(final long dpy, final int screen_idx) { - return null; + + private final long getMonitorInfoHandle(final long dpy, final int screen_idx, long screenResources, final int monitor_idx) { + if( null != crtInfoHandleMap ) { + long h = crtInfoHandleMap.get(monitor_idx); + if( 0 == h ) { + h = getMonitorInfoHandle0(dpy, screen_idx, screenResources, monitor_idx); + crtInfoHandleMap.put(monitor_idx, h); + } + return h; + } else { + return getMonitorInfoHandle0(dpy, screen_idx, screenResources, monitor_idx); + } } + private final void releaseMonitorInfoHandle(final long monitorInfoHandle) { + if( null == crtInfoHandleMap ) { + freeMonitorInfoHandle0(monitorInfoHandle); + } + } - public boolean setCurrentScreenModeImpl(final long dpy, final int screen_idx, final ScreenMode screenMode, final int screenModeIdx, final int resolutionIdx) { - return false; + @Override + public int getMonitorDeviceCount(final long dpy, final ScreenDriver screen) { + final int screen_idx = screen.getIndex(); + final long screenResources = getScreenResourceHandle(dpy, screen_idx); + try { + return getMonitorDeviceCount0(screenResources); + } finally { + releaseScreenResourceHandle(screenResources); + } } + @Override + public int[] getAvailableRotations(final long dpy, final ScreenDriver screen, final int crt_idx) { + final int screen_idx = screen.getIndex(); + final long screenResources = getScreenResourceHandle(dpy, screen_idx); + try { + final long monitorInfo = getMonitorInfoHandle(dpy, screen_idx, screenResources, crt_idx); + try { + final int[] availRotations = getAvailableRotations0(monitorInfo); + if(null==availRotations || 0==availRotations.length) { + return null; + } + return availRotations; + } finally { + releaseMonitorInfoHandle(monitorInfo); + } + } finally { + releaseScreenResourceHandle(screenResources); + } + } + + @Override + public int[] getMonitorModeProps(final long dpy, final ScreenDriver screen, final int mode_idx) { + final int screen_idx = screen.getIndex(); + final long screenResources = getScreenResourceHandle(dpy, screen_idx); + try { + return getMonitorMode0(screenResources, mode_idx); + } finally { + releaseScreenResourceHandle(screenResources); + } + } + + @Override + public int[] getMonitorDeviceProps(final long dpy, final ScreenDriver screen, MonitorModeProps.Cache cache, final int crt_idx) { + final int screen_idx = screen.getIndex(); + final long screenResources = getScreenResourceHandle(dpy, screen_idx); + try { + final long monitorInfo = getMonitorInfoHandle(dpy, screen_idx, screenResources, crt_idx); + try { + return getMonitorDevice0(dpy, screenResources, monitorInfo, crt_idx); + } finally { + releaseMonitorInfoHandle(monitorInfo); + } + } finally { + releaseScreenResourceHandle(screenResources); + } + } + + @Override + public int[] getMonitorDeviceViewport(final long dpy, final ScreenDriver screen, final int crt_idx) { + final int screen_idx = screen.getIndex(); + final long screenResources = getScreenResourceHandle(dpy, screen_idx); + try { + final long monitorInfo = getMonitorInfoHandle(dpy, screen_idx, screenResources, crt_idx); + try { + return getMonitorViewport0(monitorInfo); + } finally { + releaseMonitorInfoHandle(monitorInfo); + } + } finally { + releaseScreenResourceHandle(screenResources); + } + } + + @Override + public int[] getCurrentMonitorModeProps(final long dpy, final ScreenDriver screen, final int crt_idx) { + final int screen_idx = screen.getIndex(); + final long screenResources = getScreenResourceHandle(dpy, screen_idx); + try { + final long monitorInfo = getMonitorInfoHandle(dpy, screen_idx, screenResources, crt_idx); + try { + return getMonitorCurrentMode0(screenResources, monitorInfo); + } finally { + releaseMonitorInfoHandle(monitorInfo); + } + } finally { + releaseScreenResourceHandle(screenResources); + } + } + + @Override + public boolean setCurrentMonitorMode(final long dpy, final ScreenDriver screen, MonitorDevice monitor, final MonitorMode mode) { + final int screen_idx = screen.getIndex(); + final long screenResources = getScreenResourceHandle(dpy, screen_idx); + final boolean res; + try { + final long monitorInfo = getMonitorInfoHandle(dpy, screen_idx, screenResources, monitor.getId()); + try { + res = setMonitorMode0(dpy, screenResources, monitorInfo, monitor.getId(), mode.getId(), mode.getRotation(), + -1, -1); // no fixed position! + } finally { + releaseMonitorInfoHandle(monitorInfo); + } + } finally { + releaseScreenResourceHandle(screenResources); + } + /*** + * TODO: Would need a complete re-layout of crt positions, + * which is _not_ implicit by XRandR .. sadly. + * + if( res ) { + updateScreenViewport(dpy, screen, monitor); + } */ + return res; + } + + /** See above .. + private final void updateScreenViewport(final long dpy, final ScreenDriver screen, MonitorDevice monitor) { + final int screen_idx = screen.getIndex(); + final long screenResources = getScreenResourceHandle(dpy, screen_idx); + try { + RectangleImmutable newViewp = null; + final long monitorInfo = getMonitorInfoHandle(dpy, screen_idx, screenResources, monitor.getId()); + try { + final int[] vprops = getMonitorViewport0(monitorInfo); + if( null != vprops ) { + newViewp = new Rectangle(vprops[0], vprops[1], vprops[2], vprops[3]); + } + System.err.println("XXX setScreenViewport: newVp "+newViewp); + } finally { + releaseMonitorInfoHandle(monitorInfo); + } + if( null != newViewp ) { + final List monitors = screen.getMonitorDevices(); + final ArrayList viewports = new ArrayList(); + for(int i=0; i "+newScrnViewp); + setScreenViewport0(dpy, screen_idx, screenResources, newScrnViewp.getX(), newScrnViewp.getY(), newScrnViewp.getWidth(), newScrnViewp.getHeight()); + } + } finally { + dumpInfo0(dpy, screen_idx, screenResources); + releaseScreenResourceHandle(screenResources); + } + } */ + private static native long getScreenResources0(long display, int screen_index); - private static native void freeScreenResources0(long screenConfiguration); + private static native void freeScreenResources0(long screenResources); + private static native void dumpInfo0(long display, int screen_index, long screenResources); + + private static native int getMonitorDeviceCount0(long screenResources); + + private static native long getMonitorInfoHandle0(long display, int screen_index, long screenResources, int monitor_index); + private static native void freeMonitorInfoHandle0(long monitorInfoHandle); + + private static native int[] getAvailableRotations0(long monitorInfo); + private static native int[] getMonitorViewport0(long monitorInfo); + private static native int[] getMonitorCurrentMode0(long monitorInfo); + + private static native int[] getMonitorMode0(long screenResources, int mode_index); + private static native int[] getMonitorCurrentMode0(long screenResources, long monitorInfo); + private static native int[] getMonitorDevice0(long display, long screenResources, long monitorInfo, int monitor_idx); + private static native boolean setMonitorMode0(long display, long screenResources, long monitorInfo, int monitor_idx, int mode_id, int rotation, int x, int y); + private static native boolean setScreenViewport0(long display, int screen_index, long screenResources, int x, int y, int width, int height); } diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java index cd8da9b60..ba22a6ce4 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java @@ -33,23 +33,29 @@ */ package jogamp.newt.driver.x11; +import java.util.ArrayList; import java.util.List; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.Point; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.util.Rectangle; import jogamp.nativewindow.x11.X11Util; +import jogamp.newt.Debug; import jogamp.newt.DisplayImpl; +import jogamp.newt.MonitorModeProps; import jogamp.newt.DisplayImpl.DisplayRunnable; import jogamp.newt.ScreenImpl; +import com.jogamp.common.util.ArrayHashSet; import com.jogamp.common.util.VersionNumber; import com.jogamp.nativewindow.x11.X11GraphicsDevice; import com.jogamp.nativewindow.x11.X11GraphicsScreen; -import com.jogamp.newt.ScreenMode; - -public class ScreenDriver extends ScreenImpl { +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; +public class ScreenDriver extends ScreenImpl { + protected static final boolean DEBUG_TEST_RANDR13_DISABLED = Debug.isPropertyDefined("newt.test.Screen.disableRandR13", true); + static { DisplayDriver.initSingleton(); } @@ -57,12 +63,13 @@ public class ScreenDriver extends ScreenImpl { public ScreenDriver() { } + @Override protected void createNativeImpl() { // validate screen index Long handle = runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { public Long run(long dpy) { return new Long(GetScreen0(dpy, screen_idx)); - } } ); + } } ); if (handle.longValue() == 0) { throw new RuntimeException("Error creating screen: " + screen_idx); } @@ -73,73 +80,116 @@ public class ScreenDriver extends ScreenImpl { int v[] = getRandRVersion0(dpy); randrVersion = new VersionNumber(v[0], v[1], 0); } - if( DEBUG ) { - System.err.println("RandR "+randrVersion); + { + final RandR13 rAndR13 = DEBUG_TEST_RANDR13_DISABLED ? null : RandR13.createInstance(randrVersion); + if( null != rAndR13 ) { + rAndR = rAndR13; + } else { + rAndR = RandR11.createInstance(randrVersion); + } } - if( !randrVersion.isZero() ) { - rAndR = new RandR11(); - } else { - rAndR = null; + if( DEBUG ) { + System.err.println("RandR "+randrVersion+", "+rAndR); + rAndR.dumpInfo(dpy, screen_idx); } } + @Override protected void closeNativeImpl() { } private VersionNumber randrVersion; private RandR rAndR; - + @Override - protected int[] getScreenModeFirstImpl() { - if( null == rAndR ) { return null; } - - return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { - public int[] run(long dpy) { - return rAndR.getScreenModeFirstImpl(dpy, screen_idx); - } } ); + protected final void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) { + if( null == rAndR ) { return; } + final AbstractGraphicsDevice device = getDisplay().getGraphicsDevice(); + device.lock(); + try { + if( rAndR.beginInitialQuery(device.getHandle(), this) ) { + try { + final int crtCount = rAndR.getMonitorDeviceCount(device.getHandle(), this); + + // Gather all available rotations + final ArrayHashSet availableRotations = new ArrayHashSet(); + for(int i = 0; i < crtCount; i++) { + final int[] rotations = rAndR.getAvailableRotations(device.getHandle(), this, i); + if( null != rotations ) { + final List rotationList = new ArrayList(rotations.length); + for(int j=0; j 0 ) { + for(int i = 0; i < crtCount; i++) { + final int[] monitorProps = rAndR.getMonitorDeviceProps(device.getHandle(), this, cache, i); + if( null != monitorProps ) { // enabled + MonitorModeProps.streamInMonitorDevice(null, cache, this, monitorProps, 0); + } + } + } + } finally { + rAndR.endInitialQuery(device.getHandle(), this); + } + } + } finally { + device.unlock(); + } } @Override - protected int[] getScreenModeNextImpl() { - if( null == rAndR ) { return null; } - - // assemble: w x h x bpp x f x r - return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { - public int[] run(long dpy) { - return rAndR.getScreenModeNextImpl(dpy, screen_idx); - } } ); + protected Rectangle getNativeMonitorDeviceViewportImpl(MonitorDevice monitor) { + final AbstractGraphicsDevice device = getDisplay().getGraphicsDevice(); + device.lock(); + try { + int[] viewportProps = rAndR.getMonitorDeviceViewport(device.getHandle(), this, monitor.getId()); + return new Rectangle(viewportProps[0], viewportProps[1], viewportProps[2], viewportProps[3]); + } finally { + device.unlock(); + } } - + @Override - protected ScreenMode getCurrentScreenModeImpl() { + protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) { if( null == rAndR ) { return null; } - return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { - public ScreenMode run(long dpy) { - return rAndR.getCurrentScreenModeImpl(dpy, screen_idx); + return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { + public MonitorMode run(long dpy) { + final int[] currentModeProps = rAndR.getCurrentMonitorModeProps(dpy, ScreenDriver.this, monitor.getId()); + return MonitorModeProps.streamInMonitorMode(null, null, currentModeProps, 0); } } ); } @Override - protected boolean setCurrentScreenModeImpl(final ScreenMode screenMode) { + protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) { if( null == rAndR ) { return false; } - final List screenModes = this.getScreenModesOrig(); - final int screenModeIdx = screenModes.indexOf(screenMode); - if(0>screenModeIdx) { - throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode); - } final long t0 = System.currentTimeMillis(); boolean done = runWithTempDisplayHandle( new DisplayImpl.DisplayRunnable() { public Boolean run(long dpy) { - final int resIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx); - return Boolean.valueOf( rAndR.setCurrentScreenModeImpl(dpy, screen_idx, screenMode, screenModeIdx, resIdx) ); + return Boolean.valueOf( rAndR.setCurrentMonitorMode(dpy, ScreenDriver.this, monitor, mode) ); } }).booleanValue(); if(DEBUG || !done) { System.err.println("X11Screen.setCurrentScreenModeImpl: TO ("+SCREEN_MODE_CHANGE_TIMEOUT+") reached: "+ - (System.currentTimeMillis()-t0)+"ms; Current: "+getCurrentScreenMode()+"; Desired: "+screenMode); + (System.currentTimeMillis()-t0)+"ms; "+monitor.getCurrentMode()+" -> "+mode); } return done; } @@ -149,6 +199,7 @@ public class ScreenDriver extends ScreenImpl { return new Boolean(X11Util.XineramaIsEnabled(dpy)); } }; + @Override protected int validateScreenIndex(final int idx) { final DisplayDriver x11Display = (DisplayDriver) getDisplay(); final Boolean r = x11Display.isXineramaEnabled(); @@ -159,13 +210,14 @@ public class ScreenDriver extends ScreenImpl { } } - protected void getVirtualScreenOriginAndSize(final Point virtualOrigin, final Dimension virtualSize) { + @Override + protected void calcVirtualScreenOriginAndSize(final Rectangle vOriginSize) { runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { public Object run(long dpy) { - virtualOrigin.setX(0); - virtualOrigin.setY(0); - virtualSize.setWidth(getWidth0(dpy, screen_idx)); - virtualSize.setHeight(getHeight0(dpy, screen_idx)); + vOriginSize.setX(0); + vOriginSize.setY(0); + vOriginSize.setWidth(getWidth0(dpy, screen_idx)); + vOriginSize.setHeight(getHeight0(dpy, screen_idx)); return null; } } ); } 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; icrtc, SAFE_STRING(xrrOutputInfo->name), xrrOutputInfo->nameLen, xrrOutputInfo->mm_width, xrrOutputInfo->mm_height, + xrrOutputInfo->ncrtc, xrrOutputInfo->nmode, xrrOutputInfo->npreferred); + for(j=0; jnmode; 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; incrtc; 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; incrtc; 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; jnoutput; 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; inmode; 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; incrtc; 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; inmode; 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; inmode; 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; imodes[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 ) ; } /* diff --git a/src/test/com/jogamp/opengl/test/android/NEWTElektronActivity.java b/src/test/com/jogamp/opengl/test/android/NEWTElektronActivity.java index 0dead125a..88cd9a719 100644 --- a/src/test/com/jogamp/opengl/test/android/NEWTElektronActivity.java +++ b/src/test/com/jogamp/opengl/test/android/NEWTElektronActivity.java @@ -32,8 +32,8 @@ import javax.media.opengl.GLProfile; import jogamp.newt.driver.android.NewtBaseActivity; -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.event.ScreenModeListener; +import com.jogamp.newt.event.MonitorEvent; +import com.jogamp.newt.event.MonitorModeListener; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.test.junit.jogl.demos.es2.ElektronenMultiplizierer; @@ -58,11 +58,13 @@ public class NEWTElektronActivity extends NewtBaseActivity { setContentView(getWindow(), glWindow); glWindow.addGLEventListener(new ElektronenMultiplizierer()); - glWindow.getScreen().addScreenModeListener(new ScreenModeListener() { - public void screenModeChangeNotify(ScreenMode sm) { } - public void screenModeChanged(ScreenMode sm, boolean success) { - System.err.println("ScreenMode Changed: "+sm); - } + glWindow.getScreen().addMonitorModeListener(new MonitorModeListener() { + @Override + public void monitorModeChangeNotify(MonitorEvent me) { } + @Override + public void monitorModeChanged(MonitorEvent me, boolean success) { + System.err.println("MonitorMode Changed (success "+success+"): "+me); + } }); glWindow.setVisible(true); Animator animator = new Animator(glWindow); diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES1Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES1Activity.java index c020413cf..f10cfc11f 100644 --- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES1Activity.java +++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES1Activity.java @@ -32,8 +32,8 @@ import javax.media.opengl.GLProfile; import jogamp.newt.driver.android.NewtBaseActivity; -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.event.ScreenModeListener; +import com.jogamp.newt.event.MonitorEvent; +import com.jogamp.newt.event.MonitorModeListener; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.test.junit.jogl.demos.es1.GearsES1; @@ -63,11 +63,13 @@ public class NEWTGearsES1Activity extends NewtBaseActivity { setContentView(getWindow(), glWindow); glWindow.addGLEventListener(new GearsES1(-1)); - glWindow.getScreen().addScreenModeListener(new ScreenModeListener() { - public void screenModeChangeNotify(ScreenMode sm) { } - public void screenModeChanged(ScreenMode sm, boolean success) { - System.err.println("ScreenMode Changed: "+sm); - } + glWindow.getScreen().addMonitorModeListener(new MonitorModeListener() { + @Override + public void monitorModeChangeNotify(MonitorEvent me) { } + @Override + public void monitorModeChanged(MonitorEvent me, boolean success) { + System.err.println("MonitorMode Changed (success "+success+"): "+me); + } }); glWindow.setVisible(true); Animator animator = new Animator(glWindow); diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java index 542912c08..2e9774565 100644 --- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java +++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java @@ -36,10 +36,10 @@ import javax.media.opengl.GLProfile; import jogamp.newt.driver.android.NewtBaseActivity; -import com.jogamp.newt.ScreenMode; +import com.jogamp.newt.event.MonitorEvent; import com.jogamp.newt.event.MouseAdapter; import com.jogamp.newt.event.MouseEvent; -import com.jogamp.newt.event.ScreenModeListener; +import com.jogamp.newt.event.MonitorModeListener; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; @@ -75,11 +75,13 @@ public class NEWTGearsES2Activity extends NewtBaseActivity { GearsES2 demo = new GearsES2(-1); // demo.enableAndroidTrace(true); glWindow.addGLEventListener(demo); - glWindow.getScreen().addScreenModeListener(new ScreenModeListener() { - public void screenModeChangeNotify(ScreenMode sm) { } - public void screenModeChanged(ScreenMode sm, boolean success) { - System.err.println("ScreenMode Changed: "+sm); - } + glWindow.getScreen().addMonitorModeListener(new MonitorModeListener() { + @Override + public void monitorModeChangeNotify(MonitorEvent me) { } + @Override + public void monitorModeChanged(MonitorEvent me, boolean success) { + System.err.println("MonitorMode Changed (success "+success+"): "+me); + } }); if( null != System.getProperty(forceKillProcessTest) ) { Log.d(TAG, "forceKillProcessTest"); diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java index 5e7a5c489..c87e66189 100644 --- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java +++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java @@ -57,6 +57,7 @@ public class NEWTGearsES2ActivityLauncher extends LauncherUtil.BaseActivityLaunc // props.setProperty("jogl.debug.DebugGL", "true"); // props.setProperty("jogl.debug.TraceGL", "true"); // props.setProperty("newt.debug", "all"); + props.setProperty("newt.debug.Screen", "true"); props.setProperty("newt.debug.Window", "true"); props.setProperty("newt.debug.Window.MouseEvent", "true"); props.setProperty("newt.debug.Window.KeyEvent", "true"); diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java index 18c3cb042..98e6b7c5f 100644 --- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java +++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java @@ -34,8 +34,8 @@ import jogamp.newt.driver.android.NewtBaseActivity; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Screen; -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.event.ScreenModeListener; +import com.jogamp.newt.event.MonitorEvent; +import com.jogamp.newt.event.MonitorModeListener; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; @@ -65,11 +65,13 @@ public class NEWTGearsES2TransActivity extends NewtBaseActivity { setContentView(getWindow(), glWindow); glWindow.addGLEventListener(new GearsES2(-1)); - glWindow.getScreen().addScreenModeListener(new ScreenModeListener() { - public void screenModeChangeNotify(ScreenMode sm) { } - public void screenModeChanged(ScreenMode sm, boolean success) { - System.err.println("ScreenMode Changed: "+sm); - } + glWindow.getScreen().addMonitorModeListener(new MonitorModeListener() { + @Override + public void monitorModeChangeNotify(MonitorEvent me) { } + @Override + public void monitorModeChanged(MonitorEvent me, boolean success) { + System.err.println("MonitorMode Changed (success "+success+"): "+me); + } }); Animator animator = new Animator(glWindow); // glWindow.setSkipContextReleaseThread(animator.getThread()); diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivity.java b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivity.java index bbd4f9f20..42db9d8dd 100644 --- a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivity.java +++ b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivity.java @@ -32,8 +32,8 @@ import javax.media.opengl.GLProfile; import jogamp.newt.driver.android.NewtBaseActivity; -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.event.ScreenModeListener; +import com.jogamp.newt.event.MonitorEvent; +import com.jogamp.newt.event.MonitorModeListener; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.test.junit.graph.demos.GPUUISceneGLListener0A; @@ -61,11 +61,13 @@ public class NEWTGraphUI1pActivity extends NewtBaseActivity { setContentView(getWindow(), glWindow); glWindow.addGLEventListener(new GPUUISceneGLListener0A(0)); - glWindow.getScreen().addScreenModeListener(new ScreenModeListener() { - public void screenModeChangeNotify(ScreenMode sm) { } - public void screenModeChanged(ScreenMode sm, boolean success) { - System.err.println("ScreenMode Changed: "+sm); - } + glWindow.getScreen().addMonitorModeListener(new MonitorModeListener() { + @Override + public void monitorModeChangeNotify(MonitorEvent me) { } + @Override + public void monitorModeChanged(MonitorEvent me, boolean success) { + System.err.println("MonitorMode Changed (success "+success+"): "+me); + } }); glWindow.setVisible(true); Animator animator = new Animator(glWindow); diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI2pActivity.java b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI2pActivity.java index 20ba3f484..c68de95cc 100644 --- a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI2pActivity.java +++ b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI2pActivity.java @@ -33,8 +33,8 @@ import javax.media.opengl.GLProfile; import jogamp.newt.driver.android.NewtBaseActivity; import com.jogamp.graph.curve.Region; -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.event.ScreenModeListener; +import com.jogamp.newt.event.MonitorEvent; +import com.jogamp.newt.event.MonitorModeListener; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.test.junit.graph.demos.GPUUISceneGLListener0A; @@ -62,11 +62,13 @@ public class NEWTGraphUI2pActivity extends NewtBaseActivity { setContentView(getWindow(), glWindow); glWindow.addGLEventListener(new GPUUISceneGLListener0A(Region.VBAA_RENDERING_BIT)); - glWindow.getScreen().addScreenModeListener(new ScreenModeListener() { - public void screenModeChangeNotify(ScreenMode sm) { } - public void screenModeChanged(ScreenMode sm, boolean success) { - System.err.println("ScreenMode Changed: "+sm); - } + glWindow.getScreen().addMonitorModeListener(new MonitorModeListener() { + @Override + public void monitorModeChangeNotify(MonitorEvent me) { } + @Override + public void monitorModeChanged(MonitorEvent me, boolean success) { + System.err.println("MonitorMode Changed (success "+success+"): "+me); + } }); glWindow.setVisible(true); Animator animator = new Animator(glWindow); diff --git a/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES1Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES1Activity.java index 06ce75ac5..08fbf643d 100644 --- a/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES1Activity.java +++ b/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES1Activity.java @@ -32,8 +32,8 @@ import javax.media.opengl.GLProfile; import jogamp.newt.driver.android.NewtBaseActivity; -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.event.ScreenModeListener; +import com.jogamp.newt.event.MonitorEvent; +import com.jogamp.newt.event.MonitorModeListener; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.test.junit.jogl.demos.es1.RedSquareES1; @@ -57,11 +57,13 @@ public class NEWTRedSquareES1Activity extends NewtBaseActivity { setContentView(getWindow(), glWindow); glWindow.addGLEventListener(new RedSquareES1(-1)); - glWindow.getScreen().addScreenModeListener(new ScreenModeListener() { - public void screenModeChangeNotify(ScreenMode sm) { } - public void screenModeChanged(ScreenMode sm, boolean success) { - System.err.println("ScreenMode Changed: "+sm); - } + glWindow.getScreen().addMonitorModeListener(new MonitorModeListener() { + @Override + public void monitorModeChangeNotify(MonitorEvent me) { } + @Override + public void monitorModeChanged(MonitorEvent me, boolean success) { + System.err.println("MonitorMode Changed (success "+success+"): "+me); + } }); glWindow.setVisible(true); Animator animator = new Animator(glWindow); diff --git a/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java index 02e2d8f01..cefdd842b 100644 --- a/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java +++ b/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java @@ -32,8 +32,8 @@ import javax.media.opengl.GLProfile; import jogamp.newt.driver.android.NewtBaseActivity; -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.event.ScreenModeListener; +import com.jogamp.newt.event.MonitorEvent; +import com.jogamp.newt.event.MonitorModeListener; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2; @@ -62,11 +62,13 @@ public class NEWTRedSquareES2Activity extends NewtBaseActivity { final RedSquareES2 demo = new RedSquareES2(-1); // demo.enableAndroidTrace(true); glWindow.addGLEventListener(demo); - glWindow.getScreen().addScreenModeListener(new ScreenModeListener() { - public void screenModeChangeNotify(ScreenMode sm) { } - public void screenModeChanged(ScreenMode sm, boolean success) { - System.err.println("ScreenMode Changed: "+sm); - } + glWindow.getScreen().addMonitorModeListener(new MonitorModeListener() { + @Override + public void monitorModeChangeNotify(MonitorEvent me) { } + @Override + public void monitorModeChanged(MonitorEvent me, boolean success) { + System.err.println("MonitorMode Changed (success "+success+"): "+me); + } }); Animator animator = new Animator(glWindow); // animator.setRunAsFastAsPossible(true); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java index 50f759079..4c6cae501 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java @@ -163,13 +163,25 @@ public class TestGearsES2NEWT extends UITestCase { }); glWindow.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { + @Override + public void keyPressed(final KeyEvent e) { + if( e.isAutoRepeat() ) { + return; + } if(e.getKeyChar()=='f') { new Thread() { public void run() { final Thread t = glWindow.setExclusiveContextThread(null); System.err.println("[set fullscreen pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); - glWindow.setFullscreen(!glWindow.isFullscreen()); + if( glWindow.isFullscreen() ) { + glWindow.setFullscreen( false ); + } else { + if( e.isAltDown() ) { + glWindow.setFullscreen( null ); + } else { + glWindow.setFullscreen( true ); + } + } System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); glWindow.setExclusiveContextThread(t); } }.start(); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestRulerNEWT01.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestRulerNEWT01.java index 98620e0c1..90d4a9c1f 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestRulerNEWT01.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestRulerNEWT01.java @@ -28,8 +28,8 @@ package com.jogamp.opengl.test.junit.jogl.glsl; import com.jogamp.common.nio.Buffers; -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.util.MonitorMode; +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.MonitorMode; import com.jogamp.opengl.util.GLArrayDataServer; import com.jogamp.opengl.util.PMVMatrix; import com.jogamp.opengl.util.glsl.ShaderCode; @@ -109,11 +109,13 @@ public class TestRulerNEWT01 extends UITestCase { Assert.assertNotNull(winctx); Assert.assertNotNull(winctx.window); Assert.assertNotNull(winctx.window.getScreen()); - ScreenMode sm = winctx.window.getScreen().getCurrentScreenMode(); - Assert.assertNotNull(sm); - System.err.println(sm); - final MonitorMode mmode = sm.getMonitorMode(); - final DimensionImmutable sdim = mmode.getScreenSizeMM(); + final MonitorDevice monitor = winctx.window.getMainMonitor(); + Assert.assertNotNull(monitor); + System.err.println(monitor); + final MonitorMode mmode = monitor.getCurrentMode(); + Assert.assertNotNull(mmode); + System.err.println(mmode); + final DimensionImmutable sdim = monitor.getSizeMM(); final DimensionImmutable spix = mmode.getSurfaceSize().getResolution(); final GLUniformData rulerPixFreq = new GLUniformData("gcu_RulerPixFreq", 2, Buffers.newDirectFloatBuffer(2)); final FloatBuffer rulerPixFreqV = (FloatBuffer) rulerPixFreq.getBuffer(); diff --git a/src/test/com/jogamp/opengl/test/junit/newt/ManualScreenMode03NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/ManualScreenMode03NEWT.java index 29ec443f7..a7b65545a 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/ManualScreenMode03NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/ManualScreenMode03NEWT.java @@ -35,11 +35,12 @@ import javax.media.opengl.GLProfile; import com.jogamp.opengl.util.Animator; import com.jogamp.newt.Display; +import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Screen; -import com.jogamp.newt.ScreenMode; +import com.jogamp.newt.MonitorMode; import com.jogamp.newt.opengl.GLWindow; -import com.jogamp.newt.util.ScreenModeUtil; +import com.jogamp.newt.util.MonitorModeUtil; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; import com.jogamp.opengl.test.junit.util.UITestCase; import java.util.List; @@ -72,8 +73,8 @@ public class ManualScreenMode03NEWT extends UITestCase { Screen screen = NewtFactory.createScreen(display, 0); // screen 0 GLWindow window = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); - List screenModes = screen.getScreenModes(); - if(null==screenModes) { + List monitorModes = screen.getMonitorModes(); + if(null==monitorModes) { // no support .. System.err.println("Your platform has no ScreenMode change support, sorry"); return; @@ -81,18 +82,21 @@ public class ManualScreenMode03NEWT extends UITestCase { Animator animator = new Animator(window); animator.start(); - ScreenMode smCurrent = screen.getCurrentScreenMode(); - ScreenMode smOrig = screen.getOriginalScreenMode(); - System.err.println("[0] current/orig: "+smCurrent); + MonitorDevice monitor = window.getMainMonitor(); + MonitorMode mmCurrent = monitor.queryCurrentMode(); + MonitorMode mmOrig = monitor.getOriginalMode(); + System.err.println("[0] orig : "+mmOrig); + System.err.println("[0] current: "+mmCurrent); - screenModes = ScreenModeUtil.filterByRate(screenModes, smOrig.getMonitorMode().getRefreshRate()); - screenModes = ScreenModeUtil.filterByRotation(screenModes, 0); - screenModes = ScreenModeUtil.filterByResolution(screenModes, new Dimension(801, 601)); - screenModes = ScreenModeUtil.getHighestAvailableBpp(screenModes); + monitorModes = MonitorModeUtil.filterByFlags(monitorModes, 0); // no interlace, double-scan etc + monitorModes = MonitorModeUtil.filterByRotation(monitorModes, 0); + monitorModes = MonitorModeUtil.filterByRate(monitorModes, mmOrig.getRefreshRate()); + monitorModes = MonitorModeUtil.filterByResolution(monitorModes, new Dimension(801, 601)); + monitorModes = MonitorModeUtil.getHighestAvailableBpp(monitorModes); - ScreenMode sm = (ScreenMode) screenModes.get(0); - System.err.println("[0] set current: "+sm); - screen.setCurrentScreenMode(sm); + MonitorMode mm = (MonitorMode) monitorModes.get(0); + System.err.println("[0] set current: "+mm); + monitor.setCurrentMode(mm); System.err.print("[0] post setting .. wait <"); try { diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java index 577119bcd..f64cf2eb8 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java @@ -35,18 +35,23 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import com.jogamp.common.util.ArrayHashSet; import com.jogamp.newt.Display; +import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.MonitorMode; import com.jogamp.newt.Screen; -import com.jogamp.newt.ScreenMode; -import com.jogamp.newt.util.MonitorMode; -import com.jogamp.newt.util.ScreenModeUtil; import com.jogamp.opengl.test.junit.util.UITestCase; import java.util.Iterator; import java.util.List; import javax.media.nativewindow.util.Dimension; import javax.media.nativewindow.util.DimensionImmutable; +import javax.media.nativewindow.util.Rectangle; import javax.media.nativewindow.util.SurfaceSize; +import javax.media.opengl.GLProfile; + +import jogamp.newt.MonitorDeviceImpl; +import jogamp.newt.MonitorModeProps; public class TestScreenMode00NEWT extends UITestCase { static int screenIdx = 0; @@ -59,6 +64,7 @@ public class TestScreenMode00NEWT extends UITestCase { @BeforeClass public static void initClass() { + GLProfile.initSingleton(); // hack to initialize GL for BCM_IV (Rasp.Pi) NativeWindowFactory.initSingleton(); width = 640; height = 480; @@ -66,31 +72,46 @@ public class TestScreenMode00NEWT extends UITestCase { @Test public void testScreenModeInfo00() throws InterruptedException { - DimensionImmutable res = new Dimension(640, 480); - SurfaceSize surfsz = new SurfaceSize(res, 32); - DimensionImmutable mm = new Dimension(500, 400); - MonitorMode mon = new MonitorMode(surfsz, mm, 60); - ScreenMode sm_out = new ScreenMode(mon, 90); - System.err.println("00 out: "+sm_out); - - int[] props = ScreenModeUtil.streamOut(sm_out); - ScreenMode sm_in = ScreenModeUtil.streamIn(props, 0); - System.err.println("00 in : "+sm_in); - - Assert.assertEquals(sm_in.getMonitorMode().getSurfaceSize().getResolution(), - sm_out.getMonitorMode().getSurfaceSize().getResolution()); - - Assert.assertEquals(sm_in.getMonitorMode().getSurfaceSize(), - sm_out.getMonitorMode().getSurfaceSize()); - - Assert.assertEquals(sm_in.getMonitorMode().getScreenSizeMM(), - sm_out.getMonitorMode().getScreenSizeMM()); - - Assert.assertEquals(sm_in.getMonitorMode(), sm_out.getMonitorMode()); - - Assert.assertEquals(sm_in, sm_out); + final DimensionImmutable res = new Dimension(640, 480); + final SurfaceSize surfsz = new SurfaceSize(res, 32); + final MonitorMode modeOut = new MonitorMode(surfsz, 60.0f, 0, 0); + System.err.println("00 out: "+modeOut); + final MonitorModeProps.Cache cache = new MonitorModeProps.Cache(); + cache.monitorModes.add(modeOut); + { + final int[] props = MonitorModeProps.streamOutMonitorMode(modeOut); + final MonitorMode modeIn = MonitorModeProps.streamInMonitorMode(null, cache, props, 0); + System.err.println("00 in : "+modeIn); + + Assert.assertEquals(modeOut.getSurfaceSize().getResolution(), modeIn.getSurfaceSize().getResolution()); + + Assert.assertEquals(modeOut.getSurfaceSize(), modeIn.getSurfaceSize()); + + Assert.assertEquals(modeOut.hashCode(), modeIn.hashCode()); + + Assert.assertEquals(modeOut, modeIn); + } - Assert.assertEquals(sm_out.hashCode(), sm_in.hashCode()); + final DimensionImmutable sizeMM = new Dimension(50, 50); + final Rectangle viewport = new Rectangle(0, 0, 1920, 1080); + final ArrayHashSet supportedModes = new ArrayHashSet(); + supportedModes.add(modeOut); + final MonitorDevice monOut = new MonitorDeviceImpl(null, -1, sizeMM, viewport, modeOut, supportedModes); + System.err.println("01 out : "+monOut); + cache.monitorDevices.add(monOut); + { + final int[] props = MonitorModeProps.streamOutMonitorDevice(monOut); + final MonitorDevice monIn = MonitorModeProps.streamInMonitorDevice(null, cache, null, props, 0); + System.err.println("01 in : "+monIn); + + Assert.assertEquals(monOut.getCurrentMode(), monOut.getOriginalMode()); + Assert.assertEquals(monOut.getSupportedModes(), monIn.getSupportedModes()); + Assert.assertEquals(monOut.getViewport(), monIn.getViewport()); + Assert.assertEquals(monOut.getOriginalMode(), monIn.getOriginalMode()); + Assert.assertEquals(monOut.getCurrentMode(), monIn.getCurrentMode()); + Assert.assertEquals(monOut.hashCode(), monIn.hashCode()); + Assert.assertEquals(monOut, monIn); + } } @Test @@ -101,21 +122,37 @@ public class TestScreenMode00NEWT extends UITestCase { Assert.assertEquals(true,screen.isNativeValid()); Assert.assertEquals(true,screen.getDisplay().isNativeValid()); System.err.println("Screen: "+screen.toString()); - - List screenModes = screen.getScreenModes(); - Assert.assertTrue(screenModes.size()>0); - int i=0; - for(Iterator iter=screenModes.iterator(); iter.hasNext(); i++) { - System.err.println(i+": "+iter.next()); + List allMonitorModes = screen.getMonitorModes(); + Assert.assertTrue(allMonitorModes.size()>0); + { + int i=0; + for(Iterator iMode=allMonitorModes.iterator(); iMode.hasNext(); i++) { + System.err.println("All["+i+"]: "+iMode.next()); + } + } + + List monitors = screen.getMonitorDevices(); + Assert.assertTrue(monitors.size()>0); + int j=0; + for(Iterator iMonitor=monitors.iterator(); iMonitor.hasNext(); j++) { + MonitorDevice monitor = iMonitor.next(); + System.err.println(j+": "+monitor); + List modes = monitor.getSupportedModes(); + Assert.assertTrue(modes.size()>0); + int i=0; + for(Iterator iMode=modes.iterator(); iMode.hasNext(); i++) { + System.err.println("["+j+"]["+i+"]: "+iMode.next()); + } + Assert.assertTrue(allMonitorModes.containsAll(modes)); + + MonitorMode sm_o = monitor.getOriginalMode(); + Assert.assertNotNull(sm_o); + MonitorMode sm_c = monitor.queryCurrentMode(); + System.err.println("[0] orig : "+sm_o); + System.err.println("[0] current: "+sm_c); + Assert.assertNotNull(sm_c); + Assert.assertEquals(sm_o, sm_c); } - ScreenMode sm_o = screen.getOriginalScreenMode(); - Assert.assertNotNull(sm_o); - ScreenMode sm_c = screen.getCurrentScreenMode(); - Assert.assertNotNull(sm_c); - System.err.println("orig SM: "+sm_o); - System.err.println("curr SM: "+sm_c); - System.err.println("curr sz: "+screen.getWidth()+"x"+screen.getHeight()); - Assert.assertEquals(sm_o, sm_c); screen.removeReference(); diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java index 75a312686..f4eaec5fa 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java @@ -36,9 +36,10 @@ import org.junit.BeforeClass; import org.junit.Test; import com.jogamp.newt.Display; +import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Screen; -import com.jogamp.newt.ScreenMode; +import com.jogamp.newt.MonitorMode; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; import com.jogamp.opengl.test.junit.util.UITestCase; @@ -81,23 +82,24 @@ public class TestScreenMode00bNEWT extends UITestCase { Assert.assertEquals(true,screen.isNativeValid()); Assert.assertEquals(true,display.isNativeValid()); - List screenModes = screen.getScreenModes(); + List screenModes = screen.getMonitorModes(); Assert.assertTrue(screenModes.size()>0); int i=0; - for(Iterator iter=screenModes.iterator(); iter.hasNext(); i++) { + for(Iterator iter=screenModes.iterator(); iter.hasNext(); i++) { System.err.println(i+": "+iter.next()); } - ScreenMode sm_o = screen.getOriginalScreenMode(); + MonitorDevice monitor = window.getMainMonitor(); + MonitorMode mm_o = monitor.getOriginalMode(); - Assert.assertNotNull(sm_o); - ScreenMode sm_c = screen.getCurrentScreenMode(); - Assert.assertNotNull(sm_c); - System.err.println("orig: "+sm_o); - System.err.println("curr: "+sm_c); + Assert.assertNotNull(mm_o); + MonitorMode mm_c = monitor.queryCurrentMode(); + Assert.assertNotNull(mm_c); + System.err.println("orig: "+mm_o); + System.err.println("curr: "+mm_c); for(i=0; i<50; i++) { - sm_c = screen.getCurrentScreenMode(); - Assert.assertNotNull(sm_c); + mm_c = monitor.queryCurrentMode(); + Assert.assertNotNull(mm_c); System.err.print("."+i); } System.err.println("!"); diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java index f253f3b58..78dd9fbc1 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java @@ -40,12 +40,13 @@ import org.junit.BeforeClass; import org.junit.Test; import com.jogamp.newt.Display; +import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Screen; import com.jogamp.newt.Window; -import com.jogamp.newt.ScreenMode; +import com.jogamp.newt.MonitorMode; import com.jogamp.newt.opengl.GLWindow; -import com.jogamp.newt.util.ScreenModeUtil; +import com.jogamp.newt.util.MonitorModeUtil; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; import com.jogamp.opengl.test.junit.util.AWTRobotUtil; import com.jogamp.opengl.test.junit.util.UITestCase; @@ -149,14 +150,16 @@ public class TestScreenMode01NEWT extends UITestCase { Animator animator = new Animator(window); animator.start(); + final MonitorDevice monitor = window.getMainMonitor(); + Assert.assertEquals(false, window.isFullscreen()); Assert.assertEquals(width, window.getWidth()); Assert.assertEquals(height, window.getHeight()); window.setFullscreen(true); - Assert.assertEquals(true, window.isFullscreen()); - Assert.assertEquals(window.getScreen().getWidth(), window.getWidth()); - Assert.assertEquals(window.getScreen().getHeight(), window.getHeight()); + Assert.assertEquals(true, window.isFullscreen()); + Assert.assertEquals(monitor.getViewport().getWidth(), window.getWidth()); + Assert.assertEquals(monitor.getViewport().getHeight(), window.getHeight()); Thread.sleep(waitTimeShort); @@ -192,45 +195,53 @@ public class TestScreenMode01NEWT extends UITestCase { GLWindow window = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); Assert.assertNotNull(window); - List screenModes = screen.getScreenModes(); - if(screenModes.size()==1) { + MonitorDevice monitor = window.getMainMonitor(); + + List monitorModes = monitor.getSupportedModes(); + Assert.assertTrue(monitorModes.size()>0); + if(monitorModes.size()==1) { // no support .. - System.err.println("Your platform has no ScreenMode change support, sorry"); + System.err.println("Your platform has no MonitorMode change support, sorry"); destroyWindow(window); return; } - Assert.assertTrue(screenModes.size()>0); Animator animator = new Animator(window); animator.start(); - ScreenMode smCurrent = screen.getCurrentScreenMode(); - Assert.assertNotNull(smCurrent); - ScreenMode smOrig = screen.getOriginalScreenMode(); - Assert.assertNotNull(smOrig); - Assert.assertEquals(smCurrent, smOrig); - System.err.println("[0] current/orig: "+smCurrent); - - screenModes = ScreenModeUtil.filterByRate(screenModes, smOrig.getMonitorMode().getRefreshRate()); - Assert.assertNotNull(screenModes); - Assert.assertTrue(screenModes.size()>0); - screenModes = ScreenModeUtil.filterByRotation(screenModes, 0); - Assert.assertNotNull(screenModes); - Assert.assertTrue(screenModes.size()>0); - screenModes = ScreenModeUtil.filterByResolution(screenModes, new Dimension(801, 601)); - Assert.assertNotNull(screenModes); - Assert.assertTrue(screenModes.size()>0); + MonitorMode mmCurrent = monitor.queryCurrentMode(); + Assert.assertNotNull(mmCurrent); + MonitorMode mmOrig = monitor.getOriginalMode(); + Assert.assertNotNull(mmOrig); + System.err.println("[0] orig : "+mmOrig); + System.err.println("[0] current: "+mmCurrent); + Assert.assertEquals(mmCurrent, mmOrig); + + monitorModes = MonitorModeUtil.filterByFlags(monitorModes, 0); // no interlace, double-scan etc + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.filterByRotation(monitorModes, 0); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.filterByRate(monitorModes, mmOrig.getRefreshRate()); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.filterByResolution(monitorModes, new Dimension(801, 601)); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); - screenModes = ScreenModeUtil.getHighestAvailableBpp(screenModes); - Assert.assertNotNull(screenModes); - Assert.assertTrue(screenModes.size()>0); + monitorModes = MonitorModeUtil.getHighestAvailableBpp(monitorModes); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); - ScreenMode sm = (ScreenMode) screenModes.get(0); + MonitorMode sm = (MonitorMode) monitorModes.get(0); System.err.println("[0] set current: "+sm); - screen.setCurrentScreenMode(sm); - Assert.assertEquals(sm, screen.getCurrentScreenMode()); - Assert.assertNotSame(smOrig, screen.getCurrentScreenMode()); - + monitor.setCurrentMode(sm); + Assert.assertTrue(monitor.isModeChangedByUs()); + Assert.assertEquals(sm, monitor.getCurrentMode()); + Assert.assertNotSame(mmOrig, monitor.getCurrentMode()); + Assert.assertEquals(sm, monitor.queryCurrentMode()); + Thread.sleep(waitTimeLong); // check reset .. @@ -258,15 +269,14 @@ public class TestScreenMode01NEWT extends UITestCase { Assert.assertEquals(true,display.isNativeValid()); Assert.assertEquals(true,screen.isNativeValid()); - smCurrent = screen.getCurrentScreenMode(); - System.err.println("[1] current/orig: "+smCurrent); + mmCurrent = monitor.getCurrentMode(); + System.err.println("[1] current/orig: "+mmCurrent); screen.destroy(); Assert.assertEquals(false,screen.isNativeValid()); Assert.assertEquals(false,display.isNativeValid()); - Assert.assertNotNull(smCurrent); - Assert.assertEquals(smCurrent, smOrig); - + Assert.assertNotNull(mmCurrent); + Assert.assertEquals(mmCurrent, mmOrig); cleanupGL(); } @@ -291,27 +301,30 @@ public class TestScreenMode01NEWT extends UITestCase { Animator animator = new Animator(window); animator.start(); - ScreenMode smCurrent = screen.getCurrentScreenMode(); - Assert.assertNotNull(smCurrent); - ScreenMode smOrig = screen.getOriginalScreenMode(); - Assert.assertNotNull(smOrig); - Assert.assertEquals(smCurrent, smOrig); - System.err.println("[0] current/orig: "+smCurrent); + MonitorDevice monitor = window.getMainMonitor(); + MonitorMode mmCurrent = monitor.queryCurrentMode(); + Assert.assertNotNull(mmCurrent); + MonitorMode mmOrig = monitor.getOriginalMode(); + Assert.assertNotNull(mmOrig); + System.err.println("[0] orig : "+mmOrig); + System.err.println("[0] current: "+mmCurrent); + Assert.assertEquals(mmCurrent, mmOrig); - List screenModes = screen.getScreenModes(); - if(screenModes.size()==1) { + List monitorModes = monitor.getSupportedModes(); + if(monitorModes.size()==1) { // no support .. destroyWindow(window); return; } - Assert.assertTrue(screenModes.size()>0); - screenModes = ScreenModeUtil.filterByRate(screenModes, smOrig.getMonitorMode().getRefreshRate()); - screenModes = ScreenModeUtil.filterByRotation(screenModes, 0); - screenModes = ScreenModeUtil.filterByResolution(screenModes, new Dimension(801, 601)); - screenModes = ScreenModeUtil.getHighestAvailableBpp(screenModes); - - ScreenMode screenMode = (ScreenMode) screenModes.get(0); - Assert.assertNotNull(screenMode); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.filterByFlags(monitorModes, 0); // no interlace, double-scan etc + monitorModes = MonitorModeUtil.filterByRotation(monitorModes, 0); + monitorModes = MonitorModeUtil.filterByRate(monitorModes, mmOrig.getRefreshRate()); + monitorModes = MonitorModeUtil.filterByResolution(monitorModes, new Dimension(801, 601)); + monitorModes = MonitorModeUtil.getHighestAvailableBpp(monitorModes); + + MonitorMode monitorMode = (MonitorMode) monitorModes.get(0); + Assert.assertNotNull(monitorMode); if(preFS) { System.err.println("[0] set FS pre 0: "+window.isFullscreen()); @@ -321,8 +334,8 @@ public class TestScreenMode01NEWT extends UITestCase { System.err.println("[0] set FS pre X: "+window.isFullscreen()); } - System.err.println("[0] set current: "+screenMode); - screen.setCurrentScreenMode(screenMode); + System.err.println("[0] set current: "+monitorMode); + monitor.setCurrentMode(monitorMode); if(!preFS) { System.err.println("[0] set FS post 0: "+window.isFullscreen()); @@ -358,14 +371,14 @@ public class TestScreenMode01NEWT extends UITestCase { Assert.assertEquals(true,display.isNativeValid()); Assert.assertEquals(true,screen.isNativeValid()); - smCurrent = screen.getCurrentScreenMode(); - System.err.println("[1] current/orig: "+smCurrent); + mmCurrent = monitor.getCurrentMode(); + System.err.println("[1] current/orig: "+mmCurrent); screen.destroy(); Assert.assertEquals(false,screen.isNativeValid()); Assert.assertEquals(false,display.isNativeValid()); - Assert.assertNotNull(smCurrent); - Assert.assertEquals(smCurrent, smOrig); + Assert.assertNotNull(mmCurrent); + Assert.assertEquals(mmCurrent, mmOrig); cleanupGL(); } diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01aNEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01aNEWT.java new file mode 100644 index 000000000..35390636f --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01aNEWT.java @@ -0,0 +1,212 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.newt; + +import java.io.IOException; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLProfile; + +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.jogamp.newt.Display; +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.Screen; +import com.jogamp.newt.Window; +import com.jogamp.newt.MonitorMode; +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.newt.util.MonitorModeUtil; +import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; +import com.jogamp.opengl.test.junit.util.UITestCase; + +import java.util.List; +import javax.media.nativewindow.util.Dimension; + +/** + * Documents remedy B) for NV RANDR/GL bug + * + * @see TestScreenMode01NEWT#cleanupGL() + */ +public class TestScreenMode01aNEWT extends UITestCase { + static GLProfile glp; + static int width, height; + + static int waitTimeShort = 2000; + static int waitTimeLong = 2000; + + @BeforeClass + public static void initClass() { + width = 100; + height = 100; + glp = GLProfile.getDefault(); + } + + @AfterClass + public static void releaseClass() throws InterruptedException { + Thread.sleep(waitTimeShort); + } + + static Window createWindow(Screen screen, GLCapabilities caps, String name, int x, int y, int width, int height) { + Assert.assertNotNull(caps); + + GLWindow window = GLWindow.create(screen, caps); + // Window window = NewtFactory.createWindow(screen, caps); + window.setTitle(name); + window.setPosition(x, y); + window.setSize(width, height); + window.addGLEventListener(new GearsES2()); + Assert.assertNotNull(window); + window.setVisible(true); + return window; + } + + static void destroyWindow(Window window) { + if(null!=window) { + window.destroy(); + } + } + + @Test + public void testScreenModeChange01() throws InterruptedException { + Thread.sleep(waitTimeShort); + + GLCapabilities caps = new GLCapabilities(glp); + Assert.assertNotNull(caps); + Display display = NewtFactory.createDisplay(null); // local display + Assert.assertNotNull(display); + Screen screen = NewtFactory.createScreen(display, 0); // screen 0 + Assert.assertNotNull(screen); + Window window0 = createWindow(screen, caps, "win0", 0, 0, width, height); + Assert.assertNotNull(window0); + + List allMonitorModes = screen.getMonitorModes(); + Assert.assertTrue(allMonitorModes.size()>0); + if(allMonitorModes.size()==1) { + // no support .. + System.err.println("Your platform has no MonitorMode change support (all), sorry"); + destroyWindow(window0); + return; + } + + MonitorDevice monitor = window0.getMainMonitor(); + + List monitorModes = monitor.getSupportedModes(); + Assert.assertTrue(monitorModes.size()>0); + if(monitorModes.size()==1) { + // no support .. + System.err.println("Your platform has no MonitorMode change support (monitor), sorry"); + destroyWindow(window0); + return; + } + Assert.assertTrue(allMonitorModes.containsAll(monitorModes)); + + MonitorMode mmCurrent = monitor.queryCurrentMode(); + Assert.assertNotNull(mmCurrent); + MonitorMode mmOrig = monitor.getOriginalMode(); + Assert.assertNotNull(mmOrig); + System.err.println("[0] orig : "+mmOrig); + System.err.println("[0] current: "+mmCurrent); + Assert.assertEquals(mmCurrent, mmOrig); + + + monitorModes = MonitorModeUtil.filterByFlags(monitorModes, 0); // no interlace, double-scan etc + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.filterByRotation(monitorModes, 0); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.filterByRate(monitorModes, mmOrig.getRefreshRate()); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.filterByResolution(monitorModes, new Dimension(801, 601)); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + + monitorModes = MonitorModeUtil.getHighestAvailableBpp(monitorModes); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + + MonitorMode sm = (MonitorMode) monitorModes.get(0); + System.err.println("[0] set current: "+sm); + Assert.assertTrue(monitor.setCurrentMode(sm)); + Assert.assertTrue(monitor.isModeChangedByUs()); + Assert.assertEquals(sm, monitor.getCurrentMode()); + Assert.assertNotSame(mmOrig, monitor.getCurrentMode()); + Assert.assertEquals(sm, monitor.queryCurrentMode()); + + Thread.sleep(waitTimeShort); + + // check manual reset .. + + Assert.assertEquals(true,display.isNativeValid()); + Assert.assertEquals(true,screen.isNativeValid()); + Assert.assertEquals(true,window0.isNativeValid()); + Assert.assertEquals(true,window0.isVisible()); + + screen.addReference(); // keep it alive ! + Assert.assertTrue(monitor.setCurrentMode(mmOrig)); + Assert.assertFalse(monitor.isModeChangedByUs()); + Assert.assertEquals(mmOrig, monitor.getCurrentMode()); + Assert.assertNotSame(sm, monitor.getCurrentMode()); + Assert.assertEquals(mmOrig, monitor.queryCurrentMode()); + + destroyWindow(window0); + Assert.assertEquals(false,window0.isVisible()); + Assert.assertEquals(false,window0.isNativeValid()); + Assert.assertEquals(true,screen.isNativeValid()); // alive ! + Assert.assertEquals(true,display.isNativeValid()); + + Thread.sleep(waitTimeShort); + + Window window1 = createWindow(screen, caps, "win1", + width+window0.getInsets().getTotalWidth(), 0, + width, height); + Assert.assertNotNull(window1); + Assert.assertEquals(true,window1.isNativeValid()); + Assert.assertEquals(true,window1.isVisible()); + + Thread.sleep(waitTimeShort); + + destroyWindow(window1); + Assert.assertEquals(false,window1.isNativeValid()); + Assert.assertEquals(false,window1.isVisible()); + + screen.removeReference(); + Assert.assertEquals(false,screen.isNativeValid()); + Assert.assertEquals(false,display.isNativeValid()); + } + + public static void main(String args[]) throws IOException { + String tstname = TestScreenMode01aNEWT.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01bNEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01bNEWT.java index 38612faa8..7e18f396a 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01bNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01bNEWT.java @@ -1,5 +1,5 @@ /** - * Copyright 2010 JogAmp Community. All rights reserved. + * Copyright 2013 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -29,7 +29,6 @@ package com.jogamp.opengl.test.junit.newt; import java.io.IOException; -import javax.media.nativewindow.NativeWindowFactory; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLProfile; @@ -39,34 +38,36 @@ import org.junit.BeforeClass; import org.junit.Test; import com.jogamp.newt.Display; +import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Screen; import com.jogamp.newt.Window; -import com.jogamp.newt.ScreenMode; +import com.jogamp.newt.MonitorMode; import com.jogamp.newt.opengl.GLWindow; -import com.jogamp.newt.util.ScreenModeUtil; +import com.jogamp.newt.util.MonitorModeUtil; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; +import com.jogamp.opengl.test.junit.util.MiscUtils; import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.util.Animator; import java.util.List; import javax.media.nativewindow.util.Dimension; +import javax.media.nativewindow.util.RectangleImmutable; /** - * Documents remedy B) for NV RANDR/GL bug - * - * @see TestScreenMode01NEWT#cleanupGL() + * Mode change on separate monitors .. */ public class TestScreenMode01bNEWT extends UITestCase { static GLProfile glp; static int width, height; - static int waitTimeShort = 2000; - static int waitTimeLong = 2000; + static long waitTimeShort = 2000; + static long duration = 6000; @BeforeClass public static void initClass() { - width = 100; - height = 100; + width = 200; + height = 200; glp = GLProfile.getDefault(); } @@ -75,7 +76,7 @@ public class TestScreenMode01bNEWT extends UITestCase { Thread.sleep(waitTimeShort); } - static Window createWindow(Screen screen, GLCapabilities caps, String name, int x, int y, int width, int height) { + static GLWindow createWindow(Screen screen, GLCapabilities caps, String name, int x, int y, int width, int height) throws InterruptedException { Assert.assertNotNull(caps); GLWindow window = GLWindow.create(screen, caps); @@ -85,7 +86,9 @@ public class TestScreenMode01bNEWT extends UITestCase { window.setSize(width, height); window.addGLEventListener(new GearsES2()); Assert.assertNotNull(window); + final long t0 = System.currentTimeMillis(); window.setVisible(true); + System.err.println("Time for visible/pos: "+(System.currentTimeMillis()-t0)+" ms"); return window; } @@ -96,93 +99,150 @@ public class TestScreenMode01bNEWT extends UITestCase { } @Test - public void testScreenModeChange01() throws InterruptedException { + public void testScreenModeChangeSingleQ1() throws InterruptedException { + final Display display = NewtFactory.createDisplay(null); // local display + Assert.assertNotNull(display); + final Screen screen = NewtFactory.createScreen(display, 0); // screen 0 + Assert.assertNotNull(screen); + screen.addReference(); // trigger creation + try { + RectangleImmutable monitorVp = screen.getMonitorDevices().get(0).getViewport(); + testScreenModeChangeImpl(screen, monitorVp.getX(), monitorVp.getY()); + } finally { + screen.removeReference(); + } + } + + @Test + public void testScreenModeChangeSingleQ2() throws InterruptedException { + final Display display = NewtFactory.createDisplay(null); // local display + Assert.assertNotNull(display); + final Screen screen = NewtFactory.createScreen(display, 0); // screen 0 + Assert.assertNotNull(screen); + screen.addReference(); // trigger creation + try { + if( 2 > screen.getMonitorDevices().size() ) { + System.err.println("Test Disabled (1): Monitor count < 2: "+screen); + return; + } + RectangleImmutable monitorVp = screen.getMonitorDevices().get(1).getViewport(); + testScreenModeChangeImpl(screen, monitorVp.getX(), monitorVp.getY()); + } finally { + screen.removeReference(); + } + } + + void testScreenModeChangeImpl(final Screen screen, int xpos, int ypos) throws InterruptedException { Thread.sleep(waitTimeShort); - GLCapabilities caps = new GLCapabilities(glp); + final GLCapabilities caps = new GLCapabilities(glp); Assert.assertNotNull(caps); - Display display = NewtFactory.createDisplay(null); // local display - Assert.assertNotNull(display); - Screen screen = NewtFactory.createScreen(display, 0); // screen 0 - Assert.assertNotNull(screen); - Window window0 = createWindow(screen, caps, "win0", 0, 0, width, height); + final Display display = screen.getDisplay(); + System.err.println("Test.0: Window screen: "+screen); + + System.err.println("Test.0: Window bounds (pre): "+xpos+"/"+ypos+" "+width+"x"+height+" within "+screen.getViewport()); + + GLWindow window0 = createWindow(screen, caps, "win0", xpos, ypos, width, height); Assert.assertNotNull(window0); + System.err.println("Test.0: Window bounds: "+window0.getX()+"/"+window0.getY()+" "+window0.getWidth()+"x"+window0.getHeight()+" within "+screen.getViewport()); - List screenModes = screen.getScreenModes(); - if(screenModes.size()==1) { + final Animator anim = new Animator(window0); + anim.start(); + + List allMonitorModes = screen.getMonitorModes(); + Assert.assertTrue(allMonitorModes.size()>0); + if(allMonitorModes.size()==1) { // no support .. - System.err.println("Your platform has no ScreenMode change support, sorry"); + System.err.println("Your platform has no MonitorMode change support (all), sorry"); destroyWindow(window0); return; } - Assert.assertTrue(screenModes.size()>0); - - ScreenMode smCurrent = screen.getCurrentScreenMode(); - Assert.assertNotNull(smCurrent); - ScreenMode smOrig = screen.getOriginalScreenMode(); - Assert.assertNotNull(smOrig); - Assert.assertEquals(smCurrent, smOrig); - System.err.println("[0] current/orig: "+smCurrent); - - screenModes = ScreenModeUtil.filterByRate(screenModes, smOrig.getMonitorMode().getRefreshRate()); - Assert.assertNotNull(screenModes); - Assert.assertTrue(screenModes.size()>0); - screenModes = ScreenModeUtil.filterByRotation(screenModes, 0); - Assert.assertNotNull(screenModes); - Assert.assertTrue(screenModes.size()>0); - screenModes = ScreenModeUtil.filterByResolution(screenModes, new Dimension(801, 601)); - Assert.assertNotNull(screenModes); - Assert.assertTrue(screenModes.size()>0); - - screenModes = ScreenModeUtil.getHighestAvailableBpp(screenModes); - Assert.assertNotNull(screenModes); - Assert.assertTrue(screenModes.size()>0); - ScreenMode sm = (ScreenMode) screenModes.get(0); - System.err.println("[0] set current: "+sm); - screen.setCurrentScreenMode(sm); - Assert.assertEquals(sm, screen.getCurrentScreenMode()); - Assert.assertNotSame(smOrig, screen.getCurrentScreenMode()); - - Thread.sleep(waitTimeShort); - - // check reset .. + MonitorDevice monitor = window0.getMainMonitor(); + System.err.println("Test.0: Window monitor: "+monitor); + + List monitorModes = monitor.getSupportedModes(); + Assert.assertTrue(monitorModes.size()>0); + if(monitorModes.size()==1) { + // no support .. + System.err.println("Your platform has no MonitorMode change support (monitor), sorry"); + destroyWindow(window0); + return; + } + Assert.assertTrue(allMonitorModes.containsAll(monitorModes)); + + MonitorMode mmCurrent = monitor.getCurrentMode(); + Assert.assertNotNull(mmCurrent); + MonitorMode mmOrig = monitor.getOriginalMode(); + Assert.assertNotNull(mmOrig); + System.err.println("[0] orig : "+mmOrig); + System.err.println("[0] current: "+mmCurrent); + Assert.assertEquals(mmCurrent, mmOrig); + + monitorModes = MonitorModeUtil.filterByFlags(monitorModes, 0); // no interlace, double-scan etc + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.filterByRotation(monitorModes, 0); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.filterByRate(monitorModes, mmOrig.getRefreshRate()); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.filterByResolution(monitorModes, new Dimension(801, 601)); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + + monitorModes = MonitorModeUtil.getHighestAvailableBpp(monitorModes); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + + MonitorMode sm = (MonitorMode) monitorModes.get(0); + System.err.println("[1] set current: "+sm); + Assert.assertTrue(monitor.setCurrentMode(sm)); + mmCurrent = monitor.getCurrentMode(); + System.err.println("[1] current: "+mmCurrent); + Assert.assertTrue(monitor.isModeChangedByUs()); + Assert.assertEquals(sm, monitor.getCurrentMode()); + Assert.assertNotSame(mmOrig, monitor.getCurrentMode()); + Assert.assertEquals(sm, monitor.queryCurrentMode()); + + System.err.println("Test.1: Window screen: "+screen); + System.err.println("Test.1: Window bounds: "+window0.getX()+"/"+window0.getY()+" "+window0.getWidth()+"x"+window0.getHeight()+" within "+screen.getViewport()); + System.err.println("Test.1: Window monitor: "+window0.getMainMonitor()); + + Thread.sleep(duration); Assert.assertEquals(true,display.isNativeValid()); Assert.assertEquals(true,screen.isNativeValid()); Assert.assertEquals(true,window0.isNativeValid()); Assert.assertEquals(true,window0.isVisible()); - screen.addReference(); // keep it alive ! - screen.setCurrentScreenMode(smOrig); + Assert.assertTrue(monitor.setCurrentMode(mmOrig)); + Assert.assertFalse(monitor.isModeChangedByUs()); + Assert.assertEquals(mmOrig, monitor.getCurrentMode()); + Assert.assertNotSame(sm, monitor.getCurrentMode()); + Assert.assertEquals(mmOrig, monitor.queryCurrentMode()); + + System.err.println("Test.2: Window screen: "+screen); + System.err.println("Test.2: Window bounds: "+window0.getX()+"/"+window0.getY()+" "+window0.getWidth()+"x"+window0.getHeight()+" within "+screen.getViewport()); + System.err.println("Test.2: Window monitor: "+window0.getMainMonitor()); + Thread.sleep(duration); + anim.stop(); destroyWindow(window0); Assert.assertEquals(false,window0.isVisible()); Assert.assertEquals(false,window0.isNativeValid()); - Assert.assertEquals(true,screen.isNativeValid()); // alive ! Assert.assertEquals(true,display.isNativeValid()); - - Thread.sleep(waitTimeShort); - - Window window1 = createWindow(screen, caps, "win1", - width+window0.getInsets().getTotalWidth(), 0, - width, height); - Assert.assertNotNull(window1); - Assert.assertEquals(true,window1.isNativeValid()); - Assert.assertEquals(true,window1.isVisible()); - - Thread.sleep(waitTimeShort); - - destroyWindow(window1); - Assert.assertEquals(false,window1.isNativeValid()); - Assert.assertEquals(false,window1.isVisible()); - - screen.removeReference(); - Assert.assertEquals(false,screen.isNativeValid()); - Assert.assertEquals(false,display.isNativeValid()); + Assert.assertEquals(true,screen.isNativeValid()); } public static void main(String args[]) throws IOException { + for(int i=0; i screen.getMonitorDevices().size() ) { + System.err.println("Test Disabled (1): Monitor count < 2: "+screen); + return; + } + RectangleImmutable monitorVp = screen.getMonitorDevices().get(1).getViewport(); + testScreenFullscreenImpl(screen, monitorVp.getX(), monitorVp.getY(), false, null); + } finally { + screen.removeReference(); + } + } + + @Test + public void testScreenFullscreenSpanQ1Q2() throws InterruptedException { + final Display display = NewtFactory.createDisplay(null); // local display + Assert.assertNotNull(display); + final Screen screen = NewtFactory.createScreen(display, 0); // screen 0 + Assert.assertNotNull(screen); + screen.addReference(); // trigger creation + try { + final int crtCount = screen.getMonitorDevices().size(); + if( 2 >= crtCount ) { + System.err.println("Test Disabled (2): Spanning monitor count "+2+" >= screen monitor count: "+screen); + return; + } + final ArrayList monitors = new ArrayList(); + monitors.add(screen.getMonitorDevices().get(0)); // Q1 + monitors.add(screen.getMonitorDevices().get(1)); // Q2 + RectangleImmutable monitorVp = screen.getMonitorDevices().get(0).getViewport(); + testScreenFullscreenImpl(screen, monitorVp.getX()+50, monitorVp.getY()+50, true, monitors); + } finally { + screen.removeReference(); + } + } + + @Test + public void testScreenFullscreenSpanALL() throws InterruptedException { + final Display display = NewtFactory.createDisplay(null); // local display + Assert.assertNotNull(display); + final Screen screen = NewtFactory.createScreen(display, 0); // screen 0 + Assert.assertNotNull(screen); + screen.addReference(); // trigger creation + try { + if( 2 > screen.getMonitorDevices().size() ) { + System.err.println("Test Disabled (3): Monitor count < 2: "+screen); + return; + } + RectangleImmutable monitorVp = screen.getMonitorDevices().get(1).getViewport(); + testScreenFullscreenImpl(screen, monitorVp.getX()-50, monitorVp.getY()+50, true, null); + } finally { + screen.removeReference(); + } + } + + void testScreenFullscreenImpl(final Screen screen, int xpos, int ypos, boolean spanAcrossMonitors, List monitors) throws InterruptedException { + Thread.sleep(waitTimeShort); + + final GLCapabilities caps = new GLCapabilities(glp); + Assert.assertNotNull(caps); + final Display display = screen.getDisplay(); + + System.err.println("Test.0: Window screen: "+screen); + + System.err.println("Test.0: Window bounds (pre): "+xpos+"/"+ypos+" "+width+"x"+height+" within "+screen.getViewport()); + + GLWindow window0 = createWindow(screen, caps, "win0", xpos, ypos, width, height); + Assert.assertNotNull(window0); + System.err.println("Test.0: Window bounds: "+window0.getX()+"/"+window0.getY()+" "+window0.getWidth()+"x"+window0.getHeight()+" within "+screen.getViewport()); + + final Animator anim = new Animator(window0); + anim.start(); + + List allMonitorModes = screen.getMonitorModes(); + Assert.assertTrue(allMonitorModes.size()>0); + + MonitorDevice monitor = window0.getMainMonitor(); + System.err.println("Test.0: Window monitor: "+monitor); + if( !spanAcrossMonitors ) { + window0.setFullscreen(true); + } else { + window0.setFullscreen(monitors); + } + + monitor = window0.getMainMonitor(); + System.err.println("Test.1: Window bounds: "+window0.getX()+"/"+window0.getY()+" "+window0.getWidth()+"x"+window0.getHeight()+" within "+screen.getViewport()); + System.err.println("Test.1: Window monitor: "+monitor.getViewport()); + Rectangle window0Rect = new Rectangle(window0.getX(), window0.getY(), window0.getWidth(), window0.getHeight()); + if( !spanAcrossMonitors ) { + Assert.assertEquals(monitor.getViewport(), window0Rect); + } else { + List monitorsUsed = monitors; + if( null == monitorsUsed ) { + monitorsUsed = window0.getScreen().getMonitorDevices(); + } + Rectangle monitorsUsedViewport = MonitorDevice.unionOfViewports(new Rectangle(), monitorsUsed); + Assert.assertEquals(monitorsUsedViewport, window0Rect); + } + + Thread.sleep(duration); + + window0.setFullscreen(false); + + window0Rect = new Rectangle(window0.getX(), window0.getY(), window0.getWidth(), window0.getHeight()); + monitor = window0.getMainMonitor(); + System.err.println("Test.2: Window bounds: "+window0.getX()+"/"+window0.getY()+" "+window0.getWidth()+"x"+window0.getHeight()+" within "+screen.getViewport()); + System.err.println("Test.2: Window monitor: "+monitor.getViewport()); + + Thread.sleep(duration); + anim.stop(); + destroyWindow(window0); + Assert.assertEquals(false,window0.isVisible()); + Assert.assertEquals(false,window0.isNativeValid()); + Assert.assertEquals(true,display.isNativeValid()); + Assert.assertEquals(true,screen.isNativeValid()); + } + + public static void main(String args[]) throws IOException { + for(int i=0; i screenModes = screen.getScreenModes(); - if(screenModes.size()==1) { + MonitorDevice monitor = window.getMainMonitor(); + List monitorModes = monitor.getSupportedModes(); + if(monitorModes.size()==1) { // no support .. System.err.println("Your platform has no ScreenMode change support, sorry"); destroyWindow(window); return; } - Assert.assertTrue(screenModes.size()>0); + Assert.assertTrue(monitorModes.size()>0); Animator animator = new Animator(window); animator.start(); - ScreenMode smCurrent = screen.getCurrentScreenMode(); - Assert.assertNotNull(smCurrent); - ScreenMode smOrig = screen.getOriginalScreenMode(); - Assert.assertNotNull(smOrig); - Assert.assertEquals(smCurrent, smOrig); - System.err.println("[0] current/orig: "+smCurrent); - - screenModes = ScreenModeUtil.filterByRate(screenModes, smOrig.getMonitorMode().getRefreshRate()); - Assert.assertNotNull(screenModes); - Assert.assertTrue(screenModes.size()>0); - screenModes = ScreenModeUtil.filterByRotation(screenModes, 90); - if(null==screenModes) { + MonitorMode mmCurrent = monitor.getCurrentMode(); + Assert.assertNotNull(mmCurrent); + MonitorMode mmOrig = monitor.getOriginalMode(); + Assert.assertNotNull(mmOrig); + System.err.println("[0] orig : "+mmOrig); + System.err.println("[0] current: "+mmCurrent); + Assert.assertEquals(mmCurrent, mmOrig); + + monitorModes = MonitorModeUtil.filterByFlags(monitorModes, 0); // no interlace, double-scan etc + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.filterByRotation(monitorModes, 90); + if(null==monitorModes || Platform.getOSType() == Platform.OSType.MACOS ) { // no rotation support .. System.err.println("Your platform has no rotation support, sorry"); destroyWindow(window); return; } - Assert.assertTrue(screenModes.size()>0); - screenModes = ScreenModeUtil.filterByResolution(screenModes, new Dimension(801, 601)); - Assert.assertNotNull(screenModes); - Assert.assertTrue(screenModes.size()>0); - screenModes = ScreenModeUtil.getHighestAvailableBpp(screenModes); - Assert.assertNotNull(screenModes); - Assert.assertTrue(screenModes.size()>0); - - ScreenMode sm = (ScreenMode) screenModes.get(0); + monitorModes = MonitorModeUtil.filterByRate(monitorModes, mmOrig.getRefreshRate()); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.filterByResolution(monitorModes, new Dimension(801, 601)); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.getHighestAvailableBpp(monitorModes); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + + MonitorMode sm = (MonitorMode) monitorModes.get(0); System.err.println("[0] set current: "+sm); - screen.setCurrentScreenMode(sm); - Assert.assertEquals(sm, screen.getCurrentScreenMode()); - Assert.assertNotSame(smOrig, screen.getCurrentScreenMode()); + monitor.setCurrentMode(sm); + Assert.assertTrue(monitor.isModeChangedByUs()); + Assert.assertEquals(sm, monitor.getCurrentMode()); + Assert.assertNotSame(mmOrig, monitor.getCurrentMode()); + Assert.assertEquals(sm, monitor.queryCurrentMode()); Thread.sleep(waitTimeLong); @@ -167,11 +176,11 @@ public class TestScreenMode02NEWT extends UITestCase { Assert.assertEquals(true,display.isNativeValid()); Assert.assertEquals(true,screen.isNativeValid()); - smCurrent = screen.getCurrentScreenMode(); - System.err.println("[1] current/orig: "+smCurrent); + mmCurrent = monitor.getCurrentMode(); + System.err.println("[1] current/orig: "+mmCurrent); - Assert.assertNotNull(smCurrent); - Assert.assertEquals(smCurrent, smOrig); + Assert.assertNotNull(mmCurrent); + Assert.assertEquals(mmCurrent, mmOrig); screen.destroy(); -- cgit v1.2.3 From aed9662552503b0a2fa67bcddbb7063b16d003d5 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 12 Jun 2013 11:58:55 +0200 Subject: Fix Bug 750: Leaked X11 ColorMap for each created X11 Window in NativeWindow (dummy) and NEWT Free the colormap at WindowDestroy, which we have created at WindowCreate w/ AllocNone. Due to the fact we used 'AllocNone' the leak is minimal though .. --- src/nativewindow/native/x11/Xmisc.c | 7 +++++++ src/newt/native/X11Window.c | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'src/newt/native/X11Window.c') diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c index 69f0c0746..31620d752 100644 --- a/src/nativewindow/native/x11/Xmisc.c +++ b/src/nativewindow/native/x11/Xmisc.c @@ -624,6 +624,7 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyWindow { Display * dpy = (Display *)(intptr_t)display; Window w = (Window) window; + XWindowAttributes xwa; if(NULL==dpy) { NativewindowCommon_throwNewRuntimeException(env, "invalid display connection.."); @@ -631,10 +632,16 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyWindow } NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 1, errorHandlerQuiet, 0); + XSync(dpy, False); + memset(&xwa, 0, sizeof(XWindowAttributes)); + XGetWindowAttributes(dpy, w, &xwa); // prefetch colormap to be destroyed after window destruction XSelectInput(dpy, w, 0); XUnmapWindow(dpy, w); XSync(dpy, False); XDestroyWindow(dpy, w); + if( None != xwa.colormap ) { + XFreeColormap(dpy, xwa.colormap); + } // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, errorHandlerQuiet, 1); } diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 6c5a127b6..e567781cf 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -676,6 +676,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0 Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; jobject jwindow; + XWindowAttributes xwa; if(dpy==NULL) { NewtCommon_FatalError(env, "invalid display connection.."); @@ -694,13 +695,19 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0 } XSync(dpy, False); + memset(&xwa, 0, sizeof(XWindowAttributes)); + XGetWindowAttributes(dpy, w, &xwa); // prefetch colormap to be destroyed after window destruction XSelectInput(dpy, w, 0); XUnmapWindow(dpy, w); + XSync(dpy, False); // Drain all events related to this window .. Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom /*, kbdHandle */); // XKB disabled for now XDestroyWindow(dpy, w); + if( None != xwa.colormap ) { + XFreeColormap(dpy, xwa.colormap); + } XSync(dpy, True); // discard all events now, no more handler (*env)->DeleteGlobalRef(env, jwindow); -- cgit v1.2.3 From 8b33170ec6fd3f215976875cb66d746fa1b48f61 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Mon, 17 Jun 2013 09:01:23 +0200 Subject: Fix Bug 688: Removal of NEWT KeyEvent.EVENT_KEY_TYPED and KeyListener.keyTyped(KeyEvent) --- make/scripts/tests.sh | 13 ++----- .../classes/com/jogamp/newt/awt/NewtCanvasAWT.java | 11 ++---- .../jogamp/newt/awt/applet/JOGLNewtAppletBase.java | 7 ++-- .../classes/com/jogamp/newt/event/KeyAdapter.java | 2 -- .../classes/com/jogamp/newt/event/KeyEvent.java | 6 ---- .../classes/com/jogamp/newt/event/KeyListener.java | 18 ++++++---- .../com/jogamp/newt/event/TraceKeyAdapter.java | 4 --- src/newt/classes/jogamp/newt/WindowImpl.java | 34 +----------------- src/newt/native/KeyEvent.h | 1 - src/newt/native/X11Event.c | 6 ---- src/newt/native/X11Window.c | 1 - src/newt/native/XCBEvent.c | 6 ---- .../graph/demos/GPURendererListenerBase01.java | 1 - .../graph/demos/GPUTextRendererListenerBase01.java | 10 +++--- .../junit/graph/demos/ui/UIListenerBase01.java | 1 - .../junit/jogl/acore/TestFBOMix2DemosES2NEWT.java | 5 ++- .../test/junit/jogl/caps/TestTranslucencyNEWT.java | 5 ++- .../jogl/demos/es1/newt/TestGearsES1NEWT.java | 5 ++- .../jogl/demos/es1/newt/TestRedSquareES1NEWT.java | 5 ++- .../test/junit/jogl/demos/es2/av/MovieCube.java | 5 ++- .../es2/newt/TestElektronenMultipliziererNEWT.java | 5 ++- .../demos/es2/newt/TestGearsES2NewtCanvasAWT.java | 5 ++- .../demos/es2/newt/TestGearsES2NewtCanvasSWT.java | 5 ++- .../jogl/demos/es2/newt/TestLandscapeES2NEWT.java | 5 ++- .../es2/newt/TestLandscapeES2NewtCanvasAWT.java | 5 ++- .../jogl/demos/es2/newt/TestRedSquareES2NEWT.java | 5 ++- .../junit/jogl/demos/gl2/newt/TestGearsNEWT.java | 5 ++- .../TestNewtCanvasSWTBug628ResizeDeadlockAWT.java | 5 ++- .../newt/event/TestNewtKeyCodeModifiersAWT.java | 32 ++++++----------- .../test/junit/newt/event/TestNewtKeyCodesAWT.java | 3 -- .../newt/event/TestNewtKeyEventAutoRepeatAWT.java | 21 ++++++------ .../junit/newt/event/TestNewtKeyEventOrderAWT.java | 4 +-- .../TestNewtKeyPressReleaseUnmaskRepeatAWT.java | 5 --- .../test/junit/newt/parenting/KeyAction.java | 5 ++- .../parenting/NewtAWTReparentingKeyAdapter.java | 5 ++- .../TestParentingFocusTraversal01AWT.java | 5 ++- .../opengl/test/junit/util/AWTKeyAdapter.java | 19 ++-------- .../test/junit/util/KeyEventCountAdapter.java | 4 +-- .../opengl/test/junit/util/NEWTKeyAdapter.java | 26 +++----------- .../jogamp/opengl/test/junit/util/NEWTKeyUtil.java | 40 ++++++---------------- .../jogamp/opengl/test/junit/util/QuitAdapter.java | 6 ++-- 41 files changed, 136 insertions(+), 225 deletions(-) (limited to 'src/newt/native/X11Window.c') diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 5fd5d621d..bf8615d6e 100644 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -284,7 +284,9 @@ function testawtswt() { #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelAWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelsAWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT $* +#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NewtCanvasAWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NEWT $* #testawtswt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasSWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple $* @@ -438,15 +440,6 @@ function testawtswt() { #testawt com.jogamp.opengl.test.junit.jogl.awt.TestGLCanvasAWTActionDeadlock01AWT $* #testawt com.jogamp.opengl.test.junit.jogl.awt.TestGLCanvasAWTActionDeadlock02AWT $* -#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NEWT $* -#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NewtCanvasAWT $* -#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT $* -testawt com.jogamp.opengl.test.bugs.Bug735Inv0AppletAWT $* -#testawt com.jogamp.opengl.test.bugs.Bug735Inv1AppletAWT $* -#testawt com.jogamp.opengl.test.bugs.Bug735Inv2AppletAWT $* -#testawt com.jogamp.opengl.test.bugs.Bug735Inv3AppletAWT $* -#testawt com.jogamp.opengl.test.bugs.Bug735Inv4AWT $* - # # swt (testswt) # @@ -478,7 +471,7 @@ testawt com.jogamp.opengl.test.bugs.Bug735Inv0AppletAWT $* #testawt com.jogamp.opengl.test.junit.newt.event.TestNewtKeyPressReleaseUnmaskRepeatAWT $* #testawt com.jogamp.opengl.test.junit.newt.event.TestNewtKeyCodesAWT $* #testawt com.jogamp.opengl.test.junit.newt.event.TestNewtKeyCodeModifiersAWT $* -#testawt com.jogamp.opengl.test.junit.newt.event.TestNewtEventModifiersNEWTWindowAWT $* +testawt com.jogamp.opengl.test.junit.newt.event.TestNewtEventModifiersNEWTWindowAWT $* #testawt com.jogamp.opengl.test.junit.newt.event.TestNewtEventModifiersAWTCanvas $* #testawt com.jogamp.opengl.test.junit.newt.event.TestNewtEventModifiersNewtCanvasAWT $* #testawtswt com.jogamp.opengl.test.junit.newt.event.TestNewtEventModifiersNewtCanvasSWTAWT $* diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java index 32a92ec8b..692741a88 100644 --- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java +++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java @@ -201,8 +201,6 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto }; class FocusTraversalKeyListener implements KeyListener { - boolean suppress = false; - public void keyPressed(KeyEvent e) { if( isParent() && !isFullscreen() ) { handleKey(e, false); @@ -213,21 +211,16 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto handleKey(e, true); } } - public void keyTyped(KeyEvent e) { - if(suppress) { - e.setConsumed(true); - suppress = false; // reset - } - } void handleKey(KeyEvent evt, boolean onRelease) { if(null == keyboardFocusManager) { throw new InternalError("XXX"); } final AWTKeyStroke ks = AWTKeyStroke.getAWTKeyStroke(evt.getKeyCode(), evt.getModifiers(), onRelease); + boolean suppress = false; if(null != ks) { final Set fwdKeys = keyboardFocusManager.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); - final Set bwdKeys = keyboardFocusManager.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS); + final Set bwdKeys = keyboardFocusManager.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS); if(fwdKeys.contains(ks)) { if(DEBUG) { System.err.println("NewtCanvasAWT.focusKey (fwd): "+ks+", current focusOwner "+keyboardFocusManager.getFocusOwner()); diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java index 091a1a5cf..35199dc82 100644 --- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java +++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java @@ -288,9 +288,10 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener { public void keyPressed(KeyEvent e) { } - public void keyReleased(KeyEvent e) { - } - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } if(e.getKeyChar()=='d') { glWindow.setUndecorated(!glWindow.isUndecorated()); } if(e.getKeyChar()=='f') { diff --git a/src/newt/classes/com/jogamp/newt/event/KeyAdapter.java b/src/newt/classes/com/jogamp/newt/event/KeyAdapter.java index 93c8409b1..42ebea722 100644 --- a/src/newt/classes/com/jogamp/newt/event/KeyAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/KeyAdapter.java @@ -35,7 +35,5 @@ public abstract class KeyAdapter implements KeyListener } public void keyReleased(KeyEvent e) { } - public void keyTyped(KeyEvent e) { - } } diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java index 6e63ad3a3..683a5ca54 100644 --- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java @@ -217,7 +217,6 @@ public class KeyEvent extends InputEvent switch(type) { case EVENT_KEY_PRESSED: return "EVENT_KEY_PRESSED"; case EVENT_KEY_RELEASED: return "EVENT_KEY_RELEASED"; - case EVENT_KEY_TYPED: return "EVENT_KEY_TYPED"; default: return "unknown (" + type + ")"; } } @@ -365,11 +364,6 @@ public class KeyEvent extends InputEvent public static final short EVENT_KEY_PRESSED = 300; /** A key has been released, excluding {@link #isAutoRepeat() auto-repeat} {@link #isModifierKey() modifier} keys. */ public static final short EVENT_KEY_RELEASED= 301; - /** - * A {@link #isPrintableKey() printable} key has been typed (pressed and released), excluding {@link #isAutoRepeat() auto-repeat}. - * @deprecated Redundant, will be removed soon. Use {@link #EVENT_KEY_RELEASED} and exclude non {@link #isPrintableKey() printable} keys and {@link #isAutoRepeat() auto-repeat}. - */ - public static final short EVENT_KEY_TYPED = 302; /** * This value, {@code '\0'}, is used to indicate that the keyChar is unknown or not printable. diff --git a/src/newt/classes/com/jogamp/newt/event/KeyListener.java b/src/newt/classes/com/jogamp/newt/event/KeyListener.java index 5bca733d3..b3927d81a 100644 --- a/src/newt/classes/com/jogamp/newt/event/KeyListener.java +++ b/src/newt/classes/com/jogamp/newt/event/KeyListener.java @@ -43,13 +43,19 @@ public interface KeyListener extends NEWTEventListener { /** A key has been {@link KeyEvent#EVENT_KEY_PRESSED pressed}, excluding {@link #isAutoRepeat() auto-repeat} {@link #isModifierKey() modifier} keys. See {@link KeyEvent}. */ public void keyPressed(KeyEvent e); - /** A key has been {@link KeyEvent#EVENT_KEY_RELEASED released}, excluding {@link #isAutoRepeat() auto-repeat} {@link #isModifierKey() modifier} keys. See {@link KeyEvent}. */ - public void keyReleased(KeyEvent e); /** - * A {@link #isPrintableKey() printable} key has been {@link KeyEvent#EVENT_KEY_TYPED typed} (pressed and released), excluding {@link #isAutoRepeat() auto-repeat}. See {@link KeyEvent}. - * @deprecated Redundant, will be removed soon. Use {@link #keyReleased(KeyEvent)} and exclude non {@link #isPrintableKey() printable} keys and {@link #isAutoRepeat() auto-repeat}. - */ - public void keyTyped(KeyEvent e) ; + * A key has been {@link KeyEvent#EVENT_KEY_RELEASED released}, excluding {@link #isAutoRepeat() auto-repeat} {@link #isModifierKey() modifier} keys. See {@link KeyEvent}. + *

    + * To simulated the removed keyTyped(KeyEvent e) semantics, + * simply apply the following constraints upfront and bail out if not matched, i.e.: + *

    +        if( !e.isPrintableKey() || e.isAutoRepeat() ) {
    +            return;
    +        }            
    +     * 
    + *

    + */ + public void keyReleased(KeyEvent e); } diff --git a/src/newt/classes/com/jogamp/newt/event/TraceKeyAdapter.java b/src/newt/classes/com/jogamp/newt/event/TraceKeyAdapter.java index 98ba5a24d..629dc50d7 100644 --- a/src/newt/classes/com/jogamp/newt/event/TraceKeyAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/TraceKeyAdapter.java @@ -48,9 +48,5 @@ public class TraceKeyAdapter implements KeyListener { System.err.println(e); if(null!=downstream) { downstream.keyReleased(e); } } - public void keyTyped(KeyEvent e) { - System.err.println(e); - if(null!=downstream) { downstream.keyTyped(e); } - } } diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 805ad08ad..dca287c6b 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -2476,7 +2476,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer return keyListeners.toArray(new KeyListener[keyListeners.size()]); } - @SuppressWarnings("deprecation") private final boolean propagateKeyEvent(KeyEvent e, KeyListener l) { switch(e.getEventType()) { case KeyEvent.EVENT_KEY_PRESSED: @@ -2485,40 +2484,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer case KeyEvent.EVENT_KEY_RELEASED: l.keyReleased(e); break; - case KeyEvent.EVENT_KEY_TYPED: - l.keyTyped(e); - break; default: throw new NativeWindowException("Unexpected key event type " + e.getEventType()); } return e.isConsumed(); } - @SuppressWarnings("deprecation") protected void consumeKeyEvent(KeyEvent e) { - boolean consumedE = false, consumedTyped = false; - if( KeyEvent.EVENT_KEY_TYPED == e.getEventType() ) { - throw new InternalError("Deprecated KeyEvent.EVENT_KEY_TYPED is synthesized - don't send/enqueue it!"); - } - - // Synthesize deprecated event KeyEvent.EVENT_KEY_TYPED - final KeyEvent eTyped; - if( KeyEvent.EVENT_KEY_RELEASED == e.getEventType() && e.isPrintableKey() && !e.isAutoRepeat() ) { - eTyped = KeyEvent.create(KeyEvent.EVENT_KEY_TYPED, e.getSource(), e.getWhen(), e.getModifiers(), e.getKeyCode(), e.getKeySymbol(), e.getKeyChar()); - } else { - eTyped = null; - } + boolean consumedE = false; if(null != keyboardFocusHandler) { consumedE = propagateKeyEvent(e, keyboardFocusHandler); if(DEBUG_KEY_EVENT) { System.err.println("consumeKeyEvent: "+e+", keyboardFocusHandler consumed: "+consumedE); } - if( null != eTyped ) { - consumedTyped = propagateKeyEvent(eTyped, keyboardFocusHandler); - if(DEBUG_KEY_EVENT) { - System.err.println("consumeKeyEvent: "+eTyped+", keyboardFocusHandler consumed: "+consumedTyped); - } - } } if(DEBUG_KEY_EVENT) { if( !consumedE ) { @@ -2528,16 +2506,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer for(int i = 0; !consumedE && i < keyListeners.size(); i++ ) { consumedE = propagateKeyEvent(e, keyListeners.get(i)); } - if( null != eTyped ) { - if(DEBUG_KEY_EVENT) { - if( !consumedTyped ) { - System.err.println("consumeKeyEvent: "+eTyped); - } - } - for(int i = 0; !consumedTyped && i < keyListeners.size(); i++ ) { - consumedTyped = propagateKeyEvent(eTyped, keyListeners.get(i)); - } - } } // diff --git a/src/newt/native/KeyEvent.h b/src/newt/native/KeyEvent.h index a182db973..59977d565 100644 --- a/src/newt/native/KeyEvent.h +++ b/src/newt/native/KeyEvent.h @@ -31,7 +31,6 @@ #define EVENT_KEY_PRESSED 300 #define EVENT_KEY_RELEASED 301 -#define EVENT_KEY_TYPED 302 #define J_VK_UNDEFINED ( 0x0U ) #define J_VK_HOME ( 0x02U ) diff --git a/src/newt/native/X11Event.c b/src/newt/native/X11Event.c index 770f60e8f..32a55c67c 100644 --- a/src/newt/native/X11Event.c +++ b/src/newt/native/X11Event.c @@ -170,15 +170,9 @@ void X11EventPoll(JNIEnv *env, jobject obj, Display *dpy, jlong javaObjectAtom, #ifdef USE_SENDIO_DIRECT (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED, modifiers, keySym, (jchar) -1); - - (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED, - modifiers, keySym, (jchar) keyChar); #else (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_RELEASED, modifiers, keySym, (jchar) -1); - - (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_TYPED, - modifiers, keySym, (jchar) keyChar); #endif break; diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index e567781cf..3f50f27a4 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -699,7 +699,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0 XGetWindowAttributes(dpy, w, &xwa); // prefetch colormap to be destroyed after window destruction XSelectInput(dpy, w, 0); XUnmapWindow(dpy, w); - XSync(dpy, False); // Drain all events related to this window .. Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom /*, kbdHandle */); // XKB disabled for now diff --git a/src/newt/native/XCBEvent.c b/src/newt/native/XCBEvent.c index f067f4b7a..d02d5a4ba 100644 --- a/src/newt/native/XCBEvent.c +++ b/src/newt/native/XCBEvent.c @@ -176,15 +176,9 @@ void XCBEventPoll(JNIEnv *env, jobject obj, Display *dpy, jlong javaObjectAtom, #ifdef USE_SENDIO_DIRECT (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED, modifiers, X11KeySym2NewtVKey(_evt->state), (jchar) keyChar); - - (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED, - modifiers, (jint) -1, (jchar) keyChar); #else (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_RELEASED, modifiers, X11KeySym2NewtVKey(_evt->state), (jchar) keyChar); - - (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_TYPED, - modifiers, (jint) -1, (jchar) keyChar); #endif } break; diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java index 6378c1ee3..4ebb937a0 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java @@ -293,7 +293,6 @@ public abstract class GPURendererListenerBase01 implements GLEventListener { } } } - public void keyTyped(KeyEvent arg0) {} public void keyReleased(KeyEvent arg0) {} } } diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java index 658d4a4f1..31377025a 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java @@ -295,10 +295,13 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB } } - public void keyTyped(KeyEvent arg0) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } if(userInput) { - char c = arg0.getKeyChar(); - + char c = e.getKeyChar(); + if(c == 0x0d) { userInput = false; setIgnoreInput(false); @@ -309,6 +312,5 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB } } } - public void keyReleased(KeyEvent arg0) {} } } diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java index 15daf70cd..c94b63494 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java @@ -317,7 +317,6 @@ public abstract class UIListenerBase01 implements GLEventListener { } } } - public void keyTyped(KeyEvent arg0) {} public void keyReleased(KeyEvent arg0) {} } } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java index b3c542c63..87d4df342 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMix2DemosES2NEWT.java @@ -152,7 +152,10 @@ public class TestFBOMix2DemosES2NEWT extends UITestCase { }); glWindow.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } System.err.println("*** "+e); if(e.getKeyChar()=='f') { new Thread() { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyNEWT.java index 67e8524a3..f184873be 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyNEWT.java @@ -85,7 +85,10 @@ public class TestTranslucencyNEWT extends UITestCase { final GLWindow f_glWindow = glWindow; glWindow.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } if(e.getKeyChar()=='f') { new Thread() { public void run() { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java index 05cc2aeb0..34fa79b5a 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java @@ -84,7 +84,10 @@ public class TestGearsES1NEWT extends UITestCase { final GLWindow f_glWindow = glWindow; glWindow.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } if(e.getKeyChar()=='f') { new Thread() { public void run() { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java index b0e6b2b00..478195c99 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java @@ -82,7 +82,10 @@ public class TestRedSquareES1NEWT extends UITestCase { final GLWindow f_glWindow = glWindow; glWindow.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } if(e.getKeyChar()=='f') { new Thread() { public void run() { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java index 7f2713354..b7c4e729e 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java @@ -82,7 +82,10 @@ public class MovieCube implements GLEventListener, GLMediaEventListener { } private final KeyListener keyAction = new KeyAdapter() { - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } System.err.println("MC "+e); int pts0 = mPlayer.getCurrentPosition(); int pts1 = 0; diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestElektronenMultipliziererNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestElektronenMultipliziererNEWT.java index ed308bdfd..e22b00dff 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestElektronenMultipliziererNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestElektronenMultipliziererNEWT.java @@ -103,7 +103,10 @@ public class TestElektronenMultipliziererNEWT extends UITestCase { final GLWindow f_glWindow = glWindow; glWindow.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } if(e.getKeyChar()=='f') { new Thread() { public void run() { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java index bf47109fa..f12f02c5e 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java @@ -269,7 +269,10 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { }); glWindow.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } if(e.getKeyChar()=='f') { quitAdapter.enable(false); new Thread() { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasSWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasSWT.java index 9d9e3a876..eed2e1267 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasSWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasSWT.java @@ -178,7 +178,10 @@ public class TestGearsES2NewtCanvasSWT extends UITestCase { }); glWindow.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } if(e.getKeyChar()=='f') { new Thread() { public void run() { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NEWT.java index 4ca70d7d3..281ee54f9 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NEWT.java @@ -80,7 +80,10 @@ public class TestLandscapeES2NEWT extends UITestCase { glWindow.addWindowListener(quitAdapter); glWindow.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } if(e.getKeyChar()=='f') { new Thread() { public void run() { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java index c1df18c19..72357dc29 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java @@ -117,7 +117,10 @@ public class TestLandscapeES2NewtCanvasAWT extends UITestCase { }); glWindow.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } if(e.getKeyChar()=='f') { quitAdapter.enable(false); new Thread() { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java index 0e5842b23..b880c2f3b 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java @@ -93,7 +93,10 @@ public class TestRedSquareES2NEWT extends UITestCase { glWindow.addWindowListener(quitAdapter); glWindow.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } if(e.getKeyChar()=='f') { new Thread() { public void run() { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java index 93dc885b6..3c33a4899 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java @@ -83,7 +83,10 @@ public class TestGearsNEWT extends UITestCase { final GLWindow f_glWindow = glWindow; glWindow.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } if(e.getKeyChar()=='f') { new Thread() { public void run() { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlockAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlockAWT.java index d1b276105..0f9c50baa 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlockAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlockAWT.java @@ -308,7 +308,10 @@ public class TestNewtCanvasSWTBug628ResizeDeadlockAWT extends UITestCase { glWindow.addGLEventListener( new BigFlashingX() ) ; glWindow.addKeyListener(new KeyAdapter() { @Override - public void keyTyped(com.jogamp.newt.event.KeyEvent e) { + public void keyReleased(com.jogamp.newt.event.KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } System.err.print("."); glWindow.display(); } diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodeModifiersAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodeModifiersAWT.java index b075af977..c1b572df3 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodeModifiersAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodeModifiersAWT.java @@ -159,48 +159,40 @@ public class TestNewtKeyCodeModifiersAWT extends UITestCase { testNewtCanvasAWT_Impl(false); } - @SuppressWarnings("deprecation") static void testKeyCodeModifier(Robot robot, NEWTKeyAdapter keyAdapter, short modifierKey, int modifierMask, short keyCode, char keyCharOnly, char keyCharMod) { keyAdapter.reset(); AWTRobotUtil.newtKeyPress(0, robot, true, keyCode, 10); // press keyCode - AWTRobotUtil.newtKeyPress(0, robot, false, keyCode, 100); // release+typed keyCode + AWTRobotUtil.newtKeyPress(0, robot, false, keyCode, 100); // release keyCode robot.waitForIdle(); - for(int j=0; j < 100 && keyAdapter.getQueueSize() < 3; j++) { // wait until events are collected + for(int j=0; j < 100 && keyAdapter.getQueueSize() < 2; j++) { // wait until events are collected robot.delay(100); } AWTRobotUtil.newtKeyPress(0, robot, true, modifierKey, 10); // press MOD AWTRobotUtil.newtKeyPress(0, robot, true, keyCode, 10); // press keyCode - AWTRobotUtil.newtKeyPress(0, robot, false, keyCode, 10); // release+typed keyCode + AWTRobotUtil.newtKeyPress(0, robot, false, keyCode, 10); // release keyCode AWTRobotUtil.newtKeyPress(0, robot, false, modifierKey, 100); // release MOD robot.waitForIdle(); - for(int j=0; j < 100 && keyAdapter.getQueueSize() < 3+5; j++) { // wait until events are collected + for(int j=0; j < 100 && keyAdapter.getQueueSize() < 2+4; j++) { // wait until events are collected robot.delay(100); } - final int modTypedCount = KeyEvent.NULL_CHAR != keyCharMod ? 2 : -1 ; // ignore due to mods 'isPrintable' impact. NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, - 3 /* press-SI */, 3 /* release-SI */, modTypedCount /* typed-SI */, - 0 /* press-AR */, 0 /* release-AR */, 0 /* typed-AR */ ); + 3 /* press-SI */, 3 /* release-SI */, + 0 /* press-AR */, 0 /* release-AR */ ); final List queue = keyAdapter.getQueued(); int i=0; NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, 0, keyCode, keyCharOnly); NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, 0, keyCode, keyCharOnly); - NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_TYPED, 0, keyCode, keyCharOnly); NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, modifierMask, modifierKey, KeyEvent.NULL_CHAR); NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, modifierMask, keyCode, keyCharMod); NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, modifierMask, keyCode, keyCharMod); KeyEvent e = (KeyEvent) queue.get(i++); - if( KeyEvent.EVENT_KEY_TYPED == e.getEventType() ) { // optional, due to mods 'isPrintable' impact. - NEWTKeyUtil.validateKeyEvent(e, KeyEvent.EVENT_KEY_TYPED, modifierMask, keyCode, keyCharMod); - e = (KeyEvent) queue.get(i++); - } NEWTKeyUtil.validateKeyEvent(e, KeyEvent.EVENT_KEY_RELEASED, modifierMask, modifierKey, KeyEvent.NULL_CHAR); } - @SuppressWarnings("deprecation") static void testKeyCodeAllModifierV1(Robot robot, NEWTKeyAdapter keyAdapter) { final short m1k = KeyEvent.VK_ALT; final int m1m = InputEvent.ALT_MASK; @@ -215,18 +207,18 @@ public class TestNewtKeyCodeModifiersAWT extends UITestCase { AWTRobotUtil.newtKeyPress(0, robot, true, m3k, 10); // press MOD3 AWTRobotUtil.newtKeyPress(0, robot, true, KeyEvent.VK_1, 10); // press P - AWTRobotUtil.newtKeyPress(0, robot, false, KeyEvent.VK_1, 100); // release+typed P + AWTRobotUtil.newtKeyPress(0, robot, false, KeyEvent.VK_1, 100); // release P AWTRobotUtil.newtKeyPress(0, robot, false, m3k, 10); // release MOD AWTRobotUtil.newtKeyPress(0, robot, false, m2k, 10); // release MOD AWTRobotUtil.newtKeyPress(0, robot, false, m1k, 10); // release MOD robot.waitForIdle(); - for(int j=0; j < 100 && keyAdapter.getQueueSize() < 4+4+1; j++) { // wait until events are collected + for(int j=0; j < 100 && keyAdapter.getQueueSize() < 4+4; j++) { // wait until events are collected robot.delay(100); } NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, - 4 /* press-SI */, 4 /* release-SI */, -1 /* typed-SI - ignored, since unknow whether printable w/ all mods */, - 0 /* press-AR */, 0 /* release-AR */, 0 /* typed-AR */ ); + 4 /* press-SI */, 4 /* release-SI */, + 0 /* press-AR */, 0 /* release-AR */ ); final List queue = keyAdapter.getQueued(); int i=0; @@ -237,10 +229,6 @@ public class TestNewtKeyCodeModifiersAWT extends UITestCase { NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_PRESSED, m1m|m2m|m3m, KeyEvent.VK_1, KeyEvent.NULL_CHAR); NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m|m3m, KeyEvent.VK_1, KeyEvent.NULL_CHAR); KeyEvent e = (KeyEvent) queue.get(i++); - if( KeyEvent.EVENT_KEY_TYPED == e.getEventType() ) { // optional, due to mods 'isPrintable' impact. - NEWTKeyUtil.validateKeyEvent(e, KeyEvent.EVENT_KEY_TYPED, m1m|m2m|m3m, KeyEvent.VK_1, KeyEvent.NULL_CHAR); - e = (KeyEvent) queue.get(i++); - } NEWTKeyUtil.validateKeyEvent(e, KeyEvent.EVENT_KEY_RELEASED, m1m|m2m|m3m, m3k, KeyEvent.NULL_CHAR); NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m|m2m, m2k, KeyEvent.NULL_CHAR); NEWTKeyUtil.validateKeyEvent((KeyEvent) queue.get(i++), KeyEvent.EVENT_KEY_RELEASED, m1m, m1k, KeyEvent.NULL_CHAR); diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodesAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodesAWT.java index fb42141ea..a5f47e870 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodesAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyCodesAWT.java @@ -210,9 +210,6 @@ public class TestNewtKeyCodesAWT extends UITestCase { break; } eventCount++; - if( KeyEvent.isPrintableKey(c, false) ) { - eventCount++; - } robot.waitForIdle(); } for(int j=0; j < 20 && keyAdapter.getQueueSize() < eventCount; j++) { // wait until events are collected diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventAutoRepeatAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventAutoRepeatAWT.java index d7de4e735..f3a5c4aa9 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventAutoRepeatAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventAutoRepeatAWT.java @@ -153,7 +153,6 @@ public class TestNewtKeyEventAutoRepeatAWT extends UITestCase { glWindow.destroy(); } - @SuppressWarnings("deprecation") static void testKeyEventAutoRepeat(Robot robot, NEWTKeyAdapter keyAdapter, int loops, int pressDurationMS) { System.err.println("KEY Event Auto-Repeat Test: "+loops); EventObject[][] first = new EventObject[loops][3]; @@ -167,8 +166,8 @@ public class TestNewtKeyEventAutoRepeatAWT extends UITestCase { robot.waitForIdle(); AWTRobotUtil.keyPress(0, robot, false, java.awt.event.KeyEvent.VK_A, 500); // 1s .. no AR anymore robot.waitForIdle(); - final int minCodeCount = firstIdx + 3; - final int desiredCodeCount = firstIdx + 6; + final int minCodeCount = firstIdx + 2; + final int desiredCodeCount = firstIdx + 4; for(int j=0; j < 10 && keyAdapter.getQueueSize() < desiredCodeCount; j++) { // wait until events are collected robot.delay(100); } @@ -206,15 +205,15 @@ public class TestNewtKeyEventAutoRepeatAWT extends UITestCase { final int expSI, expAR; if( hasAR ) { expSI = perLoopSI * loops; - expAR = ( keyEvents.size() - expSI*3 ) / 2; // AR: no typed -> 2, SI: typed -> 3 + expAR = ( keyEvents.size() - expSI*2 ) / 2; // auto-repeat release } else { - expSI = keyEvents.size() / 3; // all typed events + expSI = keyEvents.size() / 2; // all released events expAR = 0; } NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, - expSI /* press-SI */, expSI /* release-SI */, expSI /* typed-SI */, - expAR /* press-AR */, expAR /* release-AR */, 0 /* typed-AR */ ); + expSI /* press-SI */, expSI /* release-SI */, + expAR /* press-AR */, expAR /* release-AR */ ); } if( !hasAR ) { @@ -246,17 +245,17 @@ public class TestNewtKeyEventAutoRepeatAWT extends UITestCase { e = (KeyEvent) last[i][0]; Assert.assertTrue("last-2 Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() ); - Assert.assertTrue("last-2 Shall be PRESSED, but is "+e, KeyEvent.EVENT_KEY_PRESSED == e.getEventType() ); + Assert.assertTrue("last-2 Shall be RELEASED, but is "+e, KeyEvent.EVENT_KEY_RELEASED == e.getEventType() ); Assert.assertTrue("last-2 Shall be AR, but is "+e, 0 != ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) ); e = (KeyEvent) last[i][1]; Assert.assertTrue("last-1 Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() ); - Assert.assertTrue("last-1 Shall be RELEASED, but is "+e, KeyEvent.EVENT_KEY_RELEASED == e.getEventType() ); - Assert.assertTrue("last-1 Shall not be AR, but is "+e, 0 == ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) ); + Assert.assertTrue("last-1 Shall be PRESSED, but is "+e, KeyEvent.EVENT_KEY_PRESSED == e.getEventType() ); + Assert.assertTrue("last-1 Shall be AR, but is "+e, 0 != ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) ); e = (KeyEvent) last[i][2]; Assert.assertTrue("last-0 Shall be A, but is "+e, KeyEvent.VK_A == e.getKeyCode() ); - Assert.assertTrue("last-0 Shall be TYPED, but is "+e, KeyEvent.EVENT_KEY_TYPED == e.getEventType() ); + Assert.assertTrue("last-2 Shall be RELEASED, but is "+e, KeyEvent.EVENT_KEY_RELEASED == e.getEventType() ); Assert.assertTrue("last-0 Shall not be AR, but is "+e, 0 == ( InputEvent.AUTOREPEAT_MASK & e.getModifiers() ) ); } } diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventOrderAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventOrderAWT.java index bdf932904..68ccecf6b 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventOrderAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyEventOrderAWT.java @@ -191,8 +191,8 @@ public class TestNewtKeyEventOrderAWT extends UITestCase { final int expTotal = 6*loops; // all typed events NEWTKeyUtil.validateKeyAdapterStats(keyAdapter, - expTotal /* press-SI */, expTotal /* release-SI */, expTotal /* typed-SI */, - 0 /* press-AR */, 0 /* release-AR */, 0 /* typed-AR */ ); + expTotal /* press-SI */, expTotal /* release-SI */, + 0 /* press-AR */, 0 /* release-AR */ ); } diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyPressReleaseUnmaskRepeatAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyPressReleaseUnmaskRepeatAWT.java index 2a35a15eb..d70259f13 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyPressReleaseUnmaskRepeatAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/event/TestNewtKeyPressReleaseUnmaskRepeatAWT.java @@ -215,11 +215,6 @@ public class TestNewtKeyPressReleaseUnmaskRepeatAWT extends UITestCase { System.err.println(seq+": "+e); } } - - @Override - public void keyTyped(KeyEvent e) { - } - } public static void main(String args[]) throws IOException { diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/KeyAction.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/KeyAction.java index 3313ec65c..0ae94d7af 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/KeyAction.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/KeyAction.java @@ -38,7 +38,10 @@ class KeyAction extends KeyAdapter { this.eventFifo = eventFifo; } - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } eventFifo.put(e); } } diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java index 15393e8ea..9d08d8ff4 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java @@ -47,7 +47,10 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter { this.glWindow = glWindow; } - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } if(e.getKeyChar()=='i') { System.err.println(glWindow); } else if(e.getKeyChar()=='d') { diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java index a1f07bda6..d340fc280 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java @@ -146,7 +146,10 @@ public class TestParentingFocusTraversal01AWT extends UITestCase { glWindow1.addGLEventListener(demo1); glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1)); glWindow1.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } if(e.getKeyChar()=='c') { System.err.println("Focus Clear"); if(glWindow1.getDelegatedWindow() instanceof DriverClearFocus) { diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java index 837ba5da1..776c3c7eb 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java @@ -36,7 +36,7 @@ import java.util.List; public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements KeyEventCountAdapter { String prefix; - int keyPressed, keyReleased, keyTyped; + int keyPressed, keyReleased; boolean pressed; List queue = new ArrayList(); boolean verbose = true; @@ -53,7 +53,7 @@ public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements KeyEvent } public synchronized int getCount() { - return keyTyped; + return keyReleased; } public synchronized int getKeyPressedCount(boolean autoRepeatOnly) { @@ -64,10 +64,6 @@ public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements KeyEvent return keyReleased; } - public synchronized int getKeyTypedCount(boolean autoRepeatOnly) { - return keyTyped; - } - public synchronized List getQueued() { return queue; } @@ -77,7 +73,6 @@ public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements KeyEvent } public synchronized void reset() { - keyTyped = 0; keyPressed = 0; keyReleased = 0; pressed = false; @@ -102,14 +97,6 @@ public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements KeyEvent } } - public synchronized void keyTyped(java.awt.event.KeyEvent e) { - keyTyped++; - queue.add(e); - if( verbose ) { - System.err.println("KEY AWT TYPED ["+keyTyped+"]: "+prefix+", "+e); - } - } - - public String toString() { return prefix+"[pressed "+pressed+", typed "+keyTyped+"]"; } + public String toString() { return prefix+"[pressed "+pressed+", keyReleased "+keyReleased+"]"; } } diff --git a/src/test/com/jogamp/opengl/test/junit/util/KeyEventCountAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/KeyEventCountAdapter.java index 832f5ae82..1d6d97a17 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/KeyEventCountAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/KeyEventCountAdapter.java @@ -31,8 +31,6 @@ package com.jogamp.opengl.test.junit.util; public interface KeyEventCountAdapter extends InputEventCountAdapter { public int getKeyPressedCount(boolean autoRepeatOnly); - public int getKeyReleasedCount(boolean autoRepeatOnly); - - public int getKeyTypedCount(boolean autoRepeatOnly); + public int getKeyReleasedCount(boolean autoRepeatOnly); } diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java index f19169b42..88ed74a3f 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java @@ -39,8 +39,8 @@ import com.jogamp.newt.event.KeyEvent; public class NEWTKeyAdapter extends KeyAdapter implements KeyEventCountAdapter { String prefix; - int keyPressed, keyReleased, keyTyped; - int keyPressedAR, keyReleasedAR, keyTypedAR; + int keyPressed, keyReleased; + int keyPressedAR, keyReleasedAR; boolean pressed; List queue = new ArrayList(); boolean verbose = true; @@ -57,7 +57,7 @@ public class NEWTKeyAdapter extends KeyAdapter implements KeyEventCountAdapter { } public synchronized int getCount() { - return keyTyped; + return keyReleased; } public synchronized int getKeyPressedCount(boolean autoRepeatOnly) { @@ -68,10 +68,6 @@ public class NEWTKeyAdapter extends KeyAdapter implements KeyEventCountAdapter { return autoRepeatOnly ? keyReleasedAR: keyReleased; } - public synchronized int getKeyTypedCount(boolean autoRepeatOnly) { - return autoRepeatOnly ? keyTypedAR: keyTyped; - } - public synchronized List getQueued() { return queue; } @@ -81,10 +77,8 @@ public class NEWTKeyAdapter extends KeyAdapter implements KeyEventCountAdapter { } public synchronized void reset() { - keyTyped = 0; keyPressed = 0; keyReleased = 0; - keyTypedAR = 0; keyPressedAR = 0; keyReleasedAR = 0; pressed = false; @@ -115,18 +109,6 @@ public class NEWTKeyAdapter extends KeyAdapter implements KeyEventCountAdapter { } } - @Override - public synchronized void keyTyped(KeyEvent e) { - keyTyped++; - if( 0 != ( e.getModifiers() & InputEvent.AUTOREPEAT_MASK ) ) { - keyTypedAR++; - } - queue.add(e); - if( verbose ) { - System.err.println("KEY NEWT TYPED ["+keyTyped+"]: "+prefix+", "+e); - } - } - - public String toString() { return prefix+"[pressed "+pressed+", typed "+keyTyped+"]"; } + public String toString() { return prefix+"[pressed "+pressed+", keyReleased "+keyReleased+"]"; } } diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java index 1def57edf..990930994 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java +++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyUtil.java @@ -104,11 +104,7 @@ public class NEWTKeyUtil { missCodes.add(new CodeEvent(c, codeSeg.description, e)); misses++; } - if( KeyEvent.isPrintableKey(c, false) ) { - evtIdx += 3; // w/ TYPED - } else { - evtIdx += 2; - } + evtIdx += 2; } } final boolean res = evtIdx == keyEvents.size() && 0 == missCodes.size(); @@ -133,16 +129,13 @@ public class NEWTKeyUtil { } } - @SuppressWarnings("deprecation") public static short getNextKeyEventType(KeyEvent e) { final int et = e.getEventType(); switch( et ) { case KeyEvent.EVENT_KEY_PRESSED: return KeyEvent.EVENT_KEY_RELEASED; case KeyEvent.EVENT_KEY_RELEASED: - return e.isPrintableKey() && !e.isAutoRepeat() ? KeyEvent.EVENT_KEY_TYPED : KeyEvent.EVENT_KEY_PRESSED; - case KeyEvent.EVENT_KEY_TYPED: - return KeyEvent.EVENT_KEY_PRESSED; + return KeyEvent.EVENT_KEY_PRESSED; default: Assert.assertTrue("Invalid event "+e, false); return 0; @@ -168,14 +161,12 @@ public class NEWTKeyUtil { * @param keyAdapter * @param expPressedCountSI number of single key press events * @param expReleasedCountSI number of single key release events - * @param expTypedCountSI number of single key types events, set to -1 to ignore * @param expPressedCountAR number of auto-repeat key press events * @param expReleasedCountAR number of auto-repeat key release events - * @param expTypedCountAR number of auto-repeat key types events, set to -1 to ignore */ public static void validateKeyAdapterStats(NEWTKeyAdapter keyAdapter, - int expPressedCountSI, int expReleasedCountSI, int expTypedCountSI, - int expPressedCountAR, int expReleasedCountAR, int expTypedCountAR) { + int expPressedCountSI, int expReleasedCountSI, + int expPressedCountAR, int expReleasedCountAR) { final int expPressReleaseCountSI = expPressedCountSI + expReleasedCountSI; final int expPressReleaseCountAR = expPressedCountAR + expReleasedCountAR; final int expPressReleaseCountALL = expPressReleaseCountSI + expPressReleaseCountAR; @@ -184,36 +175,25 @@ public class NEWTKeyUtil { final int keyPressedAR = keyAdapter.getKeyPressedCount(true); final int keyReleasedALL = keyAdapter.getKeyReleasedCount(false); final int keyReleasedAR = keyAdapter.getKeyReleasedCount(true); - final int keyTypedALL = keyAdapter.getKeyTypedCount(false); - final int keyTypedAR = keyAdapter.getKeyTypedCount(true); final int keyPressedSI = keyPressedALL-keyPressedAR; final int keyReleasedSI = keyReleasedALL-keyReleasedAR; - final int keyTypedSI = keyTypedALL-keyTypedAR; final int pressReleaseCountALL = keyPressedALL + keyReleasedALL; final int pressReleaseCountSI = keyPressedSI + keyReleasedSI; final int pressReleaseCountAR = keyPressedAR + keyReleasedAR; - System.err.println("Expec Single Press "+expPressedCountSI +", Release "+expReleasedCountSI +", Typed "+expTypedCountSI); - System.err.println("Expec AutoRp Press "+expPressedCountAR +", Release "+expReleasedCountAR +", Typed "+expTypedCountAR); + System.err.println("Expec Single Press "+expPressedCountSI +", Release "+expReleasedCountSI); + System.err.println("Expec AutoRp Press "+expPressedCountAR +", Release "+expReleasedCountAR); - System.err.println("Total Single Press "+keyPressedSI +", Release "+keyReleasedSI +", Typed "+keyTypedSI +", Events "+pressReleaseCountSI); - System.err.println("Total AutoRp Press "+keyPressedAR +", Release "+keyReleasedAR +", Typed "+keyTypedAR +", Events "+pressReleaseCountAR); - System.err.println("Total ALL Press "+keyPressedALL +", Release "+keyReleasedALL +", Typed "+keyTypedALL+", Events "+pressReleaseCountALL); + System.err.println("Total Single Press "+keyPressedSI +", Release "+keyReleasedSI +", Events "+pressReleaseCountSI); + System.err.println("Total AutoRp Press "+keyPressedAR +", Release "+keyReleasedAR +", Events "+pressReleaseCountAR); + System.err.println("Total ALL Press "+keyPressedALL +", Release "+keyReleasedALL +", Events "+pressReleaseCountALL); Assert.assertEquals("Internal Error: pressReleaseSI != pressReleaseALL - pressReleaseAR", pressReleaseCountSI, pressReleaseCountALL - pressReleaseCountAR); - Assert.assertEquals("Invalid: Has AR Typed events", 0, keyTypedAR); - if( 0 <= expTypedCountAR ) { - Assert.assertEquals("Invalid: Exp AR Typed events", 0, expTypedCountAR); - } - Assert.assertEquals("Key press count failure (SI)", expPressedCountSI, keyPressedSI); Assert.assertEquals("Key released count failure (SI)", expReleasedCountSI, keyReleasedSI); - if( 0 <= expTypedCountSI ) { - Assert.assertEquals("Key typed count failure (SI)", expTypedCountSI, keyTypedSI); - } Assert.assertEquals("Key press count failure (AR)", expPressedCountAR, keyPressedAR); Assert.assertEquals("Key released count failure (AR)", expReleasedCountAR, keyReleasedAR); @@ -224,6 +204,6 @@ public class NEWTKeyUtil { final List keyEvents = keyAdapter.getQueued(); Assert.assertEquals("Key pressRelease count failure (ALL) w/ list sum ", expPressReleaseCountALL, pressReleaseCountALL); - Assert.assertEquals("Key total count failure (ALL) w/ list size ", pressReleaseCountALL + keyTypedALL, keyEvents.size()); + Assert.assertEquals("Key total count failure (ALL) w/ list size ", pressReleaseCountALL, keyEvents.size()); } } diff --git a/src/test/com/jogamp/opengl/test/junit/util/QuitAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/QuitAdapter.java index 59e243171..b5864e39c 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/QuitAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/QuitAdapter.java @@ -47,7 +47,10 @@ public class QuitAdapter extends WindowAdapter implements WindowListener, KeyLis } } - public void keyTyped(KeyEvent e) { + public void keyReleased(KeyEvent e) { + if( !e.isPrintableKey() || e.isAutoRepeat() ) { + return; + } if( enabled ) { if(e.getKeyChar()=='q') { System.err.println("QUIT Key "+Thread.currentThread()); @@ -56,6 +59,5 @@ public class QuitAdapter extends WindowAdapter implements WindowListener, KeyLis } } public void keyPressed(KeyEvent e) {} - public void keyReleased(KeyEvent e) {} } -- cgit v1.2.3 From 205a17de1abec614d3d06386f873170fc1691e86 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 2 Jul 2013 15:10:20 +0200 Subject: Fix Bug 770 and 771 Bug 770: X11Window.c: - Request focus _before_ enabling EWMH flags (fullscreen or above) after resize and temporary invisibility. This actually allows us to keep the focus after resize and repositioning! - Set _NET_WM_BYPASS_COMPOSITOR implicit analog to _NET_WM_STATE_FLAG_ABOVE - Clean up _NET_WM_* flag names, avoiding name space collisions, i.e. adding FLAG! - Remove dead _NET_WM_STATE setting via direct window property (not working anyways) - Remove dead code: FS_GRAB_KEYBOARD X11/WindowDriver.java: - Enable _NET_WM_STATE_FLAG_ABOVE temporarily if FLAG_IS_FULLSCREEN && !FLAG_IS_ALWAYSONTOP - Override focusChanged(..) to react on focus lost/gained in case of temporarily enabled _NET_WM_STATE_FLAG_ABOVE. If focus is lost, disable _NET_WM_STATE_FLAG_ABOVE, otherwise re-enable it. WindowImpl.java: - FullscreenAction.run: Always use 'FLAG_IS_FULLSCREEN_SPAN' +++ Bug 771: WindowImpl.java: - Keep fullscreenMonitors and fullscreenUseMainMonitor values intact, allowing them to be tracked. Remove duplicates in FullscreenAction class. - MonitorModeListenerImpl.monitorModeChanged: Add fullscreen path: If the changed monitor is part of fullscreenMonitors, recalculate the viewport union and reset position and fullscreen-size. - MonitorModeListenerImpl: Try to regain focus after successful mode change. --- make/scripts/tests-win.bat | 5 +- make/scripts/tests.sh | 9 +- src/newt/classes/jogamp/newt/WindowImpl.java | 98 +++++++----- .../jogamp/newt/driver/x11/WindowDriver.java | 38 ++++- src/newt/native/X11Window.c | 159 +++++++----------- .../test/junit/newt/mm/TestScreenMode02aNEWT.java | 177 ++++++++++++--------- 6 files changed, 265 insertions(+), 221 deletions(-) (limited to 'src/newt/native/X11Window.c') diff --git a/make/scripts/tests-win.bat b/make/scripts/tests-win.bat index 17ac9c784..a5d368c48 100755 --- a/make/scripts/tests-win.bat +++ b/make/scripts/tests-win.bat @@ -61,7 +61,7 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGe REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT -time 5000 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelAWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelsAWT %* -scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT %* +REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NewtCanvasAWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT %* @@ -119,7 +119,8 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01aN REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01bNEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01cNEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01dNEWT %* -REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02sNEWT %* +scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02aNEWT %* +REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02bNEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.ManualScreenMode03sNEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple %* diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 5acced4af..c0d15b84b 100644 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -135,7 +135,8 @@ function jrun() { #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable" #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.X11Util" #D_ARGS="-Djogl.debug.GLDrawable" - #D_ARGS="-Dnewt.debug.Screen" + #D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.Window" + #D_ARGS="-Dnewt.debug.Window" #D_ARGS="-Dnewt.test.Screen.disableRandR13" #D_ARGS="-Dnewt.test.Screen.disableScreenMode -Dnewt.debug.Screen" #D_ARGS="-Dnewt.debug.Screen -Djogl.debug.Animator" @@ -175,7 +176,7 @@ function jrun() { #D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT -Djogl.debug.GLContext" #D_ARGS="-Dnewt.debug.Window -Djogl.debug.Animator -Dnewt.debug.Screen" #D_ARGS="-Dnativewindow.debug.JAWT -Dnewt.debug.Window" - D_ARGS="-Dnewt.debug.Window.KeyEvent" + #D_ARGS="-Dnewt.debug.Window.KeyEvent" #D_ARGS="-Dnewt.debug.Window.MouseEvent" #D_ARGS="-Dnewt.debug.Window.MouseEvent -Dnewt.debug.Window.KeyEvent" #D_ARGS="-Dnewt.debug.Window -Dnativewindow.debug=all" @@ -400,13 +401,13 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.newt.TestGLWindowInvisiblePointer01NEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT #testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle02NEWT -testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00aNEWT $* +#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00aNEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00bNEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01aNEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01bNEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01cNEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01dNEWT $* -#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02aNEWT $* +testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02aNEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02bNEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.mm.ManualScreenMode03aNEWT $* #testnoawt -Djava.awt.headless=true com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT $* diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 77ff21061..600035bf6 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -372,9 +372,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if(isFullscreen()) { synchronized(fullScreenAction) { fullscreen = false; // trigger a state change - fullScreenAction.init(true, fullscreenUseMainMonitor, fullscreenMonitors); - fullscreenMonitors = null; // release references ASAP - fullscreenUseMainMonitor = true; + fullScreenAction.init(true); fullScreenAction.run(); } } else { @@ -892,17 +890,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private class SetSizeAction implements Runnable { int width, height; + boolean disregardFS; - private SetSizeAction(int w, int h) { + private SetSizeAction(int w, int h, boolean disregardFS) { this.width = w; this.height = h; + this.disregardFS = disregardFS; } public final void run() { final RecursiveLock _lock = windowLock; _lock.lock(); try { - if ( !isFullscreen() && ( getWidth() != width || getHeight() != height ) ) { + if ( ( disregardFS || !isFullscreen() ) && ( getWidth() != width || getHeight() != height ) ) { if(DEBUG_IMPLEMENTATION) { System.err.println("Window setSize: START "+getWidth()+"x"+getHeight()+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible); } @@ -937,9 +937,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } + private void setFullscreenSize(int width, int height) { + runOnEDTIfAvail(true, new SetSizeAction(width, height, true)); + } @Override public void setSize(int width, int height) { - runOnEDTIfAvail(true, new SetSizeAction(width, height)); + runOnEDTIfAvail(true, new SetSizeAction(width, height, false)); } @Override public void setTopLevelSize(int width, int height) { @@ -1850,25 +1853,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private class FullScreenAction implements Runnable { boolean fullscreen; - List monitors; - boolean useMainMonitor; - private boolean init(boolean fullscreen, boolean useMainMonitor, List monitors) { + private boolean init(boolean fullscreen) { if(isNativeValid()) { this.fullscreen = fullscreen; - if( isFullscreen() != fullscreen ) { - this.monitors = monitors; - this.useMainMonitor = useMainMonitor; - return true; - } else { - this.monitors = null; - this.useMainMonitor = true; - return false; - } + return isFullscreen() != fullscreen; } else { WindowImpl.this.fullscreen = fullscreen; // set current state for createNative(..) - WindowImpl.this.fullscreenMonitors = monitors; - WindowImpl.this.fullscreenUseMainMonitor = useMainMonitor; return false; } } @@ -1886,16 +1877,27 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer final RectangleImmutable viewport; final int fs_span_flag; if(fullscreen) { - if( null == monitors ) { - if( useMainMonitor ) { - monitors = new ArrayList(); - monitors.add( getMainMonitor() ); + if( null == fullscreenMonitors ) { + if( fullscreenUseMainMonitor ) { + fullscreenMonitors = new ArrayList(); + fullscreenMonitors.add( getMainMonitor() ); } else { - monitors = getScreen().getMonitorDevices(); + fullscreenMonitors = getScreen().getMonitorDevices(); } } - fs_span_flag = monitors.size() > 1 ? FLAG_IS_FULLSCREEN_SPAN : 0 ; - viewport = MonitorDevice.unionOfViewports(new Rectangle(), monitors); + /** + * Bug 770: + * _NET_WM_STATE_FULLSCREEN may result in ConfigureNotify event w/ virtual screen size, instead of monitor-mode size (NV + Fglrx). + * ConfigureNotify reflects the actual size of the window and is being propagated + * to NEWT and the GLEventListener. + * With Mesa/Intel open-source driver, the correct desired monitor mode size is reported + * at least on one test machine here. + * + * Bug 771: Implementation requires not to use _NET_WM_STATE_FULLSCREEN! + */ + // fs_span_flag = monitors.size() > 1 ? FLAG_IS_FULLSCREEN_SPAN : 0 ; + fs_span_flag = FLAG_IS_FULLSCREEN_SPAN; + viewport = MonitorDevice.unionOfViewports(new Rectangle(), fullscreenMonitors); nfs_x = getX(); nfs_y = getY(); nfs_width = getWidth(); @@ -1905,6 +1907,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer w = viewport.getWidth(); h = viewport.getHeight(); } else { + fullscreenUseMainMonitor = true; + fullscreenMonitors = null; fs_span_flag = 0; viewport = null; x = nfs_x; @@ -1926,16 +1930,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } } - monitors = null; // clear references ASAP - useMainMonitor = true; if(DEBUG_IMPLEMENTATION) { System.err.println("Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+ ", virtl-size: "+screen.getWidth()+"x"+screen.getHeight()+", monitorsViewport "+viewport); } - DisplayImpl display = (DisplayImpl) screen.getDisplay(); + final DisplayImpl display = (DisplayImpl) screen.getDisplay(); display.dispatchMessagesNative(); // status up2date - boolean wasVisible = isVisible(); + final boolean wasVisible = isVisible(); // Lock parentWindow only during reparenting (attempt) final NativeWindow parentWindowLocked; @@ -1963,8 +1965,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer WindowImpl.this.waitForVisible(true, false); display.dispatchMessagesNative(); // status up2date WindowImpl.this.waitForSize(w, h, false, TIMEOUT_NATIVEWINDOW); - display.dispatchMessagesNative(); // status up2date - if(DEBUG_IMPLEMENTATION) { System.err.println("Window fs done: " + WindowImpl.this); } @@ -1975,7 +1975,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener } } - private final FullScreenAction fullScreenAction = new FullScreenAction(); + private final FullScreenAction fullScreenAction = new FullScreenAction(); @Override public boolean setFullscreen(boolean fullscreen) { @@ -1989,7 +1989,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private boolean setFullscreenImpl(boolean fullscreen, boolean useMainMonitor, List monitors) { synchronized(fullScreenAction) { - if( fullScreenAction.init(fullscreen, useMainMonitor, monitors) ) { + fullscreenMonitors = monitors; + fullscreenUseMainMonitor = useMainMonitor; + if( fullScreenAction.init(fullscreen) ) { if(fullScreenAction.fsOn() && isOffscreenInstance(WindowImpl.this, parentWindow)) { // enable fullscreen on offscreen instance if(null != parentWindow) { @@ -2008,8 +2010,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer nfs_parent = null; } - if(isVisible()) { - requestFocus(true /* wait */, this.fullscreen /* skipFocusAction */, true /* force */); + if( fullscreen && isVisible() ) { // force focus on fullscreen + requestFocus(true /* wait */, true /* skipFocusAction */, true /* force */); } } return this.fullscreen; @@ -2018,10 +2020,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private class MonitorModeListenerImpl implements MonitorModeListener { boolean animatorPaused = false; + boolean hadFocus = false; public void monitorModeChangeNotify(MonitorEvent me) { + hadFocus = hasFocus(); if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.monitorModeChangeNotify: "+me); + System.err.println("Window.monitorModeChangeNotify: hadFocus "+hadFocus+", "+me); } if(null!=lifecycleHook) { @@ -2031,7 +2035,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public void monitorModeChanged(MonitorEvent me, boolean success) { if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.monitorModeChanged: "+me+", success: "+success); + System.err.println("Window.monitorModeChanged: hadFocus "+hadFocus+", "+me+", success: "+success); } if(success) { @@ -2055,13 +2059,27 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer setSize(viewport.getWidth(), viewport.getHeight()); } } + } else { + // If changed monitor is part of this fullscreen mode, reset size! (Bug 771) + final MonitorDevice md = me.getMonitor(); + if( fullscreenMonitors.contains(md) ) { + final RectangleImmutable viewport = MonitorDevice.unionOfViewports(new Rectangle(), fullscreenMonitors); + if(DEBUG_IMPLEMENTATION) { + final RectangleImmutable rect = new Rectangle(getX(), getY(), getWidth(), getHeight()); + System.err.println("Window.monitorModeChanged: FS Monitor Match: Fit window "+rect+" into new viewport union "+viewport+", provoked by "+md); + } + definePosition(viewport.getX(), viewport.getY()); // set pos for setVisible(..) or createNative(..) - reduce EDT roundtrip + setFullscreenSize(viewport.getWidth(), viewport.getHeight()); + } } } - if(animatorPaused) { lifecycleHook.resumeRenderingAction(); } sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener + if( hadFocus ) { + requestFocus(true); + } } } private final MonitorModeListenerImpl monitorModeListenerImpl = new MonitorModeListenerImpl(); diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java index 786587d65..aec7f310e 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java @@ -133,7 +133,7 @@ public class WindowDriver extends WindowImpl { } } - protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final int flags) { + protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, int flags) { if(DEBUG_IMPLEMENTATION) { System.err.println("X11Window reconfig: "+x+"/"+y+" "+width+"x"+height+", "+ getReconfigureFlagsAsString(null, flags)); } @@ -148,18 +148,52 @@ public class WindowDriver extends WindowImpl { _x = x; _y = y; } + if( 0 != ( FLAG_IS_FULLSCREEN & flags) && 0 == ( FLAG_IS_ALWAYSONTOP & flags) ) { + tempAlwaysOnTop = true; + flags |= FLAG_IS_ALWAYSONTOP; + if(DEBUG_IMPLEMENTATION) { + System.err.println("X11Window reconfig.2: temporary "+getReconfigureFlagsAsString(null, flags)); + } + } else { + tempAlwaysOnTop = false; + } + final int fflags = flags; final DisplayDriver display = (DisplayDriver) getScreen().getDisplay(); runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { public Object run(long dpy) { reconfigureWindow0( dpy, getScreenIndex(), getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(), - _x, _y, width, height, flags); + _x, _y, width, height, fflags); return null; } }); return true; } + volatile boolean tempAlwaysOnTop = false; + /** + *

    + * Deal w/ tempAlwaysOnTop. + *

    + * {@inheritDoc} + */ + protected void focusChanged(boolean defer, boolean focusGained) { + if( tempAlwaysOnTop && hasFocus() != focusGained && isNativeValid() ) { + final int flags = getReconfigureFlags(FLAG_CHANGE_ALWAYSONTOP, isVisible()) | ( focusGained ? FLAG_IS_ALWAYSONTOP : 0 ); + final DisplayDriver display = (DisplayDriver) getScreen().getDisplay(); + runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { + public Object run(long dpy) { + reconfigureWindow0( dpy, getScreenIndex(), + getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(), + getX(), getY(), getWidth(), getHeight(), flags); + return null; + } + }); + } + super.focusChanged(defer, focusGained); + } + + protected void reparentNotify(long newParentWindowHandle) { if(DEBUG_IMPLEMENTATION) { final long p0 = getParentWindowHandle(); diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 3f50f27a4..4a95d0180 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -299,9 +299,8 @@ static void NewtWindows_setNormalWindowEWMH (Display *dpy, Window w) { #define _NET_WM_STATE_REMOVE 0 #define _NET_WM_STATE_ADD 1 - -#define _NET_WM_FULLSCREEN ( 1 << 0 ) -#define _NET_WM_ABOVE ( 1 << 1 ) +#define _NET_WM_STATE_FLAG_FULLSCREEN ( 1 << 0 ) +#define _NET_WM_STATE_FLAG_ABOVE ( 1 << 1 ) /** * Set fullscreen using Extended Window Manager Hints (EWMH) @@ -314,7 +313,9 @@ static void NewtWindows_setNormalWindowEWMH (Display *dpy, Window w) { * and resets it when leaving FS. * The same is assumed for the decoration state. */ -static int NewtWindows_isFullscreenEWMHSupported (Display *dpy, Window w) { +static int NewtWindows_getSupportedStackingEWMHFlags(Display *dpy, Window w) { +#ifdef VERBOSE_ON + // Code doesn't work reliable on KDE4 ... Atom _NET_WM_ALLOWED_ACTIONS = XInternAtom( dpy, "_NET_WM_ALLOWED_ACTIONS", False ); Atom _NET_WM_ACTION_FULLSCREEN = XInternAtom( dpy, "_NET_WM_ACTION_FULLSCREEN", False ); Atom _NET_WM_ACTION_ABOVE = XInternAtom( dpy, "_NET_WM_ACTION_ABOVE", False ); @@ -329,86 +330,75 @@ static int NewtWindows_isFullscreenEWMHSupported (Display *dpy, Window w) { for(i=0; i0) { - XChangeProperty( dpy, w, _NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes); - XSync(dpy, False); - res = True; - } - } else { - if(enable) { - NewtWindows_setCWAbove(dpy, w); - } - XEvent xev; - long mask = SubstructureNotifyMask | SubstructureRedirectMask ; - int i=0; - - memset ( &xev, 0, sizeof(xev) ); - - xev.type = ClientMessage; - xev.xclient.window = w; - xev.xclient.message_type = _NET_WM_STATE; - xev.xclient.format = 32; + // _NET_WM_STATE: fullscreen and/or above + if( changeFullscreen || changeAbove ) { + { + // _NET_WM_STATE as event to root window + XEvent xev; + long mask = SubstructureNotifyMask | SubstructureRedirectMask ; + int i=0; - xev.xclient.data.l[i++] = ( True == enable ) ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE ; - if( 0 != ( ( _NET_WM_FULLSCREEN & ewmhMask ) & ewmhFlags ) ) { - xev.xclient.data.l[i++] = _NET_WM_STATE_FULLSCREEN; - } - if( 0 != ( ( _NET_WM_ABOVE & ewmhMask ) & ewmhFlags ) ) { - xev.xclient.data.l[i++] = _NET_WM_STATE_ABOVE; - } - xev.xclient.data.l[3] = 1; //source indication for normal applications + memset ( &xev, 0, sizeof(xev) ); + + xev.type = ClientMessage; + xev.xclient.window = w; + xev.xclient.message_type = _NET_WM_STATE; + xev.xclient.format = 32; + + xev.xclient.data.l[i++] = enable ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE ; + if( changeFullscreen ) { + xev.xclient.data.l[i++] = _NET_WM_STATE_FULLSCREEN; + } + if( changeAbove ) { + xev.xclient.data.l[i++] = _NET_WM_STATE_ABOVE; + } + xev.xclient.data.l[3] = 1; //source indication for normal applications - if(i>0) { XSendEvent ( dpy, root, False, mask, &xev ); - res = True; } + // If ABOVE is changed, also change _NET_WM_BYPASS_COMPOSITOR! + if( changeAbove ) { + Atom _NET_WM_BYPASS_COMPOSITOR = XInternAtom( dpy, "_NET_WM_BYPASS_COMPOSITOR", False ); + unsigned long value = enable ? 1 : 0; + XChangeProperty( dpy, w, _NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&value, 1); + } + XSync(dpy, False); + res = True; } - XSync(dpy, False); - DBG_PRINT( "X11: reconfigureWindow0 FULLSCREEN EWMH ON %d, ewmhMask 0x%X, ewmhFlags 0x%X, visible %d: %d\n", - enable, ewmhMask, ewmhFlags, isVisible, res); + DBG_PRINT( "X11: setStackingEWMHFlags ON %d, changeFullscreen %d, changeAbove %d, visible %d: %d\n", + enable, changeFullscreen, changeAbove, isVisible, res); return res; } @@ -657,7 +647,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWindow0 NewtWindows_setPosSize(dpy, window, x, y, width, height); if( TST_FLAG_IS_ALWAYSONTOP(flags) ) { - NewtWindows_setFullscreenEWMH(dpy, root, window, _NET_WM_ABOVE, True, True); + NewtWindows_setStackingEWMHFlags(dpy, root, window, _NET_WM_STATE_FLAG_ABOVE, True, True); } } @@ -720,15 +710,6 @@ static Bool WaitForReparentNotify( Display *dpy, XEvent *event, XPointer arg ) { } #endif -/** - * KDE cause lost input focus in fullscreen mode. - * Using 'XGrabKeyboard(..)' would prevent the loss, - * but also would disable WM task switcher etc. - * - * #define FS_GRAB_KEYBOARD 1 - * - */ - /* * Class: jogamp_newt_driver_x11_WindowDriver * Method: reconfigureWindow0 @@ -747,21 +728,22 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo XEvent event; Bool isVisible = !TST_FLAG_CHANGE_VISIBILITY(flags) && TST_FLAG_IS_VISIBLE(flags) ; Bool tempInvisible = ( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_PARENTING(flags) ) && isVisible ; + // Bool tempInvisible = TST_FLAG_CHANGE_PARENTING(flags) && isVisible ; int fsEWMHFlags = 0; if( TST_FLAG_CHANGE_FULLSCREEN(flags) ) { - if( !TST_FLAG_IS_FULLSCREEN_SPAN(flags) ) { // doesn't work w/ spanning across monitors - fsEWMHFlags |= _NET_WM_FULLSCREEN; + if( !TST_FLAG_IS_FULLSCREEN_SPAN(flags) ) { // doesn't work w/ spanning across monitors. See also Bug 770 & Bug 771 + fsEWMHFlags |= _NET_WM_STATE_FLAG_FULLSCREEN; } if( TST_FLAG_IS_FULLSCREEN(flags) ) { if( TST_FLAG_IS_ALWAYSONTOP(flags) ) { - fsEWMHFlags |= _NET_WM_ABOVE; // fs on, above on - } // else { } // fs on, above off + fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; // fs on, above on + } // else { } // fs on, above off } else if( !TST_FLAG_IS_ALWAYSONTOP(flags) ) { - fsEWMHFlags |= _NET_WM_ABOVE; // fs off, above off - } // else { } // fs off, above on + fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; // fs off, above off + } // else { } // fs off, above on } if( TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) { - fsEWMHFlags |= _NET_WM_ABOVE; // toggle above + fsEWMHFlags |= _NET_WM_STATE_FLAG_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 (span %d), alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d, tempInvisible %d, fsEWMHFlags %d\n", @@ -780,21 +762,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo !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( NewtWindows_setStackingEWMHFlags(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)) { - XGrabKeyboard(dpy, w, True, GrabModeAsync, GrabModeAsync, CurrentTime); - } else { - XUngrabKeyboard(dpy, CurrentTime); - } - } else if(TST_FLAG_CHANGE_ALWAYSONTOP(flags) && !TST_FLAG_IS_ALWAYSONTOP(flags)) { - XUngrabKeyboard(dpy, CurrentTime); - } - #endif + DBG_PRINT( "X11: reconfigureWindow0 X (fast)\n"); return; } } @@ -808,10 +780,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) || ( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && !TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // FS off - NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, False); - #ifdef FS_GRAB_KEYBOARD - XUngrabKeyboard(dpy, CurrentTime); - #endif + NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, False); } if( TST_FLAG_CHANGE_PARENTING(flags) && !TST_FLAG_HAS_PARENT(flags) ) { @@ -844,9 +813,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo XMapRaised(dpy, w); XIfEvent( dpy, &event, WaitForMapNotify, (XPointer) w ); // no need to notify the java side .. just temp change - } - - if( TST_FLAG_CHANGE_VISIBILITY(flags) ) { + } else if( TST_FLAG_CHANGE_VISIBILITY(flags) ) { if( TST_FLAG_IS_VISIBLE(flags) ) { DBG_PRINT( "X11: reconfigureWindow0 VISIBLE ON\n"); XMapRaised(dpy, w); @@ -859,15 +826,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags) ) || ( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // FS on - NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, True); - #ifdef FS_GRAB_KEYBOARD - if(TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags)) { - XGrabKeyboard(dpy, w, True, GrabModeAsync, GrabModeAsync, CurrentTime); - } - #endif + NewtWindows_requestFocus (dpy, w, True); + NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, True); } - DBG_PRINT( "X11: reconfigureWindow0 X\n"); + DBG_PRINT( "X11: reconfigureWindow0 X (full)\n"); } /* diff --git a/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode02aNEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode02aNEWT.java index 37ea499df..54c6bdd6c 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode02aNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode02aNEWT.java @@ -55,7 +55,8 @@ import java.util.List; import javax.media.nativewindow.util.Dimension; /** - * Tests MonitorMode change w/ changed rotation. + * Tests MonitorMode change w/ changed rotation, + * w/ and w/o fullscreen, pre and post MonitorMode change. *

    * Also tests MonitorMode reset after last Screen is dereferenced, * i.e. MonitorMode should be reinstated. @@ -75,21 +76,14 @@ public class TestScreenMode02aNEWT extends UITestCase { glp = GLProfile.getDefault(); } - @AfterClass - public static void releaseClass() throws InterruptedException { - Thread.sleep(waitTimeShort); - } - static GLWindow createWindow(Screen screen, GLCapabilities caps, int width, int height, boolean onscreen, boolean undecorated) { Assert.assertNotNull(caps); caps.setOnscreen(onscreen); GLWindow window = GLWindow.create(screen, caps); window.setSize(width, height); - window.addGLEventListener(new GearsES2()); + window.addGLEventListener(new GearsES2(1)); Assert.assertNotNull(window); - window.setVisible(true); - Assert.assertTrue(window.isVisible()); return window; } @@ -100,9 +94,26 @@ public class TestScreenMode02aNEWT extends UITestCase { } @Test - public void testScreenRotationChange01() throws InterruptedException { - Thread.sleep(waitTimeShort); - + public void testScreenRotationChange01_PreWin() throws InterruptedException { + testScreenRotationChangeImpl(true, true, false); + } + + @Test + public void testScreenRotationChange02_PreFull() throws InterruptedException { + testScreenRotationChangeImpl(true, true, true); + } + + @Test + public void testScreenRotationChange11_PostWin() throws InterruptedException { + testScreenRotationChangeImpl(true, false, false); + } + + @Test + public void testScreenRotationChange12_PostFull() throws InterruptedException { + testScreenRotationChangeImpl(true, false, true); + } + + void testScreenRotationChangeImpl(boolean changeMode, boolean preVis, boolean fullscreen) throws InterruptedException { GLCapabilities caps = new GLCapabilities(glp); Assert.assertNotNull(caps); Display display = NewtFactory.createDisplay(null); // local display @@ -111,60 +122,92 @@ public class TestScreenMode02aNEWT extends UITestCase { Assert.assertNotNull(screen); GLWindow window = createWindow(screen, caps, width, height, true /* onscreen */, false /* undecorated */); Assert.assertNotNull(window); - - MonitorDevice monitor = window.getMainMonitor(); - List monitorModes = monitor.getSupportedModes(); - if(monitorModes.size()==1) { - // no support .. - System.err.println("Your platform has no ScreenMode change support, sorry"); - destroyWindow(window); - return; + if( preVis ) { + window.setVisible(true); + if( fullscreen ) { + window.setFullscreen(true); + } + } else { + screen.createNative(); + Assert.assertEquals(true,display.isNativeValid()); + Assert.assertEquals(true,screen.isNativeValid()); } - Assert.assertTrue(monitorModes.size()>0); Animator animator = new Animator(window); animator.start(); - - MonitorMode mmCurrent = monitor.getCurrentMode(); - Assert.assertNotNull(mmCurrent); - MonitorMode mmOrig = monitor.getOriginalMode(); + + final MonitorDevice monitor = window.getMainMonitor(); + final MonitorMode mmOrig = monitor.getOriginalMode(); Assert.assertNotNull(mmOrig); - System.err.println("[0] orig : "+mmOrig); - System.err.println("[0] current: "+mmCurrent); - Assert.assertEquals(mmCurrent, mmOrig); - - monitorModes = MonitorModeUtil.filterByFlags(monitorModes, 0); // no interlace, double-scan etc - Assert.assertNotNull(monitorModes); - Assert.assertTrue(monitorModes.size()>0); - monitorModes = MonitorModeUtil.filterByRotation(monitorModes, 90); - if(null==monitorModes || Platform.getOSType() == Platform.OSType.MACOS ) { - // no rotation support .. - System.err.println("Your platform has no rotation support, sorry"); - destroyWindow(window); - return; + if(changeMode) { + List monitorModes = monitor.getSupportedModes(); + if(monitorModes.size()==1) { + // no support .. + System.err.println("Your platform has no ScreenMode change support, sorry"); + destroyWindow(window); + return; + } + Assert.assertTrue(monitorModes.size()>0); + + final MonitorMode mmCurrent = monitor.getCurrentMode(); + Assert.assertNotNull(mmCurrent); + System.err.println("[0] orig : "+mmOrig); + System.err.println("[0] current: "+mmCurrent); + Assert.assertEquals(mmCurrent, mmOrig); + + monitorModes = MonitorModeUtil.filterByFlags(monitorModes, 0); // no interlace, double-scan etc + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.filterByRotation(monitorModes, 90); + if(null==monitorModes || Platform.getOSType() == Platform.OSType.MACOS ) { + // no rotation support .. + System.err.println("Your platform has no rotation support, sorry"); + destroyWindow(window); + return; + } + monitorModes = MonitorModeUtil.filterByResolution(monitorModes, new Dimension(801, 601)); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.filterByRate(monitorModes, mmOrig.getRefreshRate()); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + monitorModes = MonitorModeUtil.getHighestAvailableBpp(monitorModes); + Assert.assertNotNull(monitorModes); + Assert.assertTrue(monitorModes.size()>0); + + MonitorMode mm = (MonitorMode) monitorModes.get(0); + System.err.println("[0] set current: "+mm); + monitor.setCurrentMode(mm); + Assert.assertTrue(monitor.isModeChangedByUs()); + Assert.assertEquals(mm, monitor.getCurrentMode()); + Assert.assertNotSame(mmOrig, monitor.getCurrentMode()); + Assert.assertEquals(mm, monitor.queryCurrentMode()); } - monitorModes = MonitorModeUtil.filterByResolution(monitorModes, new Dimension(801, 601)); - Assert.assertNotNull(monitorModes); - Assert.assertTrue(monitorModes.size()>0); - monitorModes = MonitorModeUtil.filterByRate(monitorModes, mmOrig.getRefreshRate()); - Assert.assertNotNull(monitorModes); - Assert.assertTrue(monitorModes.size()>0); - monitorModes = MonitorModeUtil.getHighestAvailableBpp(monitorModes); - Assert.assertNotNull(monitorModes); - Assert.assertTrue(monitorModes.size()>0); - - MonitorMode sm = (MonitorMode) monitorModes.get(0); - System.err.println("[0] set current: "+sm); - monitor.setCurrentMode(sm); - Assert.assertTrue(monitor.isModeChangedByUs()); - Assert.assertEquals(sm, monitor.getCurrentMode()); - Assert.assertNotSame(mmOrig, monitor.getCurrentMode()); - Assert.assertEquals(sm, monitor.queryCurrentMode()); - + + if( !preVis ) { + window.setVisible(true); + if( fullscreen ) { + window.setFullscreen(true); + } + } + Thread.sleep(waitTimeLong); - - // check reset .. - + + if( !preVis && fullscreen ) { + window.setFullscreen(false); + } + + if(changeMode) { + monitor.setCurrentMode(mmOrig); + Assert.assertFalse(monitor.isModeChangedByUs()); + Assert.assertEquals(mmOrig, monitor.getCurrentMode()); + Thread.sleep(waitTimeShort); + } + + if( preVis && fullscreen ) { + window.setFullscreen(false); + } + Assert.assertEquals(true,display.isNativeValid()); Assert.assertEquals(true,screen.isNativeValid()); Assert.assertEquals(true,window.isNativeValid()); @@ -178,22 +221,6 @@ public class TestScreenMode02aNEWT extends UITestCase { Assert.assertTrue(AWTRobotUtil.waitForRealized(screen, false)); Assert.assertEquals(false,screen.isNativeValid()); Assert.assertEquals(false,display.isNativeValid()); - - screen.createNative(); // trigger native re-creation - - Assert.assertEquals(true,display.isNativeValid()); - Assert.assertEquals(true,screen.isNativeValid()); - - mmCurrent = monitor.getCurrentMode(); - System.err.println("[1] current/orig: "+mmCurrent); - - Assert.assertNotNull(mmCurrent); - Assert.assertEquals(mmCurrent, mmOrig); - - screen.destroy(); - - Assert.assertEquals(false,screen.isNativeValid()); - Assert.assertEquals(false,display.isNativeValid()); } public static void main(String args[]) throws IOException { -- cgit v1.2.3 From 5b81a51c1f695b0e0750ec47149216e26b8ed14b Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Thu, 4 Jul 2013 15:39:00 +0200 Subject: X11Window FullScreen: Toggle _NET_WM_BYPASS_COMPOSITOR not only for ABOVE .. but also for FULLSCREEN WM state. --- make/scripts/tests.sh | 4 ++-- src/newt/native/X11Window.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/newt/native/X11Window.c') diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 8137f5f0f..640e6a01d 100644 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -406,8 +406,8 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01aNEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01bNEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01cNEWT $* -#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01dNEWT $* -testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02aNEWT $* +testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01dNEWT $* +#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02aNEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02bNEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.mm.ManualScreenMode03aNEWT $* #testnoawt -Djava.awt.headless=true com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT $* diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 4a95d0180..e6e300d2e 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -388,8 +388,8 @@ static Bool NewtWindows_setStackingEWMHFlags (Display *dpy, Window root, Window XSendEvent ( dpy, root, False, mask, &xev ); } - // If ABOVE is changed, also change _NET_WM_BYPASS_COMPOSITOR! - if( changeAbove ) { + // Also change _NET_WM_BYPASS_COMPOSITOR! + { Atom _NET_WM_BYPASS_COMPOSITOR = XInternAtom( dpy, "_NET_WM_BYPASS_COMPOSITOR", False ); unsigned long value = enable ? 1 : 0; XChangeProperty( dpy, w, _NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&value, 1); -- cgit v1.2.3 From 8be1fc983e584082b9960b4da19c56af5834d08e Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 9 Oct 2013 05:24:45 +0200 Subject: NEWT Reparent/Fullscreen: Fixes X11 unsuccessful return to parent window; Add reparentWindow(..) top-level position arguments; Misc - Fixes X11 unsuccessful return to parent window On X11 when returning to parent window (-> CHILD), we have to set the window invisible and wait for the result. Otherwise it sometimes happens that the WM's reparent operation fails, i.e. the window won't become a child of desired parent and is positioned randomly. - Add reparentWindow(..) top-level position arguments .. allows bringing the child-window to top-level w/ a desired position. Otherwise the window would be positioned elsewhere as a top-level as the plain reparenting operation. X11 needs to set position and size _after_ making the window visible, otherwise WM may ignore the XConfigureWindow request. - Reparent recreate shall always store the desired position and size On OSX/CALayer when recreation is being used, we need to store the pos/size for later creation. - Tests: Use 'NewtAWTReparentingKeyAdapter' where possible (reparent/fullscreen) instead of duplicating such code. NewtAWTReparentingKeyAdapter: Performs reparenting and fullscreen operations off-thread (i.e. not on AWT/NEW EDT) while decorating the action w/ revoking/restoring the ExclusiveContextThread (ECT). Manually tested 'TestGearsES2NewtCanvasAWT' reparenting and fullscreen on X11, Windows and OSX/CALayer w/ JDK 7u40 successful. --- make/scripts/tests-x64-dbg.bat | 4 +- make/scripts/tests.sh | 3 +- src/newt/classes/com/jogamp/newt/Window.java | 19 +++- .../classes/com/jogamp/newt/opengl/GLWindow.java | 4 +- src/newt/classes/jogamp/newt/WindowImpl.java | 95 ++++++++++-------- src/newt/native/X11Window.c | 6 +- .../acore/TestOffscreenLayer02NewtCanvasAWT.java | 2 +- .../demos/es2/newt/TestGearsES2NewtCanvasAWT.java | 53 +--------- .../es2/newt/TestLandscapeES2NewtCanvasAWT.java | 53 +--------- .../parenting/NewtAWTReparentingKeyAdapter.java | 111 ++++++++++++++------- .../junit/newt/parenting/TestParenting01NEWT.java | 8 +- .../junit/newt/parenting/TestParenting03AWT.java | 4 +- .../TestParentingFocusTraversal01AWT.java | 2 +- 13 files changed, 170 insertions(+), 194 deletions(-) (limited to 'src/newt/native/X11Window.c') diff --git a/make/scripts/tests-x64-dbg.bat b/make/scripts/tests-x64-dbg.bat index 3447605c7..c1a14c1a2 100755 --- a/make/scripts/tests-x64-dbg.bat +++ b/make/scripts/tests-x64-dbg.bat @@ -48,8 +48,8 @@ REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLC REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLContext" "-Djogl.debug.GLContext.TraceSwitch" "-Djogl.windows.useWGLVersionOf5WGLGDIFuncSet" REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLContext" "-Djogl.debug.GLContext.TraceSwitch" REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.GLJPanel" "-Djogl.debug.TileRenderer" "-Djogl.debug.TileRenderer.PNG" -set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.GLJPanel" "-Djogl.debug.TileRenderer" -REM set D_ARGS="-Dnewt.debug.Window" +REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.GLJPanel" "-Djogl.debug.TileRenderer" +set D_ARGS="-Dnewt.debug.Window" REM set D_ARGS="-Dnewt.debug.Window.KeyEvent" REM set D_ARGS="-Dnewt.debug.Window.MouseEvent" REM set D_ARGS="-Dnewt.debug.Window.MouseEvent" "-Dnewt.debug.Window.KeyEvent" diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 5c693f33c..4bafdf15d 100644 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -144,7 +144,6 @@ function jrun() { #D_ARGS="-Djogl.debug.GLDrawable" #D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.Window" #D_ARGS="-Dnewt.debug.Screen" - D_ARGS="-Dnewt.debug.Window" #D_ARGS="-Dnewt.test.Screen.disableRandR13" #D_ARGS="-Dnewt.test.Screen.disableScreenMode -Dnewt.debug.Screen" #D_ARGS="-Dnewt.debug.Screen -Djogl.debug.Animator" @@ -194,6 +193,8 @@ function jrun() { #D_ARGS="-Dnewt.debug.Window -Dnativewindow.debug.JAWT -Djogl.debug.Animator" #D_ARGS="-Dnewt.debug.Window -Djogl.debug.GLDrawable" #D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Window.KeyEvent" + #D_ARGS="-Dnewt.debug.Window -Dnewt.debug.Window.MouseEvent -Dnewt.debug.Window.KeyEvent" + D_ARGS="-Dnewt.debug.Window" #D_ARGS="-Xprof" #D_ARGS="-Dnativewindow.debug=all" #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.Java2D -Djogl.debug.GLJPanel" diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index f63c03738..8a43ef153 100644 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -351,10 +351,27 @@ public interface Window extends NativeWindow, WindowClosingProtocol { * @param newParent The new parent NativeWindow. If null, this Window becomes a top level window. * * @return The issued reparent action type (strategy) as defined in Window.ReparentAction + * @see #reparentWindow(NativeWindow, int, int, boolean) */ ReparentOperation reparentWindow(NativeWindow newParent); - ReparentOperation reparentWindow(NativeWindow newParent, boolean forceDestroyCreate); + /** + * Change this window's parent window.
    + *

    + * In case the old parent is not null and a Window, + * this window is removed from it's list of children.
    + * In case the new parent is not null and a Window, + * this window is added to it's list of children.

    + * + * @param newParent The new parent NativeWindow. If null, this Window becomes a top level window. + * @param x new top-level position, use -1 for default position. + * @param y new top-level position, use -1 for default position. + * @param forceDestroyCreate if true, uses re-creation strategy for reparenting, default is false. + * + * @return The issued reparent action type (strategy) as defined in Window.ReparentAction + * @see #reparentWindow(NativeWindow) + */ + ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, boolean forceDestroyCreate); /** * Enable or disable fullscreen mode for this window. diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 45ab2a44c..eace0f2af 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -390,8 +390,8 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind } @Override - public final ReparentOperation reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) { - return window.reparentWindow(newParent, forceDestroyCreate); + public final ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, boolean forceDestroyCreate) { + return window.reparentWindow(newParent, x, y, forceDestroyCreate); } @Override diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index a2338b93d..300ca5c3f 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -414,7 +414,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } if(postParentlockFocus) { // harmonize focus behavior for all platforms: focus on creation - requestFocusInt(isFullscreen() /* skipFocusAction */); + requestFocusInt(isFullscreen() /* skipFocusAction if fullscreen */); ((DisplayImpl) screen.getDisplay()).dispatchMessagesNative(); // status up2date } if(DEBUG_IMPLEMENTATION) { @@ -1033,7 +1033,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer removeScreenReference(); Display dpy = screen.getDisplay(); if(null != dpy) { - dpy.validateEDT(); + dpy.validateEDTStopped(); } // send synced destroyed notification @@ -1112,12 +1112,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } private class ReparentAction implements Runnable { - NativeWindow newParentWindow; + final NativeWindow newParentWindow; + final int topLevelX, topLevelY; boolean forceDestroyCreate; ReparentOperation operation; - private ReparentAction(NativeWindow newParentWindow, boolean forceDestroyCreate) { + private ReparentAction(NativeWindow newParentWindow, int topLevelX, int topLevelY, boolean forceDestroyCreate) { this.newParentWindow = newParentWindow; + this.topLevelX = topLevelX; + this.topLevelY = topLevelY; this.forceDestroyCreate = forceDestroyCreate | DEBUG_TEST_REPARENT_INCOMPATIBLE; this.operation = ReparentOperation.ACTION_INVALID; // ensure it's set } @@ -1144,10 +1147,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private void reparent() { // mirror pos/size so native change notification can get overwritten - int x = getX(); - int y = getY(); - int width = getWidth(); - int height = getHeight(); + final int oldX = getX(); + final int oldY = getY(); + final int oldWidth = getWidth(); + final int oldHeight = getHeight(); + final int x, y; + int width = oldWidth; + int height = oldHeight; boolean wasVisible; final RecursiveLock _lock = windowLock; @@ -1168,10 +1174,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer long newParentWindowHandle = 0 ; if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.reparent: START ("+getThreadName()+") valid "+isNativeValid()+", windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+", visible "+wasVisible+", old parentWindow: "+Display.hashCodeNullSafe(parentWindow)+", new parentWindow: "+Display.hashCodeNullSafe(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate+", "+x+"/"+y+" "+width+"x"+height); + System.err.println("Window.reparent: START ("+getThreadName()+") valid "+isNativeValid()+", windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+", visible "+wasVisible+", old parentWindow: "+Display.hashCodeNullSafe(parentWindow)+", new parentWindow: "+Display.hashCodeNullSafe(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate); } if(null!=newParentWindow) { + // REPARENT TO CHILD WINDOW + // reset position to 0/0 within parent space x = 0; y = 0; @@ -1233,12 +1241,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer operation = ReparentOperation.ACTION_NOP; } } else { - if( null != parentWindow ) { + // REPARENT TO TOP-LEVEL WINDOW + if( 0 <= topLevelX && 0 <= topLevelY ) { + x = topLevelX; + y = topLevelY; + } else if( null != parentWindow ) { // child -> top // put client to current parent+child position final Point p = getLocationOnScreen(null); x = p.getX(); y = p.getY(); + } else { + x = oldX; + y = oldY; } // Case: Top Window @@ -1264,18 +1279,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if ( ReparentOperation.ACTION_INVALID == operation ) { throw new NativeWindowException("Internal Error: reparentAction not set"); } - + + if(DEBUG_IMPLEMENTATION) { + System.err.println("Window.reparent: ACTION ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" new parentWindowHandle "+toHexString(newParentWindowHandle)+", reparentAction "+operation+", pos/size "+x+"/"+y+" "+width+"x"+height+", visible "+wasVisible); + } + if( ReparentOperation.ACTION_NOP == operation ) { - if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.reparent: NO CHANGE ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" new parentWindowHandle "+toHexString(newParentWindowHandle)+", visible "+wasVisible); - } return; } - if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.reparent: ACTION ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" new parentWindowHandle "+toHexString(newParentWindowHandle)+", reparentAction "+operation+", visible "+wasVisible); - } - // rearrange window tree if(null!=parentWindow && parentWindow instanceof Window) { ((Window)parentWindow).removeChild(WindowImpl.this); @@ -1285,19 +1297,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer ((Window)parentWindow).addChild(WindowImpl.this); } - if( ReparentOperation.ACTION_NATIVE_CREATION_PENDING == operation ) { - // make size and position persistent for proper recreation - definePosition(x, y); - defineSize(width, height); - return; - } - if( ReparentOperation.ACTION_NATIVE_REPARENTING == operation ) { final DisplayImpl display = (DisplayImpl) screen.getDisplay(); display.dispatchMessagesNative(); // status up2date - if(wasVisible) { - setVisibleImpl(false, x, y, width, height); + // TOP -> CLIENT: !visible first (fixes X11 unsuccessful return to parent window) + if( null != parentWindow && wasVisible && NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true) ) { + setVisibleImpl(false, oldX, oldY, oldWidth, oldHeight); WindowImpl.this.waitForVisible(false, false); // FIXME: Some composite WM behave slacky .. give 'em chance to change state -> invisible, // even though we do exactly that (KDE+Composite) @@ -1337,7 +1343,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer ok = WindowImpl.this.waitForSize(width, height, false, TIMEOUT_NATIVEWINDOW); } if(ok) { - requestFocusInt(false /* skipFocusAction */); + requestFocusInt( 0 == parentWindowHandle /* skipFocusAction if top-level */); display.dispatchMessagesNative(); // status up2date } } @@ -1358,6 +1364,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer destroy( wasVisible ); operation = ReparentOperation.ACTION_NATIVE_CREATION ; } + } else { + // Case + // ACTION_NATIVE_CREATION + // ACTION_NATIVE_CREATION_PENDING; + + // make size and position persistent for proper [re]creation + definePosition(x, y); + defineSize(width, height); } if(DEBUG_IMPLEMENTATION) { @@ -1398,7 +1412,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if(DEBUG_IMPLEMENTATION) { System.err.println("Window.reparentWindow: ReparentActionRecreate ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+Display.hashCodeNullSafe(parentWindow)); } - setVisible(true); // native creation + setVisibleActionImpl(true); // native creation + requestFocusInt( 0 == parentWindowHandle /* skipFocusAction if top-level */); } finally { _lock.unlock(); } @@ -1408,11 +1423,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer @Override public final ReparentOperation reparentWindow(NativeWindow newParent) { - return reparentWindow(newParent, false); + return reparentWindow(newParent, -1, -1, false); } - public ReparentOperation reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) { - final ReparentAction reparentAction = new ReparentAction(newParent, forceDestroyCreate); + @Override + public ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, boolean forceDestroyCreate) { + final ReparentAction reparentAction = new ReparentAction(newParent, x, y, forceDestroyCreate); runOnEDTIfAvail(true, reparentAction); return reparentAction.getOp(); } @@ -1800,7 +1816,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private void requestFocusInt(boolean skipFocusAction) { if( skipFocusAction || !focusAction() ) { if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.RequestFocusInt: forcing - ("+getThreadName()+"): "+hasFocus+" -> true - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)); + System.err.println("Window.RequestFocusInt: forcing - ("+getThreadName()+"): skipFocusAction "+skipFocusAction+", focus "+hasFocus+" -> true - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)); } requestFocusImpl(true); } @@ -1971,7 +1987,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer // Lock parentWindow only during reparenting (attempt) final NativeWindow parentWindowLocked; if( null != parentWindow ) { - if(wasVisible && !fullscreen) { // fullscreen-off -> !visible first (fixes unsuccessful return to parent window) + // fullscreen off: !visible first (fixes X11 unsuccessful return to parent window) + if( !fullscreen && wasVisible && NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true) ) { setVisibleImpl(false, oldX, oldY, oldWidth, oldHeight); WindowImpl.this.waitForVisible(false, false); // FIXME: Some composite WM behave slacky .. give 'em chance to change state -> invisible, @@ -2004,7 +2021,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer ok = WindowImpl.this.waitForSize(w, h, false, TIMEOUT_NATIVEWINDOW); } if(ok) { - requestFocusInt(fullscreen /* skipFocusAction */); + requestFocusInt(fullscreen /* skipFocusAction if fullscreen */); display.dispatchMessagesNative(); // status up2date } if(DEBUG_IMPLEMENTATION) { @@ -2038,7 +2055,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer // enable fullscreen on offscreen instance if(null != parentWindow) { nfs_parent = parentWindow; - reparentWindow(null, true /* forceDestroyCreate */); + reparentWindow(null, -1, -1, true /* forceDestroyCreate */); } else { throw new InternalError("Offscreen instance w/o parent unhandled"); } @@ -2048,13 +2065,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if(!fullScreenAction.fsOn() && null != nfs_parent) { // disable fullscreen on offscreen instance - reparentWindow(nfs_parent, true /* forceDestroyCreate */); + reparentWindow(nfs_parent, -1, -1, true /* forceDestroyCreate */); nfs_parent = null; } - - if( isVisible() ) { // force focus - requestFocus(true /* wait */, true /* skipFocusAction */, true /* force */); - } } return this.fullscreen; } diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index e6e300d2e..f195c5616 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -817,11 +817,15 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo if( TST_FLAG_IS_VISIBLE(flags) ) { DBG_PRINT( "X11: reconfigureWindow0 VISIBLE ON\n"); XMapRaised(dpy, w); + XSync(dpy, False); + // WM may disregard pos/size XConfigureWindow requests for invisible windows! + DBG_PRINT( "X11: reconfigureWindow0 setPosSize.2 %d/%d %dx%d\n", x, y, width, height); + NewtWindows_setPosSize(dpy, w, x, y, width, height); } else { DBG_PRINT( "X11: reconfigureWindow0 VISIBLE OFF\n"); XUnmapWindow(dpy, w); + XSync(dpy, False); } - XSync(dpy, False); } if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags) ) || diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java index cea104e2f..5335d858e 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java @@ -162,7 +162,7 @@ public class TestOffscreenLayer02NewtCanvasAWT extends UITestCase { } setDemoFields(demo1, glWindow1, false); glWindow1.addGLEventListener(demo1); - glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1)); + glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1, null)); frame1.setSize(frameSize0); setupFrameAndShow(frame1, newtCanvasAWT1); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java index 3fc1eb61d..5d091bb6d 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java @@ -42,8 +42,6 @@ import com.jogamp.newt.Display; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Screen; import com.jogamp.newt.awt.NewtCanvasAWT; -import com.jogamp.newt.event.KeyAdapter; -import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.event.WindowAdapter; import com.jogamp.newt.opengl.GLWindow; @@ -51,17 +49,14 @@ import com.jogamp.opengl.test.junit.util.AWTRobotUtil; import com.jogamp.opengl.test.junit.util.MiscUtils; import com.jogamp.opengl.test.junit.util.UITestCase; import com.jogamp.opengl.test.junit.util.QuitAdapter; - import com.jogamp.opengl.util.Animator; - import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; +import com.jogamp.opengl.test.junit.newt.parenting.NewtAWTReparentingKeyAdapter; import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.InsetsImmutable; import javax.media.nativewindow.util.Point; import javax.media.nativewindow.util.PointImmutable; import javax.media.nativewindow.util.DimensionImmutable; - import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLProfile; @@ -271,50 +266,8 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { } }); - glWindow.addKeyListener(new KeyAdapter() { - public void keyReleased(KeyEvent e) { - if( !e.isPrintableKey() || e.isAutoRepeat() ) { - return; - } - if(e.getKeyChar()=='f') { - quitAdapter.enable(false); - new Thread() { - public void run() { - final Thread t = glWindow.setExclusiveContextThread(null); - System.err.println("[set fullscreen pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); - glWindow.setFullscreen(!glWindow.isFullscreen()); - System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); - glWindow.setExclusiveContextThread(t); - quitAdapter.clear(); - quitAdapter.enable(true); - } }.start(); - } else if(e.getKeyChar()=='r') { - quitAdapter.enable(false); - if(glWindow.getParent()==null) { - System.err.println("XXX glWin to home"); - glWindow.reparentWindow(newtCanvasAWT.getNativeWindow()); - } else { - final InsetsImmutable nInsets = glWindow.getInsets(); - java.awt.Insets aInsets = frame.getInsets(); - System.err.println("XXX glWin to TOP - insets " + nInsets + ", " + aInsets); - glWindow.reparentWindow(null); - int dx, dy; - if(nInsets.getTotalHeight()==0) { - dx = aInsets.left; - dy = aInsets.top; - } else { - dx = nInsets.getLeftWidth(); - dy = nInsets.getTopHeight(); - } - glWindow.setPosition(frame.getX()+frame.getWidth()+dx, frame.getY()+dy); - } - glWindow.requestFocus(); - quitAdapter.clear(); - quitAdapter.enable(true); - } - } - }); - + glWindow.addKeyListener(new NewtAWTReparentingKeyAdapter(frame, newtCanvasAWT, glWindow, quitAdapter)); + if( useAnimator ) { animator.add(glWindow); animator.start(); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java index 37172822b..adc2b23ae 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestLandscapeES2NewtCanvasAWT.java @@ -36,23 +36,18 @@ import com.jogamp.newt.Display; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Screen; import com.jogamp.newt.awt.NewtCanvasAWT; -import com.jogamp.newt.event.KeyAdapter; -import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.event.WindowAdapter; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.test.junit.util.MiscUtils; import com.jogamp.opengl.test.junit.util.UITestCase; import com.jogamp.opengl.test.junit.util.QuitAdapter; - import com.jogamp.opengl.util.Animator; - import com.jogamp.opengl.test.junit.jogl.demos.es2.LandscapeES2; +import com.jogamp.opengl.test.junit.newt.parenting.NewtAWTReparentingKeyAdapter; import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.InsetsImmutable; import javax.media.nativewindow.util.DimensionImmutable; - import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLProfile; @@ -119,50 +114,8 @@ public class TestLandscapeES2NewtCanvasAWT extends UITestCase { } }); - glWindow.addKeyListener(new KeyAdapter() { - public void keyReleased(KeyEvent e) { - if( !e.isPrintableKey() || e.isAutoRepeat() ) { - return; - } - if(e.getKeyChar()=='f') { - quitAdapter.enable(false); - new Thread() { - public void run() { - final Thread t = glWindow.setExclusiveContextThread(null); - System.err.println("[set fullscreen pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); - glWindow.setFullscreen(!glWindow.isFullscreen()); - System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); - glWindow.setExclusiveContextThread(t); - quitAdapter.clear(); - quitAdapter.enable(true); - } }.start(); - } else if(e.getKeyChar()=='r') { - quitAdapter.enable(false); - if(glWindow.getParent()==null) { - System.err.println("XXX glWin to home"); - glWindow.reparentWindow(newtCanvasAWT.getNativeWindow()); - } else { - final InsetsImmutable nInsets = glWindow.getInsets(); - java.awt.Insets aInsets = frame.getInsets(); - System.err.println("XXX glWin to TOP - insets " + nInsets + ", " + aInsets); - glWindow.reparentWindow(null); - int dx, dy; - if(nInsets.getTotalHeight()==0) { - dx = aInsets.left; - dy = aInsets.top; - } else { - dx = nInsets.getLeftWidth(); - dy = nInsets.getTopHeight(); - } - glWindow.setPosition(frame.getX()+frame.getWidth()+dx, frame.getY()+dy); - } - glWindow.requestFocus(); - quitAdapter.clear(); - quitAdapter.enable(true); - } - } - }); - + glWindow.addKeyListener(new NewtAWTReparentingKeyAdapter(frame, newtCanvasAWT, glWindow, quitAdapter)); + if( useAnimator ) { animator.add(glWindow); animator.start(); diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java index 9d08d8ff4..4bf1f95c3 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java @@ -35,33 +35,58 @@ import com.jogamp.newt.awt.NewtCanvasAWT; import com.jogamp.newt.event.KeyAdapter; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.test.junit.util.QuitAdapter; public class NewtAWTReparentingKeyAdapter extends KeyAdapter { - Frame frame; - NewtCanvasAWT newtCanvasAWT; - GLWindow glWindow; + final Frame frame; + final NewtCanvasAWT newtCanvasAWT; + final GLWindow glWindow; + final QuitAdapter quitAdapter; - public NewtAWTReparentingKeyAdapter(Frame frame, NewtCanvasAWT newtCanvasAWT, GLWindow glWindow) { + public NewtAWTReparentingKeyAdapter(Frame frame, NewtCanvasAWT newtCanvasAWT, GLWindow glWindow, QuitAdapter quitAdapter) { this.frame = frame; this.newtCanvasAWT = newtCanvasAWT; this.glWindow = glWindow; + this.quitAdapter = quitAdapter; } public void keyReleased(KeyEvent e) { if( !e.isPrintableKey() || e.isAutoRepeat() ) { return; } - if(e.getKeyChar()=='i') { + if( e.getKeySymbol() == KeyEvent.VK_I ) { System.err.println(glWindow); - } else if(e.getKeyChar()=='d') { - glWindow.setUndecorated(!glWindow.isUndecorated()); - } else if(e.getKeyChar()=='f') { - glWindow.setFullscreen(!glWindow.isFullscreen()); - } else if(e.getKeyChar()=='l') { + } else if( e.getKeySymbol() == KeyEvent.VK_L ) { javax.media.nativewindow.util.Point p0 = newtCanvasAWT.getNativeWindow().getLocationOnScreen(null); javax.media.nativewindow.util.Point p1 = glWindow.getLocationOnScreen(null); System.err.println("NewtCanvasAWT position: "+p0+", "+p1); - } else if(e.getKeyChar()=='p') { + } else if( e.getKeySymbol() == KeyEvent.VK_D ) { + glWindow.setUndecorated(!glWindow.isUndecorated()); + } else if( e.getKeySymbol() == KeyEvent.VK_S ) { + if(glWindow.getParent()==null) { + System.err.println("XXX glWin to 100/100"); + glWindow.setPosition(100, 100); + } else { + System.err.println("XXX glWin to 0/0"); + glWindow.setPosition(0, 0); + } + } else if( e.getKeySymbol() == KeyEvent.VK_F ) { + if( null != quitAdapter ) { + quitAdapter.enable(false); + } + new Thread() { + public void run() { + final Thread t = glWindow.setExclusiveContextThread(null); + System.err.println("[set fullscreen pre]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); + glWindow.setFullscreen(!glWindow.isFullscreen()); + System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); + glWindow.setExclusiveContextThread(t); + if( null != quitAdapter ) { + quitAdapter.clear(); + quitAdapter.enable(true); + } + } }.start(); + } else if( e.getKeySymbol() == KeyEvent.VK_P ) { new Thread() { public void run() { if(glWindow.getAnimator().isPaused()) { @@ -71,34 +96,44 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter { } } }.run(); - } else if(e.getKeyChar()=='r') { - if(glWindow.getParent()==null) { - System.err.println("XXX glWin to home"); - glWindow.reparentWindow(newtCanvasAWT.getNativeWindow()); - } else { - final InsetsImmutable nInsets = glWindow.getInsets(); - java.awt.Insets aInsets = frame.getInsets(); - System.err.println("XXX glWin to TOP - insets " + nInsets + ", " + aInsets); - glWindow.reparentWindow(null); - int dx, dy; - if(nInsets.getTotalHeight()==0) { - dx = aInsets.left; - dy = aInsets.top; - } else { - dx = nInsets.getLeftWidth(); - dy = nInsets.getTopHeight(); - } - glWindow.setPosition(frame.getX()+frame.getWidth()+dx, frame.getY()+dy); - } - glWindow.requestFocus(); - } else if(e.getKeyChar()=='s') { - if(glWindow.getParent()==null) { - System.err.println("XXX glWin to 100/100"); - glWindow.setPosition(100, 100); - } else { - System.err.println("XXX glWin to 0/0"); - glWindow.setPosition(0, 0); + } else if( e.getKeySymbol() == KeyEvent.VK_R ) { + if( null != quitAdapter ) { + quitAdapter.enable(false); } + new Thread() { + public void run() { + final Thread t = glWindow.setExclusiveContextThread(null); + if(glWindow.getParent()==null) { + System.err.println("XXX glWin to HOME"); + glWindow.reparentWindow(newtCanvasAWT.getNativeWindow()); + } else { + if( null != frame ) { + final InsetsImmutable nInsets = glWindow.getInsets(); + final java.awt.Insets aInsets = frame.getInsets(); + int dx, dy; + if( nInsets.getTotalHeight()==0 ) { + dx = aInsets.left; + dy = aInsets.top; + } else { + dx = nInsets.getLeftWidth(); + dy = nInsets.getTopHeight(); + } + final int topLevelX = frame.getX()+frame.getWidth()+dx; + final int topLevelY = frame.getY()+dy; + System.err.println("XXX glWin to TOP.1 "+topLevelX+"/"+topLevelY+" - insets " + nInsets + ", " + aInsets); + glWindow.reparentWindow(null, topLevelX, topLevelY, false); + } else { + System.err.println("XXX glWin to TOP.0"); + glWindow.reparentWindow(null); + } + } + glWindow.requestFocus(); + glWindow.setExclusiveContextThread(t); + if( null != quitAdapter ) { + quitAdapter.clear(); + quitAdapter.enable(true); + } + } }.start(); } } } \ No newline at end of file diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java index 41a6b77fa..1f19241d8 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java @@ -379,7 +379,7 @@ public class TestParenting01NEWT extends UITestCase { // glWindow2 -- child --> glWindow1: compatible Assert.assertEquals(true, glWindow2.isVisible()); System.err.println("Frames(1) "+glWindow2.getTotalFPSFrames()); - reparentAction = glWindow2.reparentWindow(glWindow1, reparentRecreate); + reparentAction = glWindow2.reparentWindow(glWindow1, -1, -1, reparentRecreate); System.err.println("Frames(2) "+glWindow2.getTotalFPSFrames()); Assert.assertTrue(Window.ReparentOperation.ACTION_INVALID != reparentAction); Assert.assertEquals(true, glWindow2.isVisible()); @@ -405,7 +405,7 @@ public class TestParenting01NEWT extends UITestCase { // glWindow2 --> top Assert.assertEquals(true, glWindow2.isVisible()); - reparentAction = glWindow2.reparentWindow(null, reparentRecreate); + reparentAction = glWindow2.reparentWindow(null, -1, -1, reparentRecreate); Assert.assertTrue(Window.ReparentOperation.ACTION_INVALID != reparentAction); Assert.assertEquals(true, glWindow2.isVisible()); Assert.assertEquals(true, glWindow2.isNativeValid()); @@ -567,7 +567,7 @@ public class TestParenting01NEWT extends UITestCase { switch(state) { case 0: Assert.assertEquals(true, glWindow2.isVisible()); - reparentAction = glWindow2.reparentWindow(null, reparentRecreate); + reparentAction = glWindow2.reparentWindow(null, -1, -1, reparentRecreate); Assert.assertTrue(Window.ReparentOperation.ACTION_INVALID != reparentAction); Assert.assertEquals(true, glWindow2.isVisible()); Assert.assertEquals(true, glWindow2.isNativeValid()); @@ -582,7 +582,7 @@ public class TestParenting01NEWT extends UITestCase { break; case 1: Assert.assertEquals(true, glWindow2.isVisible()); - reparentAction = glWindow2.reparentWindow(glWindow1, reparentRecreate); + reparentAction = glWindow2.reparentWindow(glWindow1, -1, -1, reparentRecreate); Assert.assertTrue(Window.ReparentOperation.ACTION_INVALID != reparentAction); Assert.assertEquals(true, glWindow2.isVisible()); Assert.assertEquals(true, glWindow2.isNativeValid()); diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java index 60c2b702c..30ee0f129 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java @@ -88,7 +88,7 @@ public class TestParenting03AWT extends UITestCase { GLEventListener demo1 = new GearsES2(1); setDemoFields(demo1, glWindow1, false); glWindow1.addGLEventListener(demo1); - glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1)); + glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1, null)); GLAnimatorControl animator1 = new Animator(glWindow1); animator1.start(); @@ -104,7 +104,7 @@ public class TestParenting03AWT extends UITestCase { GLEventListener demo2 = new GearsES2(1); setDemoFields(demo2, glWindow2, false); glWindow2.addGLEventListener(demo2); - glWindow2.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT2, glWindow2)); + glWindow2.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT2, glWindow2, null)); animator2 = new Animator(glWindow2); animator2.start(); } diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java index 58dafba15..693dd1448 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java @@ -147,7 +147,7 @@ public class TestParentingFocusTraversal01AWT extends UITestCase { GLEventListener demo1 = new GearsES2(1); setDemoFields(demo1, glWindow1, false); glWindow1.addGLEventListener(demo1); - glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1)); + glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1, null)); glWindow1.addKeyListener(new KeyAdapter() { public void keyReleased(KeyEvent e) { if( !e.isPrintableKey() || e.isAutoRepeat() ) { -- cgit v1.2.3 From 008366fd591c9fce31e7185528b606a8205a38f8 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Thu, 19 Dec 2013 12:42:44 +0100 Subject: NEWT X11Window.c: Cleanup Code - No changes. --- src/newt/native/X11Window.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) (limited to 'src/newt/native/X11Window.c') diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index f195c5616..b1fdc71ca 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -389,6 +389,9 @@ static Bool NewtWindows_setStackingEWMHFlags (Display *dpy, Window root, Window XSendEvent ( dpy, root, False, mask, &xev ); } // Also change _NET_WM_BYPASS_COMPOSITOR! + // A value of 0 indicates no preference. + // A value of 1 hints the compositor to disabling compositing of this window. + // A value of 2 hints the compositor to not disabling compositing of this window { Atom _NET_WM_BYPASS_COMPOSITOR = XInternAtom( dpy, "_NET_WM_BYPASS_COMPOSITOR", False ); unsigned long value = enable ? 1 : 0; @@ -704,9 +707,19 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0 DBG_PRINT( "X11: CloseWindow END\n"); } -#if 0 +// #define REPARENT_WAIT_FOR_REPARENT_NOTIFY 1 + +#ifdef REPARENT_WAIT_FOR_REPARENT_NOTIFY static Bool WaitForReparentNotify( Display *dpy, XEvent *event, XPointer arg ) { - return (event->type == ReparentNotify) && (event->xreparent.window == (Window) arg); + Bool res = (event->type == ReparentNotify) && (event->xreparent.window == (Window) arg); + #ifdef VERBOSE_ON + if( event->type == ReparentNotify ) { + DBG_PRINT( "X11.WaitForReparentNotify: Event ReparentNotify: Result %d, exp %p, has %p\n", (int)res, arg, event->xreparent.window); + } else { + DBG_PRINT( "X11.WaitForReparentNotify: Event 0x%X: Result %d, exp %p, has %p\n", (int)event->type, (int)res, arg, event->xreparent.window); + } + #endif + return res; } #endif @@ -778,8 +791,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo // no need to notify the java side .. just temp change } - if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) || - ( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && !TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // FS off + if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) || // FS off + ( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && !TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // AlwaysOnTop off NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, False); } @@ -787,7 +800,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo // TOP: in -> out DBG_PRINT( "X11: reconfigureWindow0 PARENTING in->out\n"); XReparentWindow( dpy, w, parent, x, y ); // actual reparent call - // XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) w ); + #ifdef REPARENT_WAIT_FOR_REPARENT_NOTIFY + XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) w ); + #endif XSync(dpy, False); XSetWMProtocols(dpy, w, &wm_delete_atom, 1); // windowDeleteAtom } @@ -804,7 +819,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo // CHILD: out -> in DBG_PRINT( "X11: reconfigureWindow0 PARENTING out->in\n"); XReparentWindow( dpy, w, parent, x, y ); // actual reparent call - // XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) w ); + #ifdef REPARENT_WAIT_FOR_REPARENT_NOTIFY + XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) w ); + #endif XSync(dpy, False); } @@ -828,8 +845,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo } } - if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags) ) || - ( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // FS on + if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags) ) || // FS on + ( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // AlwaysOnTop on NewtWindows_requestFocus (dpy, w, True); NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, True); } -- cgit v1.2.3 From c9fcc8cd510abc0cbebb872dc3e457327655e778 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Thu, 19 Dec 2013 12:46:40 +0100 Subject: Bug 924: Fix 'Unity WM' issue w/ sticky _NET_WM_STATE after Fullscreen On/Off Cycle Unity WM keeps the _NET_WM_STATE (_NET_WM_STATE_FULLSCREEN, ..) after fullscreen-exit even though _NET_WM_STATE_REMOVE was issued. Add remedy: Reparent Child -> TOP: Reset _NET_WM_STATE (! _NET_WM_STATE_FULLSCREEN, ..). --- src/newt/native/X11Window.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src/newt/native/X11Window.c') diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index b1fdc71ca..27e7936f5 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -754,8 +754,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo } else if( !TST_FLAG_IS_ALWAYSONTOP(flags) ) { fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; // fs off, above off } // else { } // fs off, above on - } - if( TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) { + } else if( TST_FLAG_CHANGE_PARENTING(flags) ) { + // Fix for Unity WM, i.e. _remove_ persistent previous set states + fsEWMHFlags |= _NET_WM_STATE_FLAG_FULLSCREEN; + if( !TST_FLAG_IS_ALWAYSONTOP(flags) ) { + fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; + } + } else if( TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) { fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; // toggle above } @@ -769,8 +774,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags), tempInvisible, fsEWMHFlags); // FS Note: To toggle FS, utilizing the _NET_WM_STATE_FULLSCREEN WM state shall be enough. - // However, we have to consider other cases like reparenting and WM which don't support it. - + // However, we have to consider other cases like reparenting and WM which don't support it, i.e. Unity WM is sluggy. + #if 0 // Doesn't work properly w/ Unity WM if( fsEWMHFlags && !TST_FLAG_CHANGE_PARENTING(flags) && isVisible && !TST_FLAG_IS_FULLSCREEN_SPAN(flags) && ( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) ) { @@ -783,6 +788,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo return; } } + #endif if( tempInvisible ) { DBG_PRINT( "X11: reconfigureWindow0 TEMP VISIBLE OFF\n"); @@ -805,6 +811,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo #endif XSync(dpy, False); XSetWMProtocols(dpy, w, &wm_delete_atom, 1); // windowDeleteAtom + // Fix for Unity WM, i.e. _remove_ persistent previous set states + NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, False); } if( TST_FLAG_CHANGE_DECORATION(flags) ) { -- cgit v1.2.3 From c8726ef04b94ad8e66e1191a06ff793b908d130c Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Thu, 19 Dec 2013 19:18:19 +0100 Subject: Bug 924: Fix X11 Fullscreen ALT-TAB Regression ; Make ALWAYS_ON_TOP Persistent when Reparenting (child -> top) - X11 Fullscreen ALT-TAB regression (no task-switcher visible) We still need the fast reconfigure path for ALWAYSONTOP only toggle. It was removed w/ commit c9fcc8cd510abc0cbebb872dc3e457327655e778, which disabled toggling FULLSCREEN and ALWAYSONTOP. Note: Another bug in Unity WM's Compiz: 'Unredirect Fullscreen Windows := True' disables the ALT-TAB taskbar/launcher HUD rendering and subsequent task-switch. Hence it shall be disabled .. nothing we can do here. - ALWAYS_ON_TOP not persistent when child -> top WM removes ALWAYS_ON_TOP state when reparenting, hence reinforce it when Child -> Top. --- src/newt/native/X11Window.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/newt/native/X11Window.c') diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 27e7936f5..735520b86 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -771,7 +771,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo TST_FLAG_CHANGE_DECORATION(flags), TST_FLAG_IS_UNDECORATED(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); + TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags), + tempInvisible, fsEWMHFlags); // FS Note: To toggle FS, utilizing the _NET_WM_STATE_FULLSCREEN WM state shall be enough. // However, we have to consider other cases like reparenting and WM which don't support it, i.e. Unity WM is sluggy. @@ -789,6 +790,14 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo } } #endif + // Toggle ALWAYSONTOP (only) w/o visibility or window stacking sideffects + if( isVisible && fsEWMHFlags && TST_FLAG_CHANGE_ALWAYSONTOP(flags) && + !TST_FLAG_CHANGE_PARENTING(flags) && !TST_FLAG_CHANGE_FULLSCREEN(flags) ) { + if( NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, TST_FLAG_IS_ALWAYSONTOP(flags)) ) { + DBG_PRINT( "X11: reconfigureWindow0 X (atop.fast)\n"); + return; + } + } if( tempInvisible ) { DBG_PRINT( "X11: reconfigureWindow0 TEMP VISIBLE OFF\n"); @@ -813,6 +822,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo XSetWMProtocols(dpy, w, &wm_delete_atom, 1); // windowDeleteAtom // Fix for Unity WM, i.e. _remove_ persistent previous set states NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, False); + if( TST_FLAG_IS_ALWAYSONTOP(flags) ) { + // Reinforce always-on-top, lost by WM during reparenting + NewtWindows_setStackingEWMHFlags(dpy, root, w, _NET_WM_STATE_FLAG_ABOVE, isVisible, True); + } } if( TST_FLAG_CHANGE_DECORATION(flags) ) { -- cgit v1.2.3 From d67a2c52167abfd2d15e1b2b7c8a5d810932f398 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 20 Dec 2013 08:41:11 +0100 Subject: Refine commit c9fcc8cd510abc0cbebb872dc3e457327655e778 (NEWT X11Window.c comments) --- src/newt/native/X11Window.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/newt/native/X11Window.c') diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 735520b86..ad17f970b 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -755,10 +755,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; // fs off, above off } // else { } // fs off, above on } else if( TST_FLAG_CHANGE_PARENTING(flags) ) { - // Fix for Unity WM, i.e. _remove_ persistent previous set states - fsEWMHFlags |= _NET_WM_STATE_FLAG_FULLSCREEN; + // Fix for Unity WM, i.e. _remove_ persistent previous states + fsEWMHFlags |= _NET_WM_STATE_FLAG_FULLSCREEN; // fs off if( !TST_FLAG_IS_ALWAYSONTOP(flags) ) { - fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; + fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; // above off } } else if( TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) { fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; // toggle above @@ -774,9 +774,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags), tempInvisible, fsEWMHFlags); - // FS Note: To toggle FS, utilizing the _NET_WM_STATE_FULLSCREEN WM state shall be enough. - // However, we have to consider other cases like reparenting and WM which don't support it, i.e. Unity WM is sluggy. - #if 0 // Doesn't work properly w/ Unity WM + // FS Note: To toggle FS, utilizing the _NET_WM_STATE_FULLSCREEN WM state should be enough. + // However, we have to consider other cases like reparenting and WM which don't support it. + #if 0 // Also doesn't work work properly w/ Unity WM if( fsEWMHFlags && !TST_FLAG_CHANGE_PARENTING(flags) && isVisible && !TST_FLAG_IS_FULLSCREEN_SPAN(flags) && ( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) ) { @@ -785,7 +785,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo 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); } - DBG_PRINT( "X11: reconfigureWindow0 X (fast)\n"); + DBG_PRINT( "X11: reconfigureWindow0 X (fs.atop.fast)\n"); return; } } @@ -820,7 +820,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo #endif XSync(dpy, False); XSetWMProtocols(dpy, w, &wm_delete_atom, 1); // windowDeleteAtom - // Fix for Unity WM, i.e. _remove_ persistent previous set states + // Fix for Unity WM, i.e. _remove_ persistent previous states NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, False); if( TST_FLAG_IS_ALWAYSONTOP(flags) ) { // Reinforce always-on-top, lost by WM during reparenting -- cgit v1.2.3 From 904adbe63a806ff73ea654da6cc964277bbbb8d3 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 20 Dec 2013 08:49:05 +0100 Subject: Bug 924: Make ALWAYS_ON_TOP Persistent when Reparenting (child -> top) (2nd attempt) Commit c8726ef04b94ad8e66e1191a06ff793b908d130c reinforced ALWAYS_ON_TOP in native reconfig code issued at reparenting call, which might be too early for the WM. Perform ALWAYS_ON_TOP reinforcement from java side when reparenting CHILD -> TOP was successful and visibility is reached. X11 only! NewtAWTReparentingKeyAdapter: Add 'a' alwaysOnTop toggle to test w/o applet code. --- make/scripts/tests.sh | 2 +- src/newt/classes/jogamp/newt/WindowImpl.java | 4 ++++ src/newt/native/X11Window.c | 4 ---- .../test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java | 6 ++++++ 4 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src/newt/native/X11Window.c') diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index b680d2b25..57b13ab3b 100644 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -93,7 +93,7 @@ function jrun() { #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all" #D_ARGS="-Djogamp.debug=all -Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all" #D_ARGS="-Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all" - D_ARGS="-Dnativewindow.debug=all -Dnewt.debug=all" + D_ARGS="-Dnativewindow.debug=all -Dnewt.debug.Window" #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all -Djogamp.debug.Lock" #D_ARGS="-Dnativewindow.debug.X11Util.ATI_HAS_NO_XCLOSEDISPLAY_BUG" diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 437179f12..d63104c71 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -1440,6 +1440,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer setVisibleImpl(true, x, y, width, height); ok = 0 <= WindowImpl.this.waitForVisible(true, false); if(ok) { + if( isAlwaysOnTop() && 0 == parentWindowHandle && NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true) ) { + // Reinforce ALWAYSONTOP when CHILD -> TOP reparenting, since reparenting itself cause X11 WM to loose it's state. + reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(FLAG_CHANGE_ALWAYSONTOP, isVisible())); + } ok = WindowImpl.this.waitForSize(width, height, false, TIMEOUT_NATIVEWINDOW); } if(ok) { diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index ad17f970b..5f5dddbe0 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -822,10 +822,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo XSetWMProtocols(dpy, w, &wm_delete_atom, 1); // windowDeleteAtom // Fix for Unity WM, i.e. _remove_ persistent previous states NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, False); - if( TST_FLAG_IS_ALWAYSONTOP(flags) ) { - // Reinforce always-on-top, lost by WM during reparenting - NewtWindows_setStackingEWMHFlags(dpy, root, w, _NET_WM_STATE_FLAG_ABOVE, isVisible, True); - } } if( TST_FLAG_CHANGE_DECORATION(flags) ) { diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java index f7fbc7332..189645d3d 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java @@ -96,6 +96,12 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter { } } }.run(); + } else if( e.getKeySymbol() == KeyEvent.VK_A ) { + new Thread() { + public void run() { + glWindow.setAlwaysOnTop(!glWindow.isAlwaysOnTop()); + } + }.run(); } else if( e.getKeySymbol() == KeyEvent.VK_R ) { if( null != quitAdapter ) { quitAdapter.enable(false); -- cgit v1.2.3 From e7ffa68bce9bb707005be72530b207c732f62c31 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 31 Dec 2013 08:14:21 +0100 Subject: Bug 934, Bug 935: NEWT: Add support for custom Application/Window and Pointer Icons - Utilizing JOGL's PNG decoder for all icons, if available. - Application/window icons: - Providing default application/window icons in 16x16 and 32x32 size - NewtFactory.setWindowIcons(..) or property 'newt.window.icons' maybe used to override default icons. - Using icons at application/window instantiation - Display.PointerIcons: - NativeWindow Win32 WindowClass no more references a default cursor in favor of fine grained cursor control [in NEWT] - Display provides create/destroy methods, where display destruction also releases open PointerIcon references. - Window.setPointerIcon(..) sets custom PointerIcon - Implemented Platforms - X11 - Windows - OSX - Manual Test: TestGearsES2NEWT (Press 'c') --- make/build-jogl.xml | 2 +- make/build-newt.xml | 12 +- .../resources/assets-test/jogamp-pointer-64x64.png | Bin 0 -> 2843 bytes make/resources/assets/newt/data/jogamp-16x16.png | Bin 0 -> 549 bytes make/resources/assets/newt/data/jogamp-32x32.png | Bin 0 -> 1020 bytes make/resources/misc/jogamp-48x48.png | Bin 0 -> 1278 bytes make/resources/misc/jogamp-64x64.png | Bin 0 -> 1833 bytes make/scripts/tests-win.bat | 4 +- make/scripts/tests-x64-dbg.bat | 3 +- make/scripts/tests.sh | 5 +- src/nativewindow/native/win32/GDImisc.c | 2 +- src/newt/classes/com/jogamp/newt/Display.java | 50 +++++++- src/newt/classes/com/jogamp/newt/NewtFactory.java | 33 +++++ src/newt/classes/com/jogamp/newt/Window.java | 15 +++ .../classes/com/jogamp/newt/opengl/GLWindow.java | 11 ++ src/newt/classes/jogamp/newt/DisplayImpl.java | 68 +++++++++- src/newt/classes/jogamp/newt/WindowImpl.java | 22 ++++ src/newt/classes/jogamp/newt/driver/PNGIcon.java | 102 +++++++++++++++ .../jogamp/newt/driver/macosx/DisplayDriver.java | 51 ++++++++ .../jogamp/newt/driver/macosx/WindowDriver.java | 11 ++ .../jogamp/newt/driver/opengl/JoglUtilPNGIcon.java | 139 +++++++++++++++++++++ .../jogamp/newt/driver/windows/DisplayDriver.java | 38 ++++++ .../jogamp/newt/driver/windows/WindowDriver.java | 56 +++++++-- .../jogamp/newt/driver/x11/DisplayDriver.java | 46 +++++++ .../jogamp/newt/driver/x11/WindowDriver.java | 51 +++++++- src/newt/native/MacWindow.m | 73 ++++++++++- src/newt/native/NewtMacWindow.h | 4 +- src/newt/native/NewtMacWindow.m | 41 ++++-- src/newt/native/WindowsWindow.c | 115 ++++++++++++++++- src/newt/native/X11Display.c | 52 ++++++++ src/newt/native/X11Window.c | 35 +++++- .../jogl/demos/es2/newt/TestGearsES2NEWT.java | 29 ++++- 32 files changed, 1027 insertions(+), 43 deletions(-) create mode 100644 make/resources/assets-test/jogamp-pointer-64x64.png create mode 100644 make/resources/assets/newt/data/jogamp-16x16.png create mode 100644 make/resources/assets/newt/data/jogamp-32x32.png create mode 100644 make/resources/misc/jogamp-48x48.png create mode 100644 make/resources/misc/jogamp-64x64.png create mode 100644 src/newt/classes/jogamp/newt/driver/PNGIcon.java create mode 100644 src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java (limited to 'src/newt/native/X11Window.c') diff --git a/make/build-jogl.xml b/make/build-jogl.xml index 28b738b10..4cdb93f4d 100644 --- a/make/build-jogl.xml +++ b/make/build-jogl.xml @@ -1833,7 +1833,7 @@ - + + value="com/jogamp/newt/opengl/** jogamp/newt/driver/opengl/**"/> @@ -277,12 +277,14 @@ + + @@ -302,6 +304,7 @@ + @@ -309,6 +312,7 @@ + @@ -316,6 +320,7 @@ + @@ -323,6 +328,7 @@ + @@ -332,18 +338,21 @@ + + + @@ -798,6 +807,7 @@ + diff --git a/make/resources/assets-test/jogamp-pointer-64x64.png b/make/resources/assets-test/jogamp-pointer-64x64.png new file mode 100644 index 000000000..a965dcab1 Binary files /dev/null and b/make/resources/assets-test/jogamp-pointer-64x64.png differ diff --git a/make/resources/assets/newt/data/jogamp-16x16.png b/make/resources/assets/newt/data/jogamp-16x16.png new file mode 100644 index 000000000..02df8997f Binary files /dev/null and b/make/resources/assets/newt/data/jogamp-16x16.png differ diff --git a/make/resources/assets/newt/data/jogamp-32x32.png b/make/resources/assets/newt/data/jogamp-32x32.png new file mode 100644 index 000000000..ab21c6e1b Binary files /dev/null and b/make/resources/assets/newt/data/jogamp-32x32.png differ diff --git a/make/resources/misc/jogamp-48x48.png b/make/resources/misc/jogamp-48x48.png new file mode 100644 index 000000000..216f8c0b7 Binary files /dev/null and b/make/resources/misc/jogamp-48x48.png differ diff --git a/make/resources/misc/jogamp-64x64.png b/make/resources/misc/jogamp-64x64.png new file mode 100644 index 000000000..9936616ca Binary files /dev/null and b/make/resources/misc/jogamp-64x64.png differ diff --git a/make/scripts/tests-win.bat b/make/scripts/tests-win.bat index f5417bf7a..d95b0025f 100755 --- a/make/scripts/tests-win.bat +++ b/make/scripts/tests-win.bat @@ -6,7 +6,7 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestMainVersion REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT -time 30000 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT %* -REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %* +scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 4000 -x 10 -y 10 -width 100 -height 100 -screen 0 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 40000 -width 100 -height 100 -screen 0 %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT -time 5000 @@ -39,7 +39,7 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintin REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT %* -scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT %* +REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT -time 5000 REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT %* diff --git a/make/scripts/tests-x64-dbg.bat b/make/scripts/tests-x64-dbg.bat index 6e8407f3e..ce2df922c 100755 --- a/make/scripts/tests-x64-dbg.bat +++ b/make/scripts/tests-x64-dbg.bat @@ -55,9 +55,10 @@ REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLC REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.GLJPanel" "-Djogl.debug.TileRenderer" "-Djogl.debug.TileRenderer.PNG" REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.GLJPanel" "-Djogl.debug.TileRenderer" REM set D_ARGS="-Djogl.gljpanel.noverticalflip" +set D_ARGS="-Dnewt.debug=all" REM set D_ARGS="-Dnewt.debug.Window" REM set D_ARGS="-Dnewt.debug.Window.KeyEvent" -set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Window.KeyEvent" "-Dnewt.debug.EDT" +REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Window.KeyEvent" "-Dnewt.debug.EDT" REM set D_ARGS="-Dnewt.debug.Window.MouseEvent" REM set D_ARGS="-Dnewt.debug.Window.MouseEvent" "-Dnewt.debug.Window.KeyEvent" REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display" diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 6cb1966d1..4c084d705 100644 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -312,7 +312,7 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT $* #testawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLCanvasAWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile00NEWT $* -testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $* # # demos (any TK, more user driven tests) @@ -325,7 +325,7 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelsAWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NewtCanvasAWT $* -#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* +testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NEWT $* #testawtswt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasSWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT $* @@ -636,6 +636,7 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestJPEGTextureFromFileNEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGImage00NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGImage01NEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.ToolPNG2CSource $* #testawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGTextureFromFileAWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGTextureFromFileNEWT $* #testawt com.jogamp.opengl.test.junit.jogl.util.texture.TestGLReadBufferUtilTextureIOWrite01AWT $* diff --git a/src/nativewindow/native/win32/GDImisc.c b/src/nativewindow/native/win32/GDImisc.c index b55988c11..25b98acf3 100644 --- a/src/nativewindow/native/win32/GDImisc.c +++ b/src/nativewindow/native/win32/GDImisc.c @@ -263,7 +263,7 @@ Java_jogamp_nativewindow_windows_GDIUtil_CreateWindowClass0 wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; - wc.hCursor = LoadCursor( NULL, IDC_ARROW); + wc.hCursor = NULL; wc.hbrBackground = NULL; // no background paint - GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = clazzName; diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java index 4469189a8..ee6dfd080 100644 --- a/src/newt/classes/com/jogamp/newt/Display.java +++ b/src/newt/classes/com/jogamp/newt/Display.java @@ -28,15 +28,21 @@ package com.jogamp.newt; -import com.jogamp.newt.util.EDTUtil; -import jogamp.newt.Debug; - +import java.io.IOException; import java.lang.ref.WeakReference; -import java.util.*; +import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeWindowException; +import jogamp.newt.Debug; + +import com.jogamp.common.util.IOUtil; +import com.jogamp.newt.util.EDTUtil; + public abstract class Display { public static final boolean DEBUG = Debug.debug("Display"); @@ -55,6 +61,42 @@ public abstract class Display { return false; } + /** + * Native PointerIcon handle. + *

    + * Instances can be created via {@link Display#createPointerIcon(com.jogamp.common.util.IOUtil.ClassResources, int, int)} + * and released via {@link Display#destroyPointerIcon(PointerIcon)}. + *

    + *

    + * PointerIcons can be used via {@link Window#setPointerIcon(PointerIcon)}. + *

    + */ + public static interface PointerIcon { } + + /** + * Returns the created {@link PointerIcon} or null if not implemented on platform. + * + * @param pngResource PNG resource + * @param hotX pointer hotspot x-coord, origin is upper-left corner + * @param hotY pointer hotspot y-coord, origin is upper-left corner + * @throws MalformedURLException + * @throws InterruptedException + * @throws IOException + * + * @see PointerIcon + * @see #destroyPointerIcon(PointerIcon) + * @see Window#setPointerIcon(PointerIcon) + */ + + public abstract PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException; + + /** + * @param pi + * + * @see #createPointerIcon(com.jogamp.common.util.IOUtil.ClassResources, int, int) + */ + public abstract void destroyPointerIcon(PointerIcon pi); + /** * Manual trigger the native creation, if it is not done yet.
    * This is useful to be able to request the {@link javax.media.nativewindow.AbstractGraphicsDevice}, via diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java index 157e2bb3c..92339ea73 100644 --- a/src/newt/classes/com/jogamp/newt/NewtFactory.java +++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java @@ -36,6 +36,7 @@ package com.jogamp.newt; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Arrays; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; @@ -44,6 +45,8 @@ import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.NativeWindowFactory; +import com.jogamp.common.util.IOUtil; + import jogamp.newt.Debug; import jogamp.newt.DisplayImpl; import jogamp.newt.ScreenImpl; @@ -54,15 +57,45 @@ public class NewtFactory { public static final String DRIVER_DEFAULT_ROOT_PACKAGE = "jogamp.newt.driver"; + private static IOUtil.ClassResources defaultWindowIcons; + static { AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { NativeWindowFactory.initSingleton(); // last resort .. + { + final String[] paths = Debug.getProperty("newt.window.icons", true, "newt/data/jogamp-16x16.png newt/data/jogamp-32x32.png").split("\\s"); + if( paths.length < 2 ) { + throw new IllegalArgumentException("Property 'newt.window.icons' did not specify at least two PNG icons, but "+Arrays.toString(paths)); + } + final Class clazz = NewtFactory.class; + defaultWindowIcons = new IOUtil.ClassResources(clazz, paths); + } return null; } } ); } + /** + * Returns the application window icon resources to be used. + *

    + * Property newt.window.icons may define a list of PNG icons separated by a whitespace character. + * Shall reference at least two PNG icons, from lower (16x16) to higher (>= 32x32) resolution. + *

    + *

    + * Users may also specify application window icons using {@link #setWindowIcons(com.jogamp.common.util.IOUtil.ClassResources)}. + *

    + */ + public static IOUtil.ClassResources getWindowIcons() { return defaultWindowIcons; } + + /** + * Allow user to set custom window icons, only applicable at application start before creating any NEWT instance. + *

    + * Shall reference at least two PNG icons, from lower (16x16) to higher (>= 32x32) resolution. + *

    + */ + public static void setWindowIcons(IOUtil.ClassResources cres) { defaultWindowIcons = cres; } + public static Class getCustomClass(String packageName, String classBaseName) { Class clazz = null; if(packageName!=null && classBaseName!=null) { diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index 5c3bb7889..8e73ba1d2 100644 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -30,6 +30,7 @@ package com.jogamp.newt; import java.util.List; +import com.jogamp.newt.Display.PointerIcon; import com.jogamp.newt.event.GestureHandler; import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.event.WindowListener; @@ -307,6 +308,20 @@ public interface Window extends NativeWindow, WindowClosingProtocol { */ void setPointerVisible(boolean pointerVisible); + /** + * Returns the current {@link PointerIcon}, which maybe null for the default. + * @see #setPointerIcon(PointerIcon) + */ + PointerIcon getPointerIcon(); + + /** + * @param pi Valid {@link PointerIcon} reference or null to reset the pointer icon to default. + * + * @see PointerIcon + * @see Display#createPointerIcon(com.jogamp.common.util.IOUtil.ClassResources, int, int) + */ + void setPointerIcon(final PointerIcon pi); + /** @see #confinePointer(boolean) */ boolean isPointerConfined(); diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 208602aa1..ca8ab6733 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -77,6 +77,7 @@ import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Screen; import com.jogamp.newt.Window; +import com.jogamp.newt.Display.PointerIcon; import com.jogamp.newt.event.GestureHandler; import com.jogamp.newt.event.KeyListener; import com.jogamp.newt.event.MouseListener; @@ -267,6 +268,16 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind window.setPointerVisible(mouseVisible); } + @Override + public final PointerIcon getPointerIcon() { + return window.getPointerIcon(); + } + + @Override + public final void setPointerIcon(final PointerIcon pi) { + window.setPointerIcon(pi); + } + @Override public final boolean isPointerConfined() { return window.isPointerConfined(); diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java index 0c29d772a..4e9b8b441 100644 --- a/src/newt/classes/jogamp/newt/DisplayImpl.java +++ b/src/newt/classes/jogamp/newt/DisplayImpl.java @@ -34,14 +34,18 @@ package jogamp.newt; +import com.jogamp.common.util.IOUtil; import com.jogamp.newt.Display; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.event.NEWTEvent; import com.jogamp.newt.event.NEWTEventConsumer; import jogamp.newt.event.NEWTEventTask; + import com.jogamp.newt.util.EDTUtil; +import java.io.IOException; +import java.net.MalformedURLException; import java.util.ArrayList; import javax.media.nativewindow.AbstractGraphicsDevice; @@ -62,6 +66,67 @@ public abstract class DisplayImpl extends Display { }); } + public static class PointerIconImpl implements PointerIcon { + public final long handle; + public PointerIconImpl(long handle) { + this.handle=handle; + } + } + + private void addPointerIconToList(final PointerIcon pi) { + synchronized(pointerIconList) { + pointerIconList.add(pi); + } + } + private void delPointerIconFromList(final PointerIcon pi) { + synchronized(pointerIconList) { + pointerIconList.remove(pi); + } + } + private final ArrayList pointerIconList = new ArrayList(); + + /** Executed from EDT! */ + private void destroyAllPointerIconFromList(final long dpy) { + synchronized(pointerIconList) { + for( int i=0; i < pointerIconList.size(); i++ ) { + final PointerIcon item = pointerIconList.get(i); + if( null != item ) { + // destroy! + destroyPointerIconImpl(dpy, item); + } + } + pointerIconList.clear(); + } + } + + @Override + public final PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException { + final PointerIcon res = createPointerIconImpl(pngResource, hotX, hotY); + addPointerIconToList(res); + return res; + } + protected PointerIcon createPointerIconImpl(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException { + return null; + } + + @Override + public final void destroyPointerIcon(final PointerIcon pi) { + delPointerIconFromList(pi); + runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { + @Override + public Object run(long dpy) { + try { + destroyPointerIconImpl(dpy, pi); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + }); + } + /** Executed from EDT! */ + protected void destroyPointerIconImpl(final long displayHandle, final PointerIcon pi) { } + /** Ensure static init has been run. */ /* pp */static void initSingleton() { } @@ -283,6 +348,7 @@ public abstract class DisplayImpl extends Display { @Override public void run() { if ( null != f_aDevice ) { + f_dpy.destroyAllPointerIconFromList(f_aDevice.getHandle()); f_dpy.closeNativeImpl(f_aDevice); } } @@ -453,7 +519,7 @@ public abstract class DisplayImpl extends Display { /** Dispatch native Toolkit messageges */ protected abstract void dispatchMessagesNative(); - private Object eventsLock = new Object(); + private final Object eventsLock = new Object(); private ArrayList events = new ArrayList(); private volatile boolean haveEvents = false; diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 7a7e69e48..d078caa3b 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -42,6 +42,7 @@ import java.lang.reflect.Method; import com.jogamp.common.util.ArrayHashSet; import com.jogamp.common.util.IntBitfield; import com.jogamp.common.util.ReflectionUtil; +import com.jogamp.newt.Display.PointerIcon; import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Display; @@ -83,6 +84,7 @@ import javax.media.nativewindow.util.Rectangle; import javax.media.nativewindow.util.RectangleImmutable; import jogamp.nativewindow.SurfaceUpdatedHelper; +import jogamp.newt.DisplayImpl.PointerIconImpl; public abstract class WindowImpl implements Window, NEWTEventConsumer { @@ -170,6 +172,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private String title = "Newt Window"; private boolean undecorated = false; private boolean alwaysOnTop = false; + private PointerIcon pointerIcon = null; private boolean pointerVisible = true; private boolean pointerConfined = false; private LifecycleHook lifecycleHook = null; @@ -436,6 +439,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer createNativeImpl(); screen.addMonitorModeListener(monitorModeListenerImpl); setTitleImpl(title); + if( null != pointerIcon ) { + setPointerIcon(pointerIcon); + } setPointerVisibleImpl(pointerVisible); confinePointerImpl(pointerConfined); setKeyboardVisible(keyboardVisible); @@ -725,6 +731,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer protected boolean setPointerVisibleImpl(boolean pointerVisible) { return false; } protected boolean confinePointerImpl(boolean confine) { return false; } protected void warpPointerImpl(int x, int y) { } + protected void setPointerIconImpl(final PointerIconImpl pi) { } //---------------------------------------------------------------------- // NativeSurface @@ -1675,6 +1682,21 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } } + + @Override + public final PointerIcon getPointerIcon() { return pointerIcon; } + + @Override + public final void setPointerIcon(final PointerIcon pi) { + if( this.pointerIcon != pi ) { + setPointerIcon(pointerIcon); + if( isNativeValid() ) { + setPointerIconImpl((PointerIconImpl)pi); + } + this.pointerIcon = pi; + } + } + @Override public final boolean isPointerConfined() { return pointerConfined; diff --git a/src/newt/classes/jogamp/newt/driver/PNGIcon.java b/src/newt/classes/jogamp/newt/driver/PNGIcon.java new file mode 100644 index 000000000..c958f6ec2 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/PNGIcon.java @@ -0,0 +1,102 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.newt.driver; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.nio.ByteBuffer; + +import jogamp.newt.Debug; + +import com.jogamp.common.util.IOUtil; +import com.jogamp.common.util.ReflectionUtil; + +public class PNGIcon { + private static final String err0 = "PNG decoder not implemented."; + + private static final boolean avail; + + static { + Debug.initSingleton(); + + final ClassLoader cl = PNGIcon.class.getClassLoader(); + avail = ReflectionUtil.isClassAvailable("jogamp.newt.driver.opengl.JoglUtilPNGIcon", cl) && + ReflectionUtil.isClassAvailable("com.jogamp.opengl.util.texture.spi.PNGImage", cl); + } + + /** Returns true if PNG decoder is available. */ + public static boolean isAvailable() { + return avail; + } + + /** + * Implemented for X11. + * @param resources + * @param data_size + * @param elem_bytesize + * + * @return BGRA8888 bytes with origin at upper-left corner where component B is located on the lowest 8-bit and component A is located on the highest 8-bit. + * + * @throws UnsupportedOperationException if not implemented + * @throws InterruptedException + * @throws IOException + * @throws MalformedURLException + */ + public static ByteBuffer arrayToX11BGRAImages(IOUtil.ClassResources resources, int[] data_size, int[] elem_bytesize) throws UnsupportedOperationException, InterruptedException, IOException, MalformedURLException { + if( avail ) { + return jogamp.newt.driver.opengl.JoglUtilPNGIcon.arrayToX11BGRAImages(resources, data_size, elem_bytesize); + } + throw new UnsupportedOperationException(err0); + } + + /** + * Implemented for Windows. + * @param resources + * @param toBGRA if true, arranges stores in BGRA888 order, otherwise RGBA888 + * @param width + * @param height + * @param data_size + * @param elem_bytesize + * @param resourcesIdx + * @return pixels with origin at upper-left corner. + * If storing RGBA8888, component R is located on the lowest 8-bit. + * If storing BGRA8888, component B is located on the lowest 8-bit. + * Component A is located on the highest 8-bit. + * + * @throws UnsupportedOperationException if not implemented + * @throws InterruptedException + * @throws IOException + * @throws MalformedURLException + */ + public static ByteBuffer singleToRGBAImage(IOUtil.ClassResources resources, int resourceIdx, boolean toBGRA, int[] width, int[] height, int[] data_size, int[] elem_bytesize) throws UnsupportedOperationException, InterruptedException, IOException, MalformedURLException { + if( avail ) { + return jogamp.newt.driver.opengl.JoglUtilPNGIcon.singleToRGBAImage(resources, resourceIdx, toBGRA, width, height, data_size, elem_bytesize); + } + throw new UnsupportedOperationException(err0); + } +} diff --git a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java index c44685dc8..86c8464a8 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java @@ -34,15 +34,26 @@ package jogamp.newt.driver.macosx; +import java.io.IOException; +import java.net.MalformedURLException; +import java.nio.Buffer; +import java.nio.ByteBuffer; + import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeWindowException; +import com.jogamp.common.util.IOUtil; import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice; +import com.jogamp.newt.NewtFactory; import jogamp.newt.DisplayImpl; import jogamp.newt.NEWTJNILibLoader; +import jogamp.newt.driver.PNGIcon; public class DisplayDriver extends DisplayImpl { + private static final int defaultIconWidth, defaultIconHeight; + private static final Buffer defaultIconData; + static { NEWTJNILibLoader.loadNEWT(); @@ -52,6 +63,25 @@ public class DisplayDriver extends DisplayImpl { if(!WindowDriver.initIDs0()) { throw new NativeWindowException("Failed to initialize jmethodIDs"); } + { + final int[] width = { 0 }, height = { 0 }, data_size = { 0 }, elem_bytesize = { 0 }; + Buffer data=null; + if( PNGIcon.isAvailable() ) { + try { + final IOUtil.ClassResources iconRes = NewtFactory.getWindowIcons(); + data = PNGIcon.singleToRGBAImage(iconRes, iconRes.resourceCount()-1, false /* toBGRA */, width, height, data_size, elem_bytesize); + } catch (Exception e) { + e.printStackTrace(); + } + } + defaultIconWidth = width[0]; + defaultIconHeight = height[0]; + defaultIconData = data; + if( null != defaultIconData ) { + DisplayDriver.setAppIcon0(defaultIconData, defaultIconWidth, defaultIconHeight); + } + } + if(DEBUG) { System.err.println("MacDisplay.init App and IDs OK "+Thread.currentThread().getName()); } @@ -79,6 +109,23 @@ public class DisplayDriver extends DisplayImpl { aDevice.close(); } + @Override + protected PointerIcon createPointerIconImpl(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException { + if( PNGIcon.isAvailable() ) { + final int[] width = { 0 }, height = { 0 }, data_size = { 0 }, elem_bytesize = { 0 }; + if( null != pngResource && 0 < pngResource.resourceCount() ) { + final ByteBuffer data = PNGIcon.singleToRGBAImage(pngResource, 0, true /* toBGRA */, width, height, data_size, elem_bytesize); + return new PointerIconImpl( createPointerIcon0(data, width[0], height[0], hotX, hotY) ); + } + } + return null; + } + + @Override + protected final void destroyPointerIconImpl(final long displayHandle, final PointerIcon pi) { + destroyPointerIcon0(((PointerIconImpl)pi).handle); + } + public static void runNSApplication() { runNSApplication0(); } @@ -89,5 +136,9 @@ public class DisplayDriver extends DisplayImpl { private static native boolean initNSApplication0(); private static native void runNSApplication0(); private static native void stopNSApplication0(); + /* pp */ static native void setAppIcon0(Object iconData, int iconWidth, int iconHeight); + private static native long createPointerIcon0(Object iconData, int iconWidth, int iconHeight, int hotX, int hotY); + private static native long destroyPointerIcon0(long handle); + } diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java index 641d7437c..a55fa915a 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java @@ -46,6 +46,7 @@ import javax.media.nativewindow.util.PointImmutable; import jogamp.nativewindow.macosx.OSXUtil; import jogamp.newt.WindowImpl; +import jogamp.newt.DisplayImpl.PointerIconImpl; import jogamp.newt.driver.DriverClearFocus; import jogamp.newt.driver.DriverUpdatePosition; @@ -391,6 +392,15 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl } } + @Override + protected void setPointerIconImpl(final PointerIconImpl pi) { + OSXUtil.RunOnMainThread(false, new Runnable() { + @Override + public void run() { + setPointerIcon0(getWindowHandle(), null != pi ? pi.handle : 0); + } } ); + } + @Override protected boolean setPointerVisibleImpl(final boolean pointerVisible) { if( !isOffscreenInstance ) { @@ -568,6 +578,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl private static native boolean setPointerVisible0(long windowHandle, boolean hasFocus, boolean visible); private static native boolean confinePointer0(long windowHandle, boolean confine); private static native void warpPointer0(long windowHandle, int x, int y); + private static native void setPointerIcon0(long windowHandle, long handle); // Window styles private static final int NSBorderlessWindowMask = 0; diff --git a/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java b/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java new file mode 100644 index 000000000..ea9029006 --- /dev/null +++ b/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java @@ -0,0 +1,139 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package jogamp.newt.driver.opengl; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URLConnection; +import java.nio.ByteBuffer; + +import com.jogamp.common.nio.Buffers; +import com.jogamp.common.os.Platform; +import com.jogamp.common.util.IOUtil; +import com.jogamp.opengl.util.texture.spi.PNGImage; + +public class JoglUtilPNGIcon { + + public static ByteBuffer arrayToX11BGRAImages(IOUtil.ClassResources resources, int[] data_size, int[] elem_bytesize) throws UnsupportedOperationException, InterruptedException, IOException, MalformedURLException { + final PNGImage[] images = new PNGImage[resources.resourceCount()]; + data_size[0] = 0; + for(int i=0; inull if !{@link #isNativeValid()}, otherwise the Boolean value of {@link X11GraphicsDevice#isXineramaEnabled()}. */ protected Boolean isXineramaEnabled() { return isNativeValid() ? Boolean.valueOf(((X11GraphicsDevice)aDevice).isXineramaEnabled()) : null; } + @Override + protected PointerIcon createPointerIconImpl(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException { + if( PNGIcon.isAvailable() ) { + final int[] width = { 0 }, height = { 0 }, data_size = { 0 }, elem_bytesize = { 0 }; + if( null != pngResource && 0 < pngResource.resourceCount() ) { + final ByteBuffer data = PNGIcon.singleToRGBAImage(pngResource, 0, false /* toBGRA */, width, height, data_size, elem_bytesize); + final long handle = runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { + @Override + public Long run(long dpy) { + long h = 0; + try { + h = createPointerIcon0(dpy, data, width[0], height[0], hotX, hotY); + } catch (Exception e) { + e.printStackTrace(); + } + return Long.valueOf(h); + } + }).longValue(); + return new PointerIconImpl(handle); + } + } + return null; + } + + @Override + protected final void destroyPointerIconImpl(final long displayHandle, final PointerIcon pi) { + destroyPointerIcon0(displayHandle, ((PointerIconImpl)pi).handle); + } + //---------------------------------------------------------------------- // Internals only // @@ -137,6 +174,15 @@ public class DisplayDriver extends DisplayImpl { private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom /* , long kbdHandle */); // XKB disabled for now + static long createPointerIcon0(long display, Buffer data, int width, int height, int hotX, int hotY) { + if( !Buffers.isDirect(data) ) { + throw new IllegalArgumentException("data buffer is not direct "+data); + } + return createPointerIcon0(display, data, Buffers.getDirectBufferByteOffset(data), width, height, hotX, hotY); + } + private static native long createPointerIcon0(long display, Object data, int data_offset, int width, int height, int hotX, int hotY); + static native void destroyPointerIcon0(long display, long handle); + /** X11 Window delete atom marker used on EDT */ private long windowDeleteAtom; diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java index f2a27b0c9..0ea2c5358 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java @@ -34,11 +34,16 @@ package jogamp.newt.driver.x11; +import java.nio.Buffer; + import jogamp.nativewindow.x11.X11Lib; import jogamp.nativewindow.x11.X11Util; import jogamp.newt.DisplayImpl; import jogamp.newt.DisplayImpl.DisplayRunnable; +import jogamp.newt.DisplayImpl.PointerIconImpl; import jogamp.newt.WindowImpl; +import jogamp.newt.driver.PNGIcon; + import javax.media.nativewindow.*; import javax.media.nativewindow.VisualIDHolder.VIDType; import javax.media.nativewindow.util.Insets; @@ -47,6 +52,7 @@ import javax.media.nativewindow.util.Point; import com.jogamp.nativewindow.x11.X11GraphicsDevice; import com.jogamp.nativewindow.x11.X11GraphicsScreen; +import com.jogamp.newt.NewtFactory; import com.jogamp.newt.event.InputEvent; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.event.MouseEvent; @@ -58,8 +64,29 @@ public class WindowDriver extends WindowImpl { private static final int X11_WHEEL_TWO_UP_BUTTON = 6; private static final int X11_WHEEL_TWO_DOWN_BUTTON = 7; + private static final int defaultIconDataSize; + private static final Buffer defaultIconData; + static { ScreenDriver.initSingleton(); + + int _icon_data_size=0, _icon_elem_bytesize=0; + Buffer _icon_data=null; + if( PNGIcon.isAvailable() ) { + try { + final int[] data_size = { 0 }, elem_bytesize = { 0 }; + _icon_data = PNGIcon.arrayToX11BGRAImages(NewtFactory.getWindowIcons(), data_size, elem_bytesize); + _icon_data_size = data_size[0]; + _icon_elem_bytesize = elem_bytesize[0]; + } catch (Exception e) { + e.printStackTrace(); + } + } + defaultIconDataSize = _icon_data_size; + defaultIconData = _icon_data; + if(DEBUG_IMPLEMENTATION) { + System.err.println("Def. Icon: data_size "+defaultIconDataSize+" * elem_size "+_icon_elem_bytesize+" = data "+defaultIconData); + } } public WindowDriver() { @@ -100,7 +127,8 @@ public class WindowDriver extends WindowImpl { setWindowHandle(CreateWindow0(getParentWindowHandle(), edtDevice.getHandle(), screen.getIndex(), visualID, display.getJavaObjectAtom(), display.getWindowDeleteAtom(), - getX(), getY(), getWidth(), getHeight(), autoPosition(), flags)); + getX(), getY(), getWidth(), getHeight(), autoPosition(), flags, + defaultIconDataSize, defaultIconData)); } finally { edtDevice.unlock(); } @@ -245,6 +273,21 @@ public class WindowDriver extends WindowImpl { }); } + @Override + protected void setPointerIconImpl(final PointerIconImpl pi) { + runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { + @Override + public Object run(long dpy) { + try { + setPointerIcon0(dpy, getWindowHandle(), null != pi ? pi.handle : 0); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + }); + } + @Override protected boolean setPointerVisibleImpl(final boolean pointerVisible) { return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() { @@ -381,13 +424,17 @@ public class WindowDriver extends WindowImpl { private native long CreateWindow0(long parentWindowHandle, long display, int screen_index, int visualID, long javaObjectAtom, long windowDeleteAtom, - int x, int y, int width, int height, boolean autoPosition, int flags); + int x, int y, int width, int height, boolean autoPosition, int flags, + int iconDataSize, Object iconData); private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom /*, long kbdHandle*/ ); // XKB disabled for now private native void reconfigureWindow0(long display, int screen_index, long parentWindowHandle, long windowHandle, long windowDeleteAtom, int x, int y, int width, int height, int flags); private native void requestFocus0(long display, long windowHandle, boolean force); private static native void setTitle0(long display, long windowHandle, String title); + + private static native void setPointerIcon0(long display, long windowHandle, long handle); + private static native long getParentWindow0(long display, long windowHandle); private static native boolean setPointerVisible0(long display, long windowHandle, boolean visible); private static native boolean confinePointer0(long display, long windowHandle, boolean grab); diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index 30d3458ad..16e9814ef 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -285,6 +285,76 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_stopNSApplic [pool release]; } +static NSImage * createNSImageFromData(JNIEnv *env, jobject jiconData, jint jiconWidth, jint jiconHeight) { + if( NULL != jiconData ) { + unsigned char * iconData = (unsigned char *) (*env)->GetDirectBufferAddress(env, jiconData); + NSInteger iconWidth = (NSInteger) jiconWidth; + NSInteger iconHeight = (NSInteger) jiconHeight; + const NSInteger bpc = 8 /* bits per component */, spp=4 /* RGBA */, bpp = bpc * spp; + const NSBitmapFormat bfmt = NSAlphaNonpremultipliedBitmapFormat; + const BOOL hasAlpha = YES; + + NSBitmapImageRep* bir = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: &iconData + pixelsWide: iconWidth + pixelsHigh: iconHeight + bitsPerSample: bpc + samplesPerPixel: spp + hasAlpha: hasAlpha + isPlanar: NO + colorSpaceName: NSCalibratedRGBColorSpace + bitmapFormat: bfmt + bytesPerRow: iconWidth*4 + bitsPerPixel: bpp]; + [bir autorelease]; + NSImage* nsImage = [[NSImage alloc] initWithCGImage: [bir CGImage] size:NSZeroSize]; + return nsImage; + } + return NULL; +} + +/* + * Class: jogamp_newt_driver_macosx_DisplayDriver + * Method: setAppIcon0 + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_setAppIcon0 + (JNIEnv *env, jobject unused, jobject jiconData, jint jiconWidth, jint jiconHeight) +{ + NSImage * nsImage = createNSImageFromData(env, jiconData, jiconWidth, jiconHeight); + if( NULL != nsImage ) { + [nsImage autorelease]; + [NSApp setApplicationIconImage: nsImage]; + } +} + +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_createPointerIcon0 + (JNIEnv *env, jobject unused, jobject jiconData, jint jiconWidth, jint jiconHeight, jint hotX, jint hotY) +{ + NSImage * nsImage = createNSImageFromData(env, jiconData, jiconWidth, jiconHeight); + if( NULL != nsImage ) { + [nsImage autorelease]; + NSPoint hotP = { hotX, hotY }; + NSCursor * c = [[NSCursor alloc] initWithImage: nsImage hotSpot: hotP]; + return (jlong) (intptr_t) c; + } + return 0; +} + +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_destroyPointerIcon0 + (JNIEnv *env, jobject unused, jlong handle) +{ + NSCursor * c = (NSCursor*) (intptr_t) handle ; + [c release]; +} + +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerIcon0 + (JNIEnv *env, jobject unused, jlong window, jlong handle) +{ + NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) window; + NSCursor * c = (NSCursor*) (intptr_t) handle ; + + [mWin setCustomCursor: c]; +} + static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx, BOOL cap) { NSArray *screens = [NSScreen screens]; if( screen_idx<0 || screen_idx>=[screens count] ) { @@ -632,7 +702,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createView0 [pool release]; - return (jlong) ((intptr_t) myView); + return (jlong) (intptr_t) myView; } /** @@ -674,7 +744,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow backing: (NSBackingStoreType) bufferingType defer: YES isFullscreenWindow: fullscreen]; - // DBG_PRINT( "createWindow0.1 - %p, isVisible %d\n", myWindow, [myWindow isVisible]); DBG_PRINT( "createWindow0.X - %p, isVisible %d\n", myWindow, [myWindow isVisible]); diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h index ba60b5665..1f907f30e 100644 --- a/src/newt/native/NewtMacWindow.h +++ b/src/newt/native/NewtMacWindow.h @@ -114,6 +114,7 @@ BOOL mouseVisible; BOOL mouseInside; BOOL cursorIsHidden; + NSCursor * customCursor; BOOL realized; BOOL modsDown[4]; // shift, ctrl, alt/option, win/command NSPoint lastInsideMousePosition; @@ -151,7 +152,8 @@ - (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p; - (BOOL) isMouseInside; -- (void) cursorHide:(BOOL)v; +- (void) cursorHide:(BOOL)v enter:(int)enterState; +- (void) setCustomCursor:(NSCursor*)c; - (void) setMouseVisible:(BOOL)v hasFocus:(BOOL)focus; - (void) setMouseConfined:(BOOL)v; - (void) setMousePosition:(NSPoint)p; diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m index 4b0198c7e..a7bab9b9d 100644 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -41,6 +41,8 @@ #include +#define PRINTF(...) NSLog(@ __VA_ARGS__) + static jfloat GetDelta(NSEvent *event, jint javaMods[]) { CGEventRef cgEvent = [event CGEvent]; CGFloat deltaY = 0.0; @@ -468,6 +470,7 @@ static UniChar CKCH_CharForKeyCode(jshort keyCode) { defaultPresentationOptions = 0; fullscreenPresentationOptions = 0; } + isFullscreenWindow = isfs; // Why is this necessary? Without it we don't get any of the // delegate methods like resizing and window movement. @@ -484,6 +487,7 @@ static UniChar CKCH_CharForKeyCode(jshort keyCode) { mouseVisible = YES; mouseInside = NO; cursorIsHidden = NO; + customCursor = NULL; realized = YES; DBG_PRINT("NewtWindow::create: %p, realized %d, hasPresentationSwitch %d[defaultOptions 0x%X, fullscreenOptions 0x%X], (refcnt %d)\n", res, realized, (int)hasPresentationSwitch, (int)defaultPresentationOptions, (int)fullscreenPresentationOptions, (int)[res retainCount]); @@ -678,13 +682,36 @@ static UniChar CKCH_CharForKeyCode(jshort keyCode) { DBG_PRINT( "setMouseVisible: confined %d, visible %d (current: %d), mouseInside %d, hasFocus %d\n", mouseConfined, mouseVisible, !cursorIsHidden, mouseInside, focus); if(YES == focus && YES == mouseInside) { - [self cursorHide: !mouseVisible]; + [self cursorHide: !mouseVisible enter: 0]; + } +} + +- (void) setCustomCursor:(NSCursor*)c +{ + if(YES == mouseInside) { + if( NULL != c ) { + DBG_PRINT( "setCustomCursor push: %p\n", c); + [c push]; + } else if( NULL != customCursor && [NSCursor currentCursor] == customCursor ) { + DBG_PRINT( "setCustomCursor pop: %p\n", customCursor); + [customCursor pop]; + } } + customCursor = c; } -- (void) cursorHide:(BOOL)v +- (void) cursorHide:(BOOL)v enter:(int)enterState { - DBG_PRINT( "cursorHide: %d -> %d\n", cursorIsHidden, v); + DBG_PRINT( "cursorHide: %d -> %d, enter %d\n", cursorIsHidden, v, enterState); + if( NULL != customCursor ) { + if( 1 == enterState && [NSCursor currentCursor] != customCursor ) { + DBG_PRINT( "cursorHide.customCursor push: %p\n", customCursor); + [customCursor push]; + } else if( -1 == enterState && [NSCursor currentCursor] == customCursor ) { + DBG_PRINT( "cursorHide.customCursor pop: %p\n", customCursor); + [customCursor pop]; + } + } if(v) { if(!cursorIsHidden) { [NSCursor hide]; @@ -941,7 +968,7 @@ static jint mods2JavaMods(NSUInteger mods) DBG_PRINT( "*************** windowDidBecomeKey\n"); mouseInside = [self isMouseInside]; if(YES == mouseInside) { - [self cursorHide: !mouseVisible]; + [self cursorHide: !mouseVisible enter: 0]; } [self focusChanged: YES]; } @@ -995,7 +1022,7 @@ static jint mods2JavaMods(NSUInteger mods) { DBG_PRINT( "mouseEntered: confined %d, visible %d\n", mouseConfined, mouseVisible); mouseInside = YES; - [self cursorHide: !mouseVisible]; + [self cursorHide: !mouseVisible enter: 1]; if(NO == mouseConfined) { [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_ENTERED]; } @@ -1006,7 +1033,7 @@ static jint mods2JavaMods(NSUInteger mods) DBG_PRINT( "mouseExited: confined %d, visible %d\n", mouseConfined, mouseVisible); if(NO == mouseConfined) { mouseInside = NO; - [self cursorHide: NO]; + [self cursorHide: NO enter: -1]; [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_EXITED]; } else { [self setMousePosition: lastInsideMousePosition]; @@ -1160,7 +1187,7 @@ static jint mods2JavaMods(NSUInteger mods) jboolean closed = JNI_FALSE; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - [self cursorHide: NO]; + [self cursorHide: NO enter: -1]; NSView* nsview = [self contentView]; if( ! [nsview isKindOfClass:[NewtView class]] ) { diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index dd0150e78..2a16dce57 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -139,7 +139,7 @@ #include "NewtCommon.h" -// #define VERBOSE_ON 1 +#define VERBOSE_ON 1 // #define DEBUG_KEYS 1 #ifdef VERBOSE_ON @@ -186,6 +186,10 @@ typedef struct { int height; /** Tristate: -1 HIDE, 0 NOP, 1 SHOW */ int setPointerVisible; + /** Tristate: -1 RESET, 0 NOP, 1 SET-NEW */ + int setPointerAction; + HCURSOR setPointerHandle; + HCURSOR defPointerHandle; /** Bool: 0 NOP, 1 FULLSCREEN */ int setFullscreen; int pointerCaptured; @@ -1023,10 +1027,22 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP } else /* -1 == wud->setPointerVisible */ { visibilityChangeSuccessful = SafeShowCursor(FALSE); } - useDefWindowProc = visibilityChangeSuccessful ? 1 : 0; DBG_PRINT("*** WindowsWindow: WM_SETCURSOR requested visibility: %d success: %d\n", wud->setPointerVisible, visibilityChangeSuccessful); wud->setPointerVisible = 0; - // own signal, consumed + // own signal, consumed, no further processing + useDefWindowProc = 0; + res = 1; + } else if( 0 != wud->setPointerAction ) { + if( -1 == wud->setPointerAction ) { + wud->setPointerHandle = wud->defPointerHandle; + } + HCURSOR preHandle = SetCursor(wud->setPointerHandle); + DBG_PRINT("*** WindowsWindow: WM_SETCURSOR requested change %d: pre %p -> set %p, def %p\n", + wud->setPointerAction, (void*)preHandle, (void*)wud->setPointerHandle, (void*)wud->defPointerHandle); + wud->setPointerAction = 0; + // own signal, consumed, no further processing + useDefWindowProc = 0; + res = 1; } else { useDefWindowProc = 1; // NOP for us, allow parent to act } @@ -1246,6 +1262,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP if( 0 == wud->pointerInside ) { wud->pointerInside = 1; NewtWindows_trackPointerLeave(wnd); + SetCursor(wud->setPointerHandle); } (*env)->CallVoidMethod(env, window, sendMouseEventID, (jshort) EVENT_MOUSE_MOVED, @@ -1997,7 +2014,8 @@ static void NewtWindow_setVisiblePosSize(HWND hwnd, BOOL atop, BOOL visible, JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindow0 (JNIEnv *env, jobject obj, jlong hInstance, jstring jWndClassName, jstring jWndName, jint winMajor, jint winMinor, - jlong parent, jint jx, jint jy, jint defaultWidth, jint defaultHeight, jboolean autoPosition, jint flags) + jlong parent, jint jx, jint jy, jint defaultWidth, jint defaultHeight, jboolean autoPosition, jint flags, + jlong iconSmallHandle, jlong iconBigHandle) { HWND parentWindow = (HWND) (intptr_t) parent; const TCHAR* wndClassName = NULL; @@ -2054,6 +2072,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo wud->width = width; wud->height = height; wud->setPointerVisible = 0; + wud->setPointerAction = 0; + wud->defPointerHandle = LoadCursor( NULL, IDC_ARROW); + wud->setPointerHandle = wud->defPointerHandle; wud->setFullscreen = 0; wud->pointerCaptured = 0; wud->pointerInside = 0; @@ -2083,6 +2104,12 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo RECT rc; RECT * insets; + if( 0 != iconSmallHandle ) { + SendMessage(window, WM_SETICON, ICON_SMALL, (LPARAM) iconSmallHandle ); + } + if( 0 != iconBigHandle ) { + SendMessage(window, WM_SETICON, ICON_BIG, (LPARAM) iconBigHandle ); + } ShowWindow(window, SW_SHOW); // send insets before visibility, allowing java code a proper sync point! @@ -2321,3 +2348,83 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_warpPointer0 SetCursorPos(x, y); } +JNIEXPORT jlong JNICALL +Java_jogamp_newt_driver_windows_DisplayDriver_createBGRA8888Icon0(JNIEnv *env, jobject _unused, + jobject data, jint data_offset, jint width, jint height, jboolean isCursor, jint hotX, jint hotY) { + + const unsigned char * data_ptr = (const unsigned char *) (*env)->GetDirectBufferAddress(env, data) + data_offset; + const int bytes = 4 * width * height; // BGRA8888 + + DWORD dwWidth, dwHeight; + BITMAPV5HEADER bi; + HBITMAP hBitmap; + void *lpBits; + HICON handle = NULL; + + dwWidth = width; // width of cursor + dwHeight = height; // height of cursor + + ZeroMemory(&bi,sizeof(BITMAPV5HEADER)); + bi.bV5Size = sizeof(BITMAPV5HEADER); + bi.bV5Width = dwWidth; + bi.bV5Height = -1 * dwHeight; + bi.bV5Planes = 1; + bi.bV5BitCount = 32; + bi.bV5Compression = BI_BITFIELDS; + // The following mask specification specifies a supported 32 BPP + // alpha format for Windows XP. + bi.bV5RedMask = 0x00FF0000; + bi.bV5GreenMask = 0x0000FF00; + bi.bV5BlueMask = 0x000000FF; + bi.bV5AlphaMask = 0xFF000000; + + HDC hdc; + hdc = GetDC(NULL); + + // Create the DIB section with an alpha channel. + hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, + (void **)&lpBits, NULL, (DWORD)0); + + memcpy(lpBits, data_ptr, bytes); + + ReleaseDC(NULL,hdc); + + // Create an empty mask bitmap. + HBITMAP hMonoBitmap = CreateBitmap(dwWidth,dwHeight,1,1,NULL); + + ICONINFO ii; + ii.fIcon = isCursor ? FALSE : TRUE; + ii.xHotspot = hotX; + ii.yHotspot = hotY; + ii.hbmMask = hMonoBitmap; + ii.hbmColor = hBitmap; + + // Create the alpha cursor with the alpha DIB section. + handle = CreateIconIndirect(&ii); + + DeleteObject(hBitmap); + DeleteObject(hMonoBitmap); + + return (jlong) (intptr_t) handle; +} + +JNIEXPORT void JNICALL +Java_jogamp_newt_driver_windows_DisplayDriver_destroyIcon0(JNIEnv *env, jobject _unused, jlong jhandle) { + HICON handle = (HICON) (intptr_t) jhandle; + DestroyIcon(handle); +} + +JNIEXPORT void JNICALL +Java_jogamp_newt_driver_windows_WindowDriver_setPointerIcon0(JNIEnv *env, jobject _unused, jlong window, jlong iconHandle) { + HWND hwnd = (HWND) (intptr_t) window; + WindowUserData * wud; +#if !defined(__MINGW64__) && ( defined(UNDER_CE) || _MSC_VER <= 1200 ) + wud = (WindowUserData *) GetWindowLong(hwnd, GWL_USERDATA); +#else + wud = (WindowUserData *) GetWindowLongPtr(hwnd, GWLP_USERDATA); +#endif + wud->setPointerAction = 0 != iconHandle ? 1 : -1; + wud->setPointerHandle = (HCURSOR) (intptr_t) iconHandle; + SendMessage(hwnd, WM_SETCURSOR, 0, 0); +} + diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c index e2392a113..19e733111 100644 --- a/src/newt/native/X11Display.c +++ b/src/newt/native/X11Display.c @@ -28,6 +28,8 @@ #include "X11Common.h" +#include + // #include // XKB disabled for now jclass X11NewtWindowClazz = NULL; @@ -670,4 +672,54 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage } } +/* + * Class: Java_jogamp_newt_driver_x11_DisplayDriver + * Method: createPointerIcon0 + * Signature: (JJILjava/lang/Object;I)V + */ +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_createPointerIcon0 + (JNIEnv *env, jclass clazz, jlong display, jobject data, jint data_offset, jint width, jint height, jint hotX, jint hotY) +{ + Cursor c; + + if( 0 != data ) { + Display * dpy = (Display *) (intptr_t) display; + char * data_ptr = (char *) (*env)->GetDirectBufferAddress(env, data) + data_offset; + XcursorImage ci; + ci.version = 1; // XCURSOR_IMAGE_VERSION; + ci.size = width; // nominal size (assume square ..) + ci.width = width; + ci.height = height; + ci.xhot = hotX; + ci.yhot = hotY; + ci.delay = 0; + ci.pixels = (XcursorPixel *)(intptr_t)data_ptr; + + c = XcursorImageLoadCursor (dpy, &ci); + + DBG_PRINT( "X11: createPointerIcon0: %p %dx%d %d/%d -> %p\n", data_ptr, width, height, hotX, hotY, (void *)c); + + } else { + c = 0; + } + return (jlong) (intptr_t) c; +} + +/* + * Class: Java_jogamp_newt_driver_x11_DisplayDriver + * Method: destroyPointerIcon0 + * Signature: (JJILjava/lang/Object;I)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_destroyPointerIcon0 + (JNIEnv *env, jclass clazz, jlong display, jlong handle) +{ + Display * dpy = (Display *) (intptr_t) display; + + if( 0 != handle ) { + Cursor c = (Cursor) (intptr_t) handle; + DBG_PRINT( "X11: destroyPointerIcon0: %p\n", (void *)c); + XFreeCursor(dpy, c); + } +} + diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 5f5dddbe0..da2778004 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -497,6 +497,12 @@ static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint } } +static void NewtWindows_setIcon(Display *dpy, Window w, int data_size, const unsigned char * data_ptr) { + Atom _NET_WM_ICON = XInternAtom(dpy, "_NET_WM_ICON", False); + Atom CARDINAL = XInternAtom(dpy, "CARDINAL", False); + XChangeProperty(dpy, w, _NET_WM_ICON, CARDINAL, 32, PropModeReplace, data_ptr, data_size); +} + /* * Class: jogamp_newt_driver_x11_WindowDriver * Method: CreateWindow @@ -505,7 +511,8 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWindow0 (JNIEnv *env, jobject obj, jlong parent, jlong display, jint screen_index, jint visualID, jlong javaObjectAtom, jlong windowDeleteAtom, - jint x, jint y, jint width, jint height, jboolean autoPosition, int flags) + jint x, jint y, jint width, jint height, jboolean autoPosition, int flags, + jint iconDataSize, jobject iconData) { Display * dpy = (Display *)(intptr_t)display; Atom wm_delete_atom = (Atom)windowDeleteAtom; @@ -626,6 +633,11 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWindow0 XEvent event; int left=0, right=0, top=0, bottom=0; + if( 0 < iconDataSize && NULL != iconData ) { + const unsigned char * iconDataPtr = (const unsigned char *) (*env)->GetDirectBufferAddress(env, iconData); + NewtWindows_setIcon(dpy, window, (int)iconDataSize, iconDataPtr); + } + XMapWindow(dpy, window); XIfEvent( dpy, &event, WaitForMapNotify, (XPointer) window ); // wait to get proper insets values @@ -944,6 +956,27 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_setTitle0 #endif } +/* + * Class: Java_jogamp_newt_driver_x11_WindowDriver + * Method: setPointerIcon0 + * Signature: (JJILjava/lang/Object;I)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_setPointerIcon0 + (JNIEnv *env, jclass clazz, jlong display, jlong window, jlong handle) +{ + Display * dpy = (Display *) (intptr_t) display; + Window w = (Window)window; + + if( 0 == handle ) { + DBG_PRINT( "X11: setPointerIcon0: reset\n"); + XUndefineCursor(dpy, w); + } else { + Cursor c = (Cursor) (intptr_t) handle; + DBG_PRINT( "X11: setPointerIcon0: %p\n", (void*)c); + XDefineCursor(dpy, w, c); + } +} + /* * Class: Java_jogamp_newt_driver_x11_WindowDriver * Method: setPointerVisible0 diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java index b54a2cd19..efec961de 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java @@ -30,7 +30,9 @@ package com.jogamp.opengl.test.junit.jogl.demos.es2.newt; import java.io.IOException; +import com.jogamp.common.util.IOUtil; import com.jogamp.newt.Display; +import com.jogamp.newt.Display.PointerIcon; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Screen; import com.jogamp.newt.event.KeyAdapter; @@ -44,9 +46,7 @@ import com.jogamp.opengl.test.junit.util.AWTRobotUtil; import com.jogamp.opengl.test.junit.util.MiscUtils; import com.jogamp.opengl.test.junit.util.UITestCase; import com.jogamp.opengl.test.junit.util.QuitAdapter; - import com.jogamp.opengl.util.Animator; - import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; import javax.media.nativewindow.NativeWindowFactory; @@ -54,7 +54,6 @@ import javax.media.nativewindow.util.Dimension; import javax.media.nativewindow.util.Point; import javax.media.nativewindow.util.PointImmutable; import javax.media.nativewindow.util.DimensionImmutable; - import javax.media.opengl.GLAnimatorControl; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCapabilities; @@ -171,6 +170,20 @@ public class TestGearsES2NEWT extends UITestCase { } }); + final PointerIcon pointerIconOne; + { + PointerIcon _pointerIconOne = null; + final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "jogamp-pointer-64x64.png" } ); + final Display disp = glWindow.getScreen().getDisplay(); + disp.createNative(); + try { + _pointerIconOne = disp.createPointerIcon(res, 32, 0); + } catch (Exception e) { + e.printStackTrace(); + } + pointerIconOne = _pointerIconOne; + } + glWindow.addKeyListener(new KeyAdapter() { @Override public void keyPressed(final KeyEvent e) { @@ -203,6 +216,16 @@ public class TestGearsES2NEWT extends UITestCase { System.err.println("[set alwaysontop post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); glWindow.setExclusiveContextThread(t); } }.start(); + } else if(e.getKeyChar()=='c') { + new Thread() { + public void run() { + final Thread t = glWindow.setExclusiveContextThread(null); + System.err.println("[set pointer-icon pre]"); + final PointerIcon currentPI = glWindow.getPointerIcon(); + glWindow.setPointerIcon( currentPI == pointerIconOne ? null : pointerIconOne); + System.err.println("[set pointer-icon post] "+currentPI+" -> "+glWindow.getPointerIcon()); + glWindow.setExclusiveContextThread(t); + } }.start(); } else if(e.getKeyChar()=='d') { new Thread() { public void run() { -- cgit v1.2.3 From bd98b927b910d9421e63cf0dbc2b746eec019f80 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 8 Jan 2014 21:56:26 +0100 Subject: Bug 935: NEWT PointerIcon: Utilize Toolkit Agnostic PixelFormat and Conversion Utilities (Allowing 'arbitrary' PointerIcon data input) Commit fe28bc125429b38cdcd016746081f4a6d521c6fd added the notion of toolkit agnostic PixelFormat and conversion utilities, utilized and further tested by this patch. +++ - PointerIcon is a PixelRectangle and hence holds the decoded data. This allows on-the-fly conversion if required as well as recreation w/o PNG re-decoding. - Using array-backed PointerIcon data where possible, allowing better performance when converting PixelFormat etc. - NEWT Display adds 'createPointerIcon(final IOUtil.ClassResources pngResource...' method to support agnostic PointerIcon creation. - NEWT Display adds methods to allow users to avoid PixelFormat and Buffer NIO type forced conversion: - PixelFormat getNativePointerIconPixelFormat() - boolean getNativePointerIconForceDirectNIO() +++ PNGImage -> PNGPixelRect Deleted: com.jogamp.opengl.util.texture.spi.PNGImage Added: com.jogamp.opengl.util.PNGPixelRect (We hope nobody was using PNGImage directly since it was a service-plugin for TextureIO) PNGPixelRect is a PixelRectangle PNGPixelRect actually is implemented OpenGL agnostic, however - since our PNGJ support lives under package 'jogamp.opengl.util.pngj' it cannot be moved up (yet). PNGPixelRect now handles all PixelFormat for the target format and also added support for grayscale+alpha (2 channels). The latter is force-converted to RGB* - similar to paletted. Further more, PNGPixelRect allows simply passing an OutputStream to write the PNG data. Used by: TextureIO and NEWT +++ - OffscreenSurfaceLayer's setCursor(..) uses the agnostic PixelRectangle instead of a PNG resource. - AWTMisc uses the PixelRectangle to produce the AWT Cursor and converts it to the required format. Hence same pixels are used for NEWT and AWT pointer/cursor icon. - TestGearsES2Newt and NewtAWTReparentingKeyAdapter 'tests' iterate over 3 custom PointerIcon when pressed 'c'. - JOGLNewtAppletBase uses the new custom PointerIcon 'newt/data/crosshair-lumina-trans-32x32.png', which is included in NEWT (213 bytes only). - --- .../assets-test/crosshair-lumina-trans-64x64.png | Bin 0 -> 424 bytes .../newt/data/crosshair-lumina-trans-32x32.png | Bin 0 -> 213 bytes make/scripts/tests.sh | 9 +- .../com/jogamp/opengl/util/PNGPixelRect.java | 335 +++++++++++++++++++++ .../com/jogamp/opengl/util/texture/TextureIO.java | 63 ++-- .../jogamp/opengl/util/texture/spi/PNGImage.java | 319 -------------------- .../com/jogamp/nativewindow/awt/JAWTWindow.java | 17 +- .../media/nativewindow/OffscreenLayerSurface.java | 10 +- .../classes/jogamp/nativewindow/awt/AWTMisc.java | 48 ++- src/newt/classes/com/jogamp/newt/Display.java | 119 ++++++-- .../jogamp/newt/awt/applet/JOGLNewtAppletBase.java | 4 +- src/newt/classes/jogamp/newt/DisplayImpl.java | 156 +++++++++- src/newt/classes/jogamp/newt/PointerIconImpl.java | 63 +++- src/newt/classes/jogamp/newt/WindowImpl.java | 8 +- src/newt/classes/jogamp/newt/driver/PNGIcon.java | 35 +-- .../jogamp/newt/driver/macosx/DisplayDriver.java | 58 ++-- .../jogamp/newt/driver/opengl/JoglUtilPNGIcon.java | 92 ++---- .../jogamp/newt/driver/windows/DisplayDriver.java | 50 ++- .../jogamp/newt/driver/x11/DisplayDriver.java | 38 +-- .../jogamp/newt/driver/x11/WindowDriver.java | 20 +- src/newt/native/MacWindow.m | 32 +- src/newt/native/WindowsWindow.c | 16 +- src/newt/native/X11Display.c | 15 +- src/newt/native/X11Window.c | 20 +- .../jogl/demos/es2/newt/TestGearsES2NEWT.java | 59 +++- .../test/junit/jogl/util/texture/PNGTstFiles.java | 54 ++++ .../jogl/util/texture/TestPNGImage00NEWT.java | 92 ------ .../jogl/util/texture/TestPNGImage01NEWT.java | 182 ----------- .../jogl/util/texture/TestPNGPixelRect00NEWT.java | 224 ++++++++++++++ .../jogl/util/texture/TestPNGPixelRect01NEWT.java | 198 ++++++++++++ .../util/texture/TestPixelFormatUtil01NEWT.java | 105 +++++++ .../util/texture/crosshair-lumina-trans-32x32.png | Bin 0 -> 213 bytes .../util/texture/crosshair-lumina-trans-64x64.png | Bin 0 -> 424 bytes .../parenting/NewtAWTReparentingKeyAdapter.java | 62 +++- 34 files changed, 1573 insertions(+), 930 deletions(-) create mode 100644 make/resources/assets-test/crosshair-lumina-trans-64x64.png create mode 100644 make/resources/assets/newt/data/crosshair-lumina-trans-32x32.png create mode 100644 src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java delete mode 100644 src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/PNGTstFiles.java delete mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage00NEWT.java delete mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage01NEWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect00NEWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGPixelRect01NEWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPixelFormatUtil01NEWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/crosshair-lumina-trans-32x32.png create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/crosshair-lumina-trans-64x64.png (limited to 'src/newt/native/X11Window.c') diff --git a/make/resources/assets-test/crosshair-lumina-trans-64x64.png b/make/resources/assets-test/crosshair-lumina-trans-64x64.png new file mode 100644 index 000000000..9be285335 Binary files /dev/null and b/make/resources/assets-test/crosshair-lumina-trans-64x64.png differ diff --git a/make/resources/assets/newt/data/crosshair-lumina-trans-32x32.png b/make/resources/assets/newt/data/crosshair-lumina-trans-32x32.png new file mode 100644 index 000000000..92279640b Binary files /dev/null and b/make/resources/assets/newt/data/crosshair-lumina-trans-32x32.png differ diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index db852ce42..55973eb12 100644 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -229,7 +229,7 @@ function jrun() { #D_ARGS="-Djogl.debug.GLContext -Dnewt.debug=all" #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.GLJPanel -Djogl.debug.TileRenderer -Djogl.debug.TileRenderer.PNG" #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.GLJPanel -Djogl.debug.TileRenderer" - #D_ARGS="-Djogl.debug.PNGImage" + #D_ARGS="-Djogl.debug.PNG -Dnewt.debug.Display.PointerIcon" #D_ARGS="-Djogl.debug.JPEGImage" #D_ARGS="-Djogl.debug.GLDrawable -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.CapabilitiesChooser" #X_ARGS="-Dsun.java2d.noddraw=True -Dsun.java2d.opengl=True -Dsun.java2d.xrender=false" @@ -634,9 +634,10 @@ testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasA #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestJPEGJoglAWTCompareNewtAWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestJPEGJoglAWTBenchmarkNewtAWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestJPEGTextureFromFileNEWT $* -#testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGImage00NEWT $* -#testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGImage01NEWT $* -#testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.ToolPNG2CSource $* +#testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGPixelRect00NEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGPixelRect01NEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPixelFormatUtil00NEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPixelFormatUtil01NEWT $* #testawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGTextureFromFileAWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.util.texture.TestPNGTextureFromFileNEWT $* #testawt com.jogamp.opengl.test.junit.jogl.util.texture.TestGLReadBufferUtilTextureIOWrite01AWT $* diff --git a/src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java b/src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java new file mode 100644 index 000000000..1bbc12f32 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/util/PNGPixelRect.java @@ -0,0 +1,335 @@ +/** + * Copyright 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.util; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; + +import javax.media.nativewindow.util.Dimension; +import javax.media.nativewindow.util.DimensionImmutable; +import javax.media.nativewindow.util.PixelFormat; +import javax.media.nativewindow.util.PixelRectangle; +import javax.media.nativewindow.util.PixelFormatUtil; + +import jogamp.opengl.Debug; +import jogamp.opengl.util.pngj.ImageInfo; +import jogamp.opengl.util.pngj.ImageLine; +import jogamp.opengl.util.pngj.ImageLineHelper; +import jogamp.opengl.util.pngj.PngReader; +import jogamp.opengl.util.pngj.PngWriter; +import jogamp.opengl.util.pngj.chunks.PngChunkPLTE; +import jogamp.opengl.util.pngj.chunks.PngChunkTRNS; +import jogamp.opengl.util.pngj.chunks.PngChunkTextVar; + +import com.jogamp.common.nio.Buffers; +import com.jogamp.common.util.IOUtil; + +public class PNGPixelRect extends PixelRectangle.GenericPixelRect { + private static final boolean DEBUG = Debug.debug("PNG"); + + /** + * Reads a PNG image from the specified InputStream. + *

    + * Implicitly converts the image to match the desired: + *

      + *
    • {@link PixelFormat}, see {@link #getPixelformat()}
    • + *
    • destStrideInBytes, see {@link #getStride()}
    • + *
    • destIsGLOriented, see {@link #isGLOriented()}
    • + *
    + *

    + * + * @param in input stream + * @param destFmt desired destination {@link PixelFormat} incl. conversion, maybe null to use source {@link PixelFormat} + * @param destDirectBuffer if true, using a direct NIO buffer, otherwise an array backed buffer + * @param destMinStrideInBytes used if greater than PNG's stride, otherwise using PNG's stride. Stride is width * bytes-per-pixel. + * @param destIsGLOriented + * @return the newly created PNGPixelRect instance + * @throws IOException + */ + public static PNGPixelRect read(final InputStream in, + final PixelFormat ddestFmt, final boolean destDirectBuffer, final int destMinStrideInBytes, + final boolean destIsGLOriented) throws IOException { + final PngReader pngr = new PngReader(new BufferedInputStream(in), null); + final ImageInfo imgInfo = pngr.imgInfo; + final PngChunkPLTE plte = pngr.getMetadata().getPLTE(); + final PngChunkTRNS trns = pngr.getMetadata().getTRNS(); + final boolean indexed = imgInfo.indexed; + final boolean hasAlpha = indexed ? ( trns != null ) : imgInfo.alpha ; + + if(DEBUG) { + System.err.println("PNGPixelRect: "+imgInfo); + } + final int channels = indexed ? ( hasAlpha ? 4 : 3 ) : imgInfo.channels ; + final boolean isGrayAlpha = 2 == channels && imgInfo.greyscale && imgInfo.alpha; + if ( ! ( 1 == channels || 3 == channels || 4 == channels || isGrayAlpha ) ) { + throw new RuntimeException("PNGPixelRect can only handle Lum/RGB/RGBA [1/3/4 channels] or Lum+A (GA) images for now. Channels "+channels + " Paletted: " + indexed); + } + final int bytesPerPixel = indexed ? channels : imgInfo.bytesPixel ; + if ( ! ( 1 == bytesPerPixel || 3 == bytesPerPixel || 4 == bytesPerPixel || isGrayAlpha ) ) { + throw new RuntimeException("PNGPixelRect can only handle Lum/RGB/RGBA [1/3/4 bpp] images for now. BytesPerPixel "+bytesPerPixel); + } + if( channels != bytesPerPixel ) { + throw new RuntimeException("PNGPixelRect currently only handles Channels [1/3/4] == BytePerPixel [1/3/4], channels: "+channels+", bytesPerPixel "+bytesPerPixel); + } + final int width = imgInfo.cols; + final int height = imgInfo.rows; + final double dpiX, dpiY; + { + final double[] dpi = pngr.getMetadata().getDpi(); + dpiX = dpi[0]; + dpiY = dpi[1]; + } + final PixelFormat srcFmt; + if ( indexed ) { + if ( hasAlpha ) { + srcFmt = PixelFormat.RGBA8888; + } else { + srcFmt = PixelFormat.RGB888; + } + } else { + switch( channels ) { + case 1: srcFmt = PixelFormat.LUMINANCE; break; + case 2: srcFmt = isGrayAlpha ? PixelFormat.LUMINANCE : null; break; + case 3: srcFmt = PixelFormat.RGB888; break; + case 4: srcFmt = PixelFormat.RGBA8888; break; + default: srcFmt = null; + } + if( null == srcFmt ) { + throw new InternalError("XXX: channels: "+channels+", bytesPerPixel "+bytesPerPixel); + } + } + final PixelFormat destFmt; + if( null == ddestFmt ) { + if( isGrayAlpha ) { + destFmt = PixelFormat.BGRA8888; // save alpha value on gray-alpha + } else { + destFmt = srcFmt; // 1:1 + } + } else { + destFmt = ddestFmt; // user choice + } + final int destStrideInBytes = Math.max(destMinStrideInBytes, destFmt.bytesPerPixel() * width); + final ByteBuffer destPixels = destDirectBuffer ? Buffers.newDirectByteBuffer(destStrideInBytes * height) : + ByteBuffer.allocate(destStrideInBytes * height); + { + final int reqBytes = destStrideInBytes * height; + if( destPixels.limit() < reqBytes ) { + throw new IndexOutOfBoundsException("Dest buffer has insufficient bytes left, needs "+reqBytes+": "+destPixels); + } + } + final boolean vert_flip = destIsGLOriented; + + int[] rgbaScanline = indexed ? new int[width * channels] : null; + if(DEBUG) { + System.err.println("PNGPixelRect: indexed "+indexed+", alpha "+hasAlpha+", grayscale "+imgInfo.greyscale+", channels "+channels+"/"+imgInfo.channels+ + ", bytesPerPixel "+bytesPerPixel+"/"+imgInfo.bytesPixel+ + ", grayAlpha "+isGrayAlpha+", pixels "+width+"x"+height+", dpi "+dpiX+"x"+dpiY+", format "+srcFmt); + System.err.println("PNGPixelRect: destFormat "+destFmt+" ("+ddestFmt+", bytesPerPixel "+destFmt.bytesPerPixel()+", fast-path "+(destFmt==srcFmt)+"), destDirectBuffer "+destDirectBuffer+", destIsGLOriented (flip) "+destIsGLOriented); + System.err.println("PNGPixelRect: destStrideInBytes "+destStrideInBytes+" (destMinStrideInBytes "+destMinStrideInBytes+")"); + } + + for (int row = 0; row < height; row++) { + final ImageLine l1 = pngr.readRow(row); + int lineOff = 0; + int dataOff = vert_flip ? ( height - 1 - row ) * destStrideInBytes : row * destStrideInBytes; + if( indexed ) { + for (int j = width - 1; j >= 0; j--) { + rgbaScanline = ImageLineHelper.palette2rgb(l1, plte, trns, rgbaScanline); // reuse rgbaScanline and update if resized + dataOff = getPixelRGBA8ToAny(destFmt, destPixels, dataOff, rgbaScanline, lineOff, hasAlpha); + lineOff += bytesPerPixel; + } + } else if( 1 == channels ) { + for (int j = width - 1; j >= 0; j--) { + dataOff = getPixelLUMToAny(destFmt, destPixels, dataOff, (byte)l1.scanline[lineOff++], (byte)0xff); // Luminance, 1 bytesPerPixel + } + } else if( isGrayAlpha ) { + for (int j = width - 1; j >= 0; j--) { + dataOff = getPixelLUMToAny(destFmt, destPixels, dataOff, (byte)l1.scanline[lineOff++], (byte)l1.scanline[lineOff++]); // Luminance+Alpha, 2 bytesPerPixel + } + } else if( srcFmt == destFmt ) { // fast-path + for (int j = width - 1; j >= 0; j--) { + dataOff = getPixelRGBSame(destPixels, dataOff, l1.scanline, lineOff, bytesPerPixel); + lineOff += bytesPerPixel; + } + } else { + for (int j = width - 1; j >= 0; j--) { + dataOff = getPixelRGBA8ToAny(destFmt, destPixels, dataOff, l1.scanline, lineOff, hasAlpha); + lineOff += bytesPerPixel; + } + } + } + pngr.end(); + + return new PNGPixelRect(destFmt, new Dimension(width, height), destStrideInBytes, destIsGLOriented, destPixels, dpiX, dpiY); + } + + private static final int getPixelLUMToAny(PixelFormat dest_fmt, ByteBuffer d, int dOff, byte lum, byte alpha) { + switch(dest_fmt) { + case LUMINANCE: + d.put(dOff++, lum); + break; + case BGR888: + case RGB888: + d.put(dOff++, lum); + d.put(dOff++, lum); + d.put(dOff++, lum); + break; + case ABGR8888: + case ARGB8888: + d.put(dOff++, alpha); // A + d.put(dOff++, lum); + d.put(dOff++, lum); + d.put(dOff++, lum); + break; + case BGRA8888: + case RGBA8888: + d.put(dOff++, lum); + d.put(dOff++, lum); + d.put(dOff++, lum); + d.put(dOff++, alpha); // A + break; + default: + throw new InternalError("Unhandled format "+dest_fmt); + } + return dOff; + } + private static final int getPixelRGBA8ToAny(final PixelFormat dest_fmt, final ByteBuffer d, int dOff, final int[] scanline, final int lineOff, final boolean srcHasAlpha) { + final int p = PixelFormatUtil.convertToInt32(dest_fmt, (byte)scanline[lineOff], // R + (byte)scanline[lineOff+1], // G + (byte)scanline[lineOff+2], // B + srcHasAlpha ? (byte)scanline[lineOff+3] : (byte)0xff); // A + final int dbpp = dest_fmt.bytesPerPixel(); + d.put(dOff++, (byte) ( p )); // 1 + if( 1 < dbpp ) { + d.put(dOff++, (byte) ( p >>> 8 )); // 2 + d.put(dOff++, (byte) ( p >>> 16 )); // 3 + if( 4 == dbpp ) { + d.put(dOff++, (byte) ( p >>> 24 )); // 4 + } + } + return dOff; + } + private static final int getPixelRGBSame(final ByteBuffer d, int dOff, final int[] scanline, final int lineOff, final int bpp) { + d.put(dOff++, (byte)scanline[lineOff]); // R + if( 1 < bpp ) { + d.put(dOff++, (byte)scanline[lineOff + 1]); // G + d.put(dOff++, (byte)scanline[lineOff + 2]); // B + if( 4 == bpp ) { + d.put(dOff++, (byte)scanline[lineOff + 3]); // A + } + } + return dOff; + } + private int setPixelRGBA8(final ImageLine line, final int lineOff, final ByteBuffer d, final int dOff, final int bytesPerPixel, final boolean hasAlpha) { + final int b = hasAlpha ? 4-1 : 3-1; + if( d.limit() <= dOff + b ) { + throw new IndexOutOfBoundsException("Buffer has unsufficient bytes left, needs ["+dOff+".."+(dOff+b)+"]: "+d); + } + final int p = PixelFormatUtil.convertToInt32(hasAlpha ? PixelFormat.RGBA8888 : PixelFormat.RGB888, pixelformat, d, dOff); + line.scanline[lineOff ] = 0xff & p; // R + line.scanline[lineOff + 1] = 0xff & ( p >>> 8 ); // G + line.scanline[lineOff + 2] = 0xff & ( p >>> 16 ); // B + if(hasAlpha) { + line.scanline[lineOff + 3] = 0xff & ( p >>> 24 ); // A + } + return dOff + pixelformat.bytesPerPixel(); + } + + /** + * Creates a PNGPixelRect from data supplied by the end user. Shares + * data with the passed ByteBuffer. + * + * @param pixelformat + * @param size + * @param strideInBytes + * @param isGLOriented see {@link #isGLOriented()}. + * @param pixels + * @param dpiX + * @param dpiY + */ + public PNGPixelRect(final PixelFormat pixelformat, final DimensionImmutable size, + final int strideInBytes, final boolean isGLOriented, final ByteBuffer pixels, + final double dpiX, final double dpiY) { + super(pixelformat, size, strideInBytes, isGLOriented, pixels); + this.dpi = new double[] { dpiX, dpiY }; + } + public PNGPixelRect(final PixelRectangle src, final double dpiX, final double dpiY) { + super(src); + this.dpi = new double[] { dpiX, dpiY }; + } + private final double[] dpi; + + /** Returns the dpi of the image. */ + public double[] getDpi() { return dpi; } + + public void write(final OutputStream outstream, final boolean closeOutstream) throws IOException { + final int width = size.getWidth(); + final int height = size.getHeight(); + final int bytesPerPixel = pixelformat.bytesPerPixel(); + final ImageInfo imi = new ImageInfo(width, height, 8 /* bitdepth */, + (4 == bytesPerPixel) ? true : false /* alpha */, + (1 == bytesPerPixel) ? true : false /* grayscale */, + false /* indexed */); + + // open image for writing to a output stream + try { + final PngWriter png = new PngWriter(outstream, imi); + // add some optional metadata (chunks) + png.getMetadata().setDpi(dpi[0], dpi[1]); + png.getMetadata().setTimeNow(0); // 0 seconds fron now = now + png.getMetadata().setText(PngChunkTextVar.KEY_Title, "JogAmp PNGPixelRect"); + // png.getMetadata().setText("my key", "my text"); + final boolean hasAlpha = 4 == bytesPerPixel; + + final ImageLine l1 = new ImageLine(imi); + for (int row = 0; row < height; row++) { + int dataOff = isGLOriented ? ( height - 1 - row ) * strideInBytes : row * strideInBytes; + int lineOff = 0; + if(1 == bytesPerPixel) { + for (int j = width - 1; j >= 0; j--) { + l1.scanline[lineOff++] = pixels.get(dataOff++); // // Luminance, 1 bytesPerPixel + } + } else { + for (int j = width - 1; j >= 0; j--) { + dataOff = setPixelRGBA8(l1, lineOff, pixels, dataOff, bytesPerPixel, hasAlpha); + lineOff += bytesPerPixel; + } + } + png.writeRow(l1, row); + } + png.end(); + } finally { + if( closeOutstream ) { + IOUtil.close(outstream, false); + } + } + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java index 67ab5176d..0cde24db4 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java @@ -41,10 +41,12 @@ package com.jogamp.opengl.util.texture; import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.net.URL; import java.nio.Buffer; import java.nio.ByteBuffer; @@ -52,9 +54,10 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import javax.media.nativewindow.util.Dimension; +import javax.media.nativewindow.util.PixelFormat; import javax.media.opengl.GL; import javax.media.opengl.GL2; -import javax.media.opengl.GL2ES2; import javax.media.opengl.GL2GL3; import javax.media.opengl.GLContext; import javax.media.opengl.GLException; @@ -63,11 +66,11 @@ import javax.media.opengl.GLProfile; import jogamp.opengl.Debug; import com.jogamp.common.util.IOUtil; +import com.jogamp.opengl.util.PNGPixelRect; import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; import com.jogamp.opengl.util.texture.spi.DDSImage; import com.jogamp.opengl.util.texture.spi.JPEGImage; import com.jogamp.opengl.util.texture.spi.NetPbmTextureWriter; -import com.jogamp.opengl.util.texture.spi.PNGImage; import com.jogamp.opengl.util.texture.spi.SGIImage; import com.jogamp.opengl.util.texture.spi.TGAImage; import com.jogamp.opengl.util.texture.spi.TextureProvider; @@ -1166,27 +1169,29 @@ public class TextureIO { boolean mipmap, String fileSuffix) throws IOException { if (PNG.equals(fileSuffix)) { - PNGImage image = PNGImage.read(/*glp, */ stream); - if (pixelFormat == 0) { - pixelFormat = image.getGLFormat(); - } - if (internalFormat == 0) { + final PNGPixelRect image = PNGPixelRect.read(stream, null, true /* directBuffer */, 0 /* destMinStrideInBytes */, true /* destIsGLOriented */); + final GLPixelAttributes glpa = GLPixelAttributes.convert(image.getPixelformat(), glp); + if ( 0 == pixelFormat ) { + pixelFormat = glpa.format; + } // else FIXME: Actually not supported w/ preset pixelFormat! + if ( 0 == internalFormat ) { + final boolean hasAlpha = 4 == glpa.bytesPerPixel; if(glp.isGL2ES3()) { - internalFormat = (image.getBytesPerPixel()==4)?GL.GL_RGBA8:GL.GL_RGB8; + internalFormat = hasAlpha ? GL.GL_RGBA8 : GL.GL_RGB8; } else { - internalFormat = (image.getBytesPerPixel()==4)?GL.GL_RGBA:GL.GL_RGB; + internalFormat = hasAlpha ? GL.GL_RGBA : GL.GL_RGB; } } return new TextureData(glp, internalFormat, - image.getWidth(), - image.getHeight(), + image.getSize().getWidth(), + image.getSize().getHeight(), 0, pixelFormat, - image.getGLType(), + glpa.type, mipmap, false, false, - image.getData(), + image.getPixels(), null); } @@ -1392,29 +1397,7 @@ public class TextureIO { final int pixelFormat = pixelAttribs.format; final int pixelType = pixelAttribs.type; final int bytesPerPixel = pixelAttribs.bytesPerPixel; - final boolean reversedChannels; - switch(pixelFormat) { - case GL.GL_ALPHA: - case GL.GL_LUMINANCE: - case GL2ES2.GL_RED: - reversedChannels=false; - break; - case GL.GL_RGB: - reversedChannels=false; - break; - case GL.GL_RGBA: - reversedChannels=false; - break; - case GL2.GL_BGR: - reversedChannels=true; - break; - case GL.GL_BGRA: - reversedChannels=true; - break; - default: - reversedChannels=false; - break; - } + final PixelFormat pixFmt = pixelAttribs.getPixelFormat(); if ( ( 1 == bytesPerPixel || 3 == bytesPerPixel || 4 == bytesPerPixel) && ( pixelType == GL.GL_BYTE || pixelType == GL.GL_UNSIGNED_BYTE)) { ByteBuffer buf = (ByteBuffer) data.getBuffer(); @@ -1423,9 +1406,11 @@ public class TextureIO { } buf.rewind(); - PNGImage image = PNGImage.createFromData(data.getWidth(), data.getHeight(), -1f, -1f, - bytesPerPixel, reversedChannels, !data.getMustFlipVertically(), buf); - image.write(file, true); + final PNGPixelRect image = new PNGPixelRect(pixFmt, new Dimension(data.getWidth(), data.getHeight()), + 0 /* stride */, true /* isGLOriented */, buf /* pixels */, + -1f, -1f); + final OutputStream outs = new BufferedOutputStream(IOUtil.getFileOutputStream(file, true /* allowOverwrite */)); + image.write(outs, true /* close */); return true; } throw new IOException("PNG writer doesn't support this pixel format 0x"+Integer.toHexString(pixelFormat)+ diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java deleted file mode 100644 index 71cbbf97e..000000000 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java +++ /dev/null @@ -1,319 +0,0 @@ -/** - * Copyright 2012 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ -package com.jogamp.opengl.util.texture.spi; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.ByteBuffer; - -import javax.media.opengl.GL; - -import jogamp.opengl.Debug; -import jogamp.opengl.util.pngj.ImageInfo; -import jogamp.opengl.util.pngj.ImageLine; -import jogamp.opengl.util.pngj.ImageLineHelper; -import jogamp.opengl.util.pngj.PngReader; -import jogamp.opengl.util.pngj.PngWriter; -import jogamp.opengl.util.pngj.chunks.PngChunkPLTE; -import jogamp.opengl.util.pngj.chunks.PngChunkTRNS; -import jogamp.opengl.util.pngj.chunks.PngChunkTextVar; - -import com.jogamp.common.nio.Buffers; -import com.jogamp.common.util.IOUtil; - -public class PNGImage { - private static final boolean DEBUG = Debug.debug("PNGImage"); - - /** - * Creates a PNGImage from data supplied by the end user. Shares - * data with the passed ByteBuffer. Assumes the data is already in - * the correct byte order for writing to disk, i.e., LUMINANCE, RGB or RGBA. - * Orientation is bottom-to-top (OpenGL coord. default) - * or top-to-bottom depending on isGLOriented. - * - * @param width - * @param height - * @param dpiX - * @param dpiY - * @param bytesPerPixel - * @param reversedChannels - * @param isGLOriented see {@link #isGLOriented()}. - * @param data - * @return - */ - public static PNGImage createFromData(int width, int height, double dpiX, double dpiY, - int bytesPerPixel, boolean reversedChannels, boolean isGLOriented, ByteBuffer data) { - return new PNGImage(width, height, dpiX, dpiY, bytesPerPixel, reversedChannels, isGLOriented, data); - } - - /** - * Reads a PNG image from the specified InputStream. - *

    - * Implicitly flip image to GL orientation, see {@link #isGLOriented()}. - *

    - */ - public static PNGImage read(InputStream in) throws IOException { - return new PNGImage(in); - } - - /** Reverse read and store, implicitly flip image to GL orientation, see {@link #isGLOriented()}. */ - private static final int getPixelRGBA8(ByteBuffer d, int dOff, int[] scanline, int lineOff, boolean hasAlpha) { - final int b = hasAlpha ? 4-1 : 3-1; - if( d.limit() <= dOff || dOff - b < 0 ) { - throw new IndexOutOfBoundsException("Buffer has unsufficient bytes left, needs ["+(dOff-b)+".."+dOff+"]: "+d); - } - if(hasAlpha) { - d.put(dOff--, (byte)scanline[lineOff + 3]); // A - } - d.put(dOff--, (byte)scanline[lineOff + 2]); // B - d.put(dOff--, (byte)scanline[lineOff + 1]); // G - d.put(dOff--, (byte)scanline[lineOff ]); // R - return dOff; - } - - /** Reverse write and store, implicitly flip image from current orientation, see {@link #isGLOriented()}. Handle reversed channels (BGR[A]). */ - private int setPixelRGBA8(ImageLine line, int lineOff, ByteBuffer d, int dOff, boolean hasAlpha) { - final int b = hasAlpha ? 4-1 : 3-1; - if( d.limit() <= dOff + b ) { - throw new IndexOutOfBoundsException("Buffer has unsufficient bytes left, needs ["+dOff+".."+(dOff+b)+"]: "+d); - } - if( reversedChannels ) { - if(hasAlpha) { - line.scanline[lineOff + 3] = d.get(dOff++); // A - } - line.scanline[lineOff + 2] = d.get(dOff++); // R - line.scanline[lineOff + 1] = d.get(dOff++); // G - line.scanline[lineOff ] = d.get(dOff++); // B - } else { - line.scanline[lineOff ] = d.get(dOff++); // R - line.scanline[lineOff + 1] = d.get(dOff++); // G - line.scanline[lineOff + 2] = d.get(dOff++); // B - if(hasAlpha) { - line.scanline[lineOff + 3] = d.get(dOff++); // A - } - } - return isGLOriented ? dOff - bytesPerPixel - bytesPerPixel : dOff; - } - - private PNGImage(int width, int height, double dpiX, double dpiY, int bytesPerPixel, boolean reversedChannels, boolean isGLOriented, ByteBuffer data) { - pixelWidth=width; - pixelHeight=height; - dpi = new double[] { dpiX, dpiY }; - if(4 == bytesPerPixel) { - glFormat = GL.GL_RGBA; - } else if (3 == bytesPerPixel) { - glFormat = GL.GL_RGB; - } else { - throw new InternalError("XXX: bytesPerPixel "+bytesPerPixel); - } - this.bytesPerPixel = bytesPerPixel; - this.reversedChannels = reversedChannels; - this.isGLOriented = isGLOriented; - this.data = data; - } - - private PNGImage(InputStream in) { - final PngReader pngr = new PngReader(new BufferedInputStream(in), null); - final ImageInfo imgInfo = pngr.imgInfo; - final PngChunkPLTE plte = pngr.getMetadata().getPLTE(); - final PngChunkTRNS trns = pngr.getMetadata().getTRNS(); - final boolean indexed = imgInfo.indexed; - final boolean hasAlpha = indexed ? ( trns != null ) : imgInfo.alpha ; - - final int channels = indexed ? ( hasAlpha ? 4 : 3 ) : imgInfo.channels ; - if ( ! ( 1 == channels || 3 == channels || 4 == channels ) ) { - throw new RuntimeException("PNGImage can only handle Lum/RGB/RGBA [1/3/4 channels] images for now. Channels "+channels + " Paletted: " + indexed); - } - - bytesPerPixel = indexed ? channels : imgInfo.bytesPixel ; - if ( ! ( 1 == bytesPerPixel || 3 == bytesPerPixel || 4 == bytesPerPixel ) ) { - throw new RuntimeException("PNGImage can only handle Lum/RGB/RGBA [1/3/4 bpp] images for now. BytesPerPixel "+bytesPerPixel); - } - if( channels != bytesPerPixel ) { - throw new RuntimeException("PNGImage currently only handles Channels [1/3/4] == BytePerPixel [1/3/4], channels: "+channels+", bytesPerPixel "+bytesPerPixel); - } - pixelWidth = imgInfo.cols; - pixelHeight = imgInfo.rows; - dpi = new double[2]; - { - final double[] dpi2 = pngr.getMetadata().getDpi(); - dpi[0]=dpi2[0]; - dpi[1]=dpi2[1]; - } - if ( indexed ) { - if ( hasAlpha ) { - glFormat = GL.GL_RGBA; - } else { - glFormat = GL.GL_RGB; - } - } else { - switch( channels ) { - case 1: glFormat = GL.GL_LUMINANCE; break; - case 3: glFormat = GL.GL_RGB; break; - case 4: glFormat = GL.GL_RGBA; break; - default: throw new InternalError("XXX: channels: "+channels+", bytesPerPixel "+bytesPerPixel); - } - } - if(DEBUG) { - System.err.println("PNGImage: "+imgInfo); - System.err.println("PNGImage: indexed "+indexed+", alpha "+hasAlpha+", channels "+channels+"/"+imgInfo.channels+ - ", bytesPerPixel "+bytesPerPixel+"/"+imgInfo.bytesPixel+ - ", pixels "+pixelWidth+"x"+pixelHeight+", dpi "+dpi[0]+"x"+dpi[1]+", glFormat 0x"+Integer.toHexString(glFormat)); - } - - data = Buffers.newDirectByteBuffer(bytesPerPixel * pixelWidth * pixelHeight); - reversedChannels = false; // RGB[A] - isGLOriented = true; - int dataOff = bytesPerPixel * pixelWidth * pixelHeight - 1; // start at end-of-buffer, reverse store - - int[] rgbaScanline = indexed ? new int[imgInfo.cols * channels] : null; - - for (int row = 0; row < pixelHeight; row++) { - final ImageLine l1 = pngr.readRow(row); - int lineOff = ( pixelWidth - 1 ) * bytesPerPixel ; // start w/ last pixel in line, reverse read (PNG top-left -> OpenGL bottom-left origin) - if( indexed ) { - for (int j = pixelWidth - 1; j >= 0; j--) { - rgbaScanline = ImageLineHelper.palette2rgb(l1, plte, trns, rgbaScanline); // reuse rgbaScanline and update if resized - dataOff = getPixelRGBA8(data, dataOff, rgbaScanline, lineOff, hasAlpha); - lineOff -= bytesPerPixel; - } - } else if( 1 == channels ) { - for (int j = pixelWidth - 1; j >= 0; j--) { - data.put(dataOff--, (byte)l1.scanline[lineOff--]); // Luminance, 1 bytesPerPixel - } - } else { - for (int j = pixelWidth - 1; j >= 0; j--) { - dataOff = getPixelRGBA8(data, dataOff, l1.scanline, lineOff, hasAlpha); - lineOff -= bytesPerPixel; - } - } - } - pngr.end(); - } - private final int pixelWidth, pixelHeight, glFormat, bytesPerPixel; - private final boolean reversedChannels; - private final boolean isGLOriented; - private final double[] dpi; - private final ByteBuffer data; - - /** Returns the width of the image. */ - public int getWidth() { return pixelWidth; } - - /** Returns the height of the image. */ - public int getHeight() { return pixelHeight; } - - /** Returns true if data has the channels reversed to BGR or BGRA, otherwise RGB or RGBA is expected. */ - public boolean getHasReversedChannels() { return reversedChannels; } - - /** - * Returns true if the drawable is rendered in - * OpenGL's coordinate system, origin at bottom left. - * Otherwise returns false, i.e. origin at top left. - *

    - * Default impl. is true, i.e. OpenGL coordinate system. - *

    - */ - public boolean isGLOriented() { return isGLOriented; } - - /** Returns the dpi of the image. */ - public double[] getDpi() { return dpi; } - - /** Returns the OpenGL format for this texture; e.g. GL.GL_LUMINANCE, GL.GL_RGB or GL.GL_RGBA. */ - public int getGLFormat() { return glFormat; } - - /** Returns the OpenGL data type: GL.GL_UNSIGNED_BYTE. */ - public int getGLType() { return GL.GL_UNSIGNED_BYTE; } - - /** Returns the bytes per pixel */ - public int getBytesPerPixel() { return bytesPerPixel; } - - /** Returns the raw data for this texture in the correct - (bottom-to-top) order for calls to glTexImage2D. */ - public ByteBuffer getData() { return data; } - - public void write(File out, boolean allowOverwrite) throws IOException { - final ImageInfo imi = new ImageInfo(pixelWidth, pixelHeight, 8, (4 == bytesPerPixel) ? true : false); // 8 bits per channel, no alpha - // open image for writing to a output stream - final OutputStream outs = new BufferedOutputStream(IOUtil.getFileOutputStream(out, allowOverwrite)); - try { - final PngWriter png = new PngWriter(outs, imi); - // add some optional metadata (chunks) - png.getMetadata().setDpi(dpi[0], dpi[1]); - png.getMetadata().setTimeNow(0); // 0 seconds fron now = now - png.getMetadata().setText(PngChunkTextVar.KEY_Title, "JogAmp PNGImage"); - // png.getMetadata().setText("my key", "my text"); - final boolean hasAlpha = 4 == bytesPerPixel; - final ImageLine l1 = new ImageLine(imi); - if( isGLOriented ) { - // start at last pixel at end-of-buffer, reverse read (OpenGL bottom-left -> PNG top-left origin) - int dataOff = ( pixelWidth * bytesPerPixel * ( pixelHeight - 1 ) ) + // full lines - 1 line - ( ( pixelWidth - 1 ) * bytesPerPixel ); // one line - 1 pixel - for (int row = 0; row < pixelHeight; row++) { - int lineOff = ( pixelWidth - 1 ) * bytesPerPixel ; // start w/ last pixel in line, reverse store (OpenGL bottom-left -> PNG top-left origin) - if(1 == bytesPerPixel) { - for (int j = pixelWidth - 1; j >= 0; j--) { - l1.scanline[lineOff--] = data.get(dataOff--); // // Luminance, 1 bytesPerPixel - } - } else { - for (int j = pixelWidth - 1; j >= 0; j--) { - dataOff = setPixelRGBA8(l1, lineOff, data, dataOff, hasAlpha); - lineOff -= bytesPerPixel; - } - } - png.writeRow(l1, row); - } - } else { - int dataOff = 0; // start at first pixel at start-of-buffer, normal read (same origin: top-left) - for (int row = 0; row < pixelHeight; row++) { - int lineOff = 0; // start w/ first pixel in line, normal store (same origin: top-left) - if(1 == bytesPerPixel) { - for (int j = pixelWidth - 1; j >= 0; j--) { - l1.scanline[lineOff++] = data.get(dataOff++); // // Luminance, 1 bytesPerPixel - } - } else { - for (int j = pixelWidth - 1; j >= 0; j--) { - dataOff = setPixelRGBA8(l1, lineOff, data, dataOff, hasAlpha); - lineOff += bytesPerPixel; - } - } - png.writeRow(l1, row); - } - } - png.end(); - } finally { - IOUtil.close(outs, false); - } - } - - @Override - public String toString() { return "PNGImage["+pixelWidth+"x"+pixelHeight+", dpi "+dpi[0]+" x "+dpi[1]+", bytesPerPixel "+bytesPerPixel+", reversedChannels "+reversedChannels+", "+data+"]"; } -} diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java index b947505cb..ddf513180 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java @@ -38,7 +38,6 @@ package com.jogamp.nativewindow.awt; import com.jogamp.common.os.Platform; -import com.jogamp.common.util.IOUtil; import com.jogamp.common.util.awt.AWTEDTExecutor; import com.jogamp.common.util.locks.LockFactory; import com.jogamp.common.util.locks.RecursiveLock; @@ -53,7 +52,6 @@ import java.awt.event.ComponentListener; import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyListener; import java.applet.Applet; -import java.io.IOException; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; @@ -66,6 +64,7 @@ import javax.media.nativewindow.OffscreenLayerSurface; import javax.media.nativewindow.SurfaceUpdatedListener; import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.InsetsImmutable; +import javax.media.nativewindow.util.PixelRectangle; import javax.media.nativewindow.util.Point; import javax.media.nativewindow.util.PointImmutable; import javax.media.nativewindow.util.Rectangle; @@ -433,19 +432,19 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, } @Override - public final boolean setCursor(final IOUtil.ClassResources resources, final PointImmutable hotSpot) throws IOException { + public final boolean setCursor(final PixelRectangle pixelrect, final PointImmutable hotSpot) { AWTEDTExecutor.singleton.invoke(false, new Runnable() { public void run() { Cursor c = null; - if( null == resources || null == hotSpot ) { + if( null == pixelrect || null == hotSpot ) { c = Cursor.getDefaultCursor(); } else { final java.awt.Point awtHotspot = new java.awt.Point(hotSpot.getX(), hotSpot.getY()); try { - c = AWTMisc.getCursor(resources, awtHotspot); - } catch (IOException e) { - e.printStackTrace(); - } + c = AWTMisc.getCursor(pixelrect, awtHotspot); + } catch (Exception e) { + e.printStackTrace(); + } } if( null != c ) { component.setCursor(c); @@ -455,7 +454,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, } @Override - public boolean hideCursor() { + public final boolean hideCursor() { AWTEDTExecutor.singleton.invoke(false, new Runnable() { public void run() { component.setCursor(AWTMisc.getNullCursor()); diff --git a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java index 81983a7c2..cf8cf89d2 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java +++ b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java @@ -27,11 +27,9 @@ */ package javax.media.nativewindow; -import java.io.IOException; - +import javax.media.nativewindow.util.PixelRectangle; import javax.media.nativewindow.util.PointImmutable; -import com.jogamp.common.util.IOUtil; import com.jogamp.common.util.locks.RecursiveLock; /** @@ -73,12 +71,12 @@ public interface OffscreenLayerSurface { /** * Optional method setting cursor in the corresponding on-screen surface/window, if exists. * - * @param resources maybe null for default cursor + * @param pixelrect cursor pixels, maybe null for default cursor * @param hotSpot maybe null for default cursor * @return true if successful, i.e. on-screen surface/window w/ cursor capabilities exists. Otherwise false. - * @throws IOException */ - public boolean setCursor(IOUtil.ClassResources resources, PointImmutable hotSpot) throws IOException; + public boolean setCursor(PixelRectangle pixelrect, PointImmutable hotSpot); + /** * Optional method hiding the cursor in the corresponding on-screen surface/window, if exists. * diff --git a/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java b/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java index b690aff4d..069cffeb8 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java +++ b/src/nativewindow/classes/jogamp/nativewindow/awt/AWTMisc.java @@ -37,21 +37,19 @@ import java.awt.Component; import java.awt.Container; import java.awt.Frame; import java.awt.image.BufferedImage; -import java.io.IOException; -import java.net.URLConnection; import java.util.HashMap; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JRootPane; import javax.swing.WindowConstants; -import javax.imageio.ImageIO; import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.WindowClosingProtocol; +import javax.media.nativewindow.util.PixelRectangle; +import javax.media.nativewindow.util.PixelFormat; +import javax.media.nativewindow.util.PixelFormatUtil; import javax.swing.MenuSelectionManager; -import com.jogamp.common.util.IOUtil; - public class AWTMisc { public static JFrame getJFrame(Component c) { @@ -173,7 +171,7 @@ public class AWTMisc { MenuSelectionManager.defaultManager().clearSelectedPath(); } - static final HashMap cursorMap = new HashMap(); + static final HashMap cursorMap = new HashMap(); static final Cursor nulCursor; static { final Toolkit toolkit = Toolkit.getDefaultToolkit(); @@ -183,21 +181,43 @@ public class AWTMisc { public static synchronized Cursor getNullCursor() { return nulCursor; } - public static synchronized Cursor getCursor(IOUtil.ClassResources resources, Point hotSpot) throws IOException { - final String key = resources.getClass().getName()+":"+resources.resourcePaths[0]; + public static synchronized Cursor getCursor(PixelRectangle pixelrect, Point hotSpot) { + // 31 * x == (x << 5) - x + int hash = 31 + pixelrect.hashCode(); + hash = ((hash << 5) - hash) + hotSpot.hashCode(); + final Integer key = Integer.valueOf(hash); + Cursor cursor = cursorMap.get(key); if( null == cursor ) { - cursor = createAWTCursor(resources, hotSpot); + cursor = createCursor(pixelrect, hotSpot); cursorMap.put(key, cursor); } return cursor; } - private static synchronized Cursor createAWTCursor(IOUtil.ClassResources resources, Point hotSpot) throws IOException { - final URLConnection urlConn = resources.resolve(0); - final BufferedImage img = ImageIO.read(urlConn.getInputStream()); - + private static synchronized Cursor createCursor(PixelRectangle pixelrect, Point hotSpot) { + final int width = pixelrect.getSize().getWidth(); + final int height = pixelrect.getSize().getHeight(); + final BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); // PixelFormat.BGRA8888 + final PixelFormatUtil.PixelSink32 imgSink = new PixelFormatUtil.PixelSink32() { + public void store(int x, int y, int pixel) { + img.setRGB(x, y, pixel); + } + @Override + public final PixelFormat getPixelformat() { + return PixelFormat.BGRA8888; + } + @Override + public int getStride() { + return width*4; + } + @Override + public final boolean isGLOriented() { + return false; + } + }; + PixelFormatUtil.convert32(imgSink, pixelrect); final Toolkit toolkit = Toolkit.getDefaultToolkit(); - return toolkit.createCustomCursor(img, hotSpot, resources.resourcePaths[0]); + return toolkit.createCustomCursor(img, hotSpot, pixelrect.toString()); } public static WindowClosingProtocol.WindowClosingMode AWT2NWClosingOperation(int awtClosingOperation) { diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java index 8d1445f80..4b38fcca5 100644 --- a/src/newt/classes/com/jogamp/newt/Display.java +++ b/src/newt/classes/com/jogamp/newt/Display.java @@ -30,14 +30,14 @@ package com.jogamp.newt; import java.io.IOException; import java.lang.ref.WeakReference; -import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.util.DimensionImmutable; +import javax.media.nativewindow.util.PixelRectangle; +import javax.media.nativewindow.util.PixelFormat; import javax.media.nativewindow.util.PointImmutable; import jogamp.newt.Debug; @@ -47,6 +47,7 @@ import com.jogamp.newt.util.EDTUtil; public abstract class Display { public static final boolean DEBUG = Debug.debug("Display"); + protected static final boolean DEBUG_POINTER_ICON = Debug.debug("Display.PointerIcon"); /** return precomputed hashCode from FQN {@link #getFQName()} */ @Override @@ -66,7 +67,9 @@ public abstract class Display { /** * Native PointerIcon handle. *

    - * Instances can be created via {@link Display}'s {@link Display#createPointerIcon(com.jogamp.common.util.IOUtil.ClassResources, int, int) createPointerIcon(..)}. + * Instances can be created via {@link Display}'s + * {@link Display#createPointerIcon(com.jogamp.common.util.IOUtil.ClassResources, int, int) createPointerIcon(pngResource, ..)} + * or {@link Display#createPointerIcon(PixelRectangle, int, int) createPointerIcon(pixelrect, ..)}. *

    *

    * Instance is {@link #destroy()}'ed automatically if it's {@link #getDisplay() associated Display} is destroyed. @@ -75,23 +78,65 @@ public abstract class Display { * Instance can be re-validated after destruction via {@link #validate()}. *

    *

    + * {@link PointerIcon} must not be {@link #destroy() destroyed} while in use! + *

    + *

    * {@link PointerIcon} may be {@link #destroy() destroyed} manually after use, * i.e. when no {@link Window} {@link Window#setPointerIcon(PointerIcon) uses them} anymore. + * However, this is not required. *

    *

    * PointerIcons can be used via {@link Window#setPointerIcon(PointerIcon)}. *

    */ - public static interface PointerIcon { + public static interface PointerIcon extends PixelRectangle { /** - * @return the associated Display + * Always neatly packed, i.e. width * bytes_per_pixel. + *

    + * {@inheritDoc} + *

    */ - Display getDisplay(); + @Override + int getStride(); + + /** + * Always false, i.e. origin is TOP-LEFT. + *

    + * {@inheritDoc} + *

    + */ + boolean isGLOriented(); + + /** + * Computes a hash code over: + *
      + *
    • display
    • + *
    • pixelformat
    • + *
    • size
    • + *
    • stride
    • + *
    • isGLOriented
    • + *
    • pixels
    • + *
    • hotspot
    • + *
    + * Dismissing the native handle! + *

    + * The hashCode shall be computed only once with first call + * and stored for later retrieval to enhance performance. + *

    + *

    + * {@inheritDoc} + *

    + */ + @Override + int hashCode(); /** - * @return the single {@link IOUtil.ClassResources}. + * @return the associated Display */ - IOUtil.ClassResources getResource(); + Display getDisplay(); + + /** Returns the hotspot. */ + PointImmutable getHotspot(); /** * Returns true if valid, otherwise false. @@ -116,35 +161,69 @@ public abstract class Display { *

    */ void destroy(); + } - /** Returns the size, i.e. width and height. */ - DimensionImmutable getSize(); + /** + * Returns the native platform's {@link PointerIcon.PixelFormat} for pointer-icon pixel data. + *

    + * Using this value will avoid conversion within {@link #createPointerIcon(PixelRectangle, int, int)}. + *

    + */ + public abstract PixelFormat getNativePointerIconPixelFormat(); - /** Returns the hotspot. */ - PointImmutable getHotspot(); + /** + * Returns the native platform's direct NIO buffer requirement pointer-icon pixel data. + *

    + * Using this value will avoid conversion within {@link #createPointerIcon(PixelRectangle, int, int)}. + *

    + */ + public abstract boolean getNativePointerIconForceDirectNIO(); - @Override - String toString(); - } + /** + * Returns the newly created {@link PointerIcon} or null if not implemented on platform. + *

    + * See {@link PointerIcon} for lifecycle semantics. + *

    + * + * @param pngResource single PNG resource for the {@link PointerIcon}. Only the first entry of {@link IOUtil.ClassResources#resourcePaths} is used. + * @param hotX pointer hotspot x-coord, origin is upper-left corner + * @param hotY pointer hotspot y-coord, origin is upper-left corner + * + * @throws IllegalArgumentException if pngResource is null or invalid + * @throws IllegalStateException if this Display instance is not {@link #isNativeValid() valid yet}. + * @throws IOException if the pngResource could not be {@link IOUtil.ClassResources#resolve(int) resolved} + * or via the PNG parser processing the input stream. + * + * @see PointerIcon + * @see Window#setPointerIcon(PointerIcon) + */ + public abstract PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) + throws IllegalArgumentException, IllegalStateException, IOException; /** * Returns the newly created {@link PointerIcon} or null if not implemented on platform. *

    * See {@link PointerIcon} for lifecycle semantics. *

    + *

    + * In case {@link #getNativePointerIconPixelFormat()} or {@link #getNativePointerIconForceDirectNIO()} + * is not matched by the given pixelrect, the pixelrect is converted + * into the required {@link PixelFormat} and NIO type. + *

    * - * @param pngResource single PNG resource, only the first entry of {@link IOUtil.ClassResources#resourcePaths} is used. + * @param pixelrect {@link PixelRectangle} source for the {@link PointerIcon} * @param hotX pointer hotspot x-coord, origin is upper-left corner * @param hotY pointer hotspot y-coord, origin is upper-left corner + * + * @throws IllegalArgumentException if pixelrect is null. * @throws IllegalStateException if this Display instance is not {@link #isNativeValid() valid yet}. - * @throws MalformedURLException - * @throws InterruptedException - * @throws IOException * * @see PointerIcon * @see Window#setPointerIcon(PointerIcon) + * @see #getNativePointerIconPixelFormat() + * @see #getNativePointerIconForceDirectNIO() */ - public abstract PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws IllegalStateException, MalformedURLException, InterruptedException, IOException; + public abstract PointerIcon createPointerIcon(final PixelRectangle pixelrect, final int hotX, final int hotY) throws IllegalArgumentException, IllegalStateException; /** * Manual trigger the native creation, if it is not done yet.
    diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java index 7ffbc2e83..472672fd9 100644 --- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java +++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java @@ -235,10 +235,10 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener { glWindow.setVisible(true); glWindow.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); if( null == pointerIconTest ) { - final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/jogamp-32x32.png" } ); + final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/crosshair-lumina-trans-32x32.png" } ); final Display disp = glWindow.getScreen().getDisplay(); try { - pointerIconTest = disp.createPointerIcon(res, 16, 0); + pointerIconTest = disp.createPointerIcon(res, 16, 16); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java index 346c03b15..4c7169ec4 100644 --- a/src/newt/classes/jogamp/newt/DisplayImpl.java +++ b/src/newt/classes/jogamp/newt/DisplayImpl.java @@ -34,7 +34,9 @@ package jogamp.newt; +import com.jogamp.common.nio.Buffers; import com.jogamp.common.util.IOUtil; +import com.jogamp.common.util.ReflectionUtil; import com.jogamp.newt.Display; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.event.NEWTEvent; @@ -43,17 +45,25 @@ import com.jogamp.newt.event.NEWTEventConsumer; import jogamp.newt.event.NEWTEventTask; import com.jogamp.newt.util.EDTUtil; +import com.jogamp.opengl.util.PNGPixelRect; import java.io.IOException; -import java.net.MalformedURLException; +import java.net.URLConnection; +import java.nio.ByteBuffer; import java.util.ArrayList; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.NativeWindowFactory; +import javax.media.nativewindow.util.PixelFormatUtil; +import javax.media.nativewindow.util.PixelRectangle; +import javax.media.nativewindow.util.PixelFormat; +import javax.media.nativewindow.util.Point; +import javax.media.nativewindow.util.PointImmutable; public abstract class DisplayImpl extends Display { private static int serialno = 1; + private static final boolean pngUtilAvail; static { NativeWindowFactory.addCustomShutdownHook(true /* head */, new Runnable() { @@ -64,8 +74,14 @@ public abstract class DisplayImpl extends Display { DisplayImpl.shutdownAll(); } }); + + final ClassLoader cl = DisplayImpl.class.getClassLoader(); + pngUtilAvail = ReflectionUtil.isClassAvailable("jogamp.opengl.util.pngj.PngReader", cl) && + ReflectionUtil.isClassAvailable("com.jogamp.opengl.util.PNGPixelRect", cl); } + public static final boolean isPNGUtilAvailable() { return pngUtilAvail; } + final ArrayList pointerIconList = new ArrayList(); /** Executed from EDT! */ @@ -86,13 +102,94 @@ public abstract class DisplayImpl extends Display { } @Override - public final PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException { - return createPointerIcon(false /* isTemp */, pngResource, hotX, hotY); + public PixelFormat getNativePointerIconPixelFormat() { return PixelFormat.BGRA8888; } + @Override + public boolean getNativePointerIconForceDirectNIO() { return false; } + + @Override + public final PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) + throws IllegalArgumentException, IllegalStateException, IOException + { + if( !isNativeValid() ) { + throw new IllegalStateException("Display.createPointerIcon(1): Display invalid "+this); + } + if( null == pngResource || 0 >= pngResource.resourceCount() ) { + throw new IllegalArgumentException("Null or invalid pngResource "+pngResource); + } + if( !pngUtilAvail ) { + return null; + } + final PointerIconImpl[] res = { null }; + runOnEDTIfAvail(true, new Runnable() { + public void run() { + try { + if( !DisplayImpl.this.isNativeValid() ) { + throw new IllegalStateException("Display.createPointerIcon(2): Display invalid "+DisplayImpl.this); + } + final URLConnection urlConn = pngResource.resolve(0); + if( null == urlConn ) { + throw new IOException("Could not resolve "+pngResource.resourcePaths[0]); + } + final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), + getNativePointerIconPixelFormat(), + getNativePointerIconForceDirectNIO(), + 0 /* destMinStrideInBytes */, false /* destIsGLOriented */); + final long handle = createPointerIconImplChecked(image.getPixelformat(), image.getSize().getWidth(), image.getSize().getHeight(), + image.getPixels(), hotX, hotY); + final PointImmutable hotspot = new Point(hotX, hotY); + if( DEBUG_POINTER_ICON ) { + System.err.println("createPointerIconPNG.0: "+image+", handle: "+toHexString(handle)+", hot "+hotspot); + } + if( 0 != handle ) { + res[0] = new PointerIconImpl(DisplayImpl.this, image, hotspot, handle); + if( DEBUG_POINTER_ICON ) { + System.err.println("createPointerIconPNG.0: "+res[0]); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } } ); + if( null != res[0] ) { + synchronized(pointerIconList) { + pointerIconList.add(res[0]); + } + } + return res[0]; } - PointerIcon createPointerIcon(final boolean isTemp, final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException { + + @Override + public final PointerIcon createPointerIcon(final PixelRectangle pixelrect, final int hotX, final int hotY) + throws IllegalArgumentException, IllegalStateException + { if( !isNativeValid() ) { throw new IllegalStateException("Display.createPointerIcon(1): Display invalid "+this); } + if( null == pixelrect ) { + throw new IllegalArgumentException("Null or pixelrect"); + } + final PixelRectangle fpixelrect; + if( getNativePointerIconPixelFormat() != pixelrect.getPixelformat() || pixelrect.isGLOriented() ) { + // conversion ! + fpixelrect = PixelFormatUtil.convert32(pixelrect, getNativePointerIconPixelFormat(), + 0 /* ddestStride */, false /* isGLOriented */, getNativePointerIconForceDirectNIO() ); + if( DEBUG_POINTER_ICON ) { + System.err.println("createPointerIconRES.0: Conversion-FMT "+pixelrect+" -> "+fpixelrect); + } + } else if( getNativePointerIconForceDirectNIO() && !Buffers.isDirect(pixelrect.getPixels()) ) { + // transfer to direct NIO + final ByteBuffer sBB = pixelrect.getPixels(); + final ByteBuffer dBB = Buffers.newDirectByteBuffer(sBB.array(), sBB.arrayOffset()); + fpixelrect = new PixelRectangle.GenericPixelRect(pixelrect.getPixelformat(), pixelrect.getSize(), pixelrect.getStride(), pixelrect.isGLOriented(), dBB); + if( DEBUG_POINTER_ICON ) { + System.err.println("createPointerIconRES.0: Conversion-NIO "+pixelrect+" -> "+fpixelrect); + } + } else { + fpixelrect = pixelrect; + if( DEBUG_POINTER_ICON ) { + System.err.println("createPointerIconRES.0: No conversion "+fpixelrect); + } + } final PointerIconImpl[] res = { null }; runOnEDTIfAvail(true, new Runnable() { public void run() { @@ -100,22 +197,63 @@ public abstract class DisplayImpl extends Display { if( !DisplayImpl.this.isNativeValid() ) { throw new IllegalStateException("Display.createPointerIcon(2): Display invalid "+DisplayImpl.this); } - res[0] = createPointerIconImpl(pngResource, hotX, hotY); + if( null != fpixelrect ) { + final long handle = createPointerIconImplChecked(fpixelrect.getPixelformat(), + fpixelrect.getSize().getWidth(), + fpixelrect.getSize().getHeight(), + fpixelrect.getPixels(), hotX, hotY); + if( 0 != handle ) { + res[0] = new PointerIconImpl(DisplayImpl.this, fpixelrect, new Point(hotX, hotY), handle); + } + } } catch (Exception e) { e.printStackTrace(); } } } ); - if( !isTemp ) { + if( null != res[0] ) { synchronized(pointerIconList) { pointerIconList.add(res[0]); } } return res[0]; } - /** Executed from EDT! */ - protected PointerIconImpl createPointerIconImpl(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException { - return null; + + /** + * Executed from EDT! + * + * @param pixelformat the pixels's format + * @param width the pixels's width + * @param height the pixels's height + * @param pixels the pixels + * @param hotX the PointerIcon's hot-spot x-coord + * @param hotY the PointerIcon's hot-spot x-coord + * @return if successful a valid handle (not null), otherwise null. + */ + protected final long createPointerIconImplChecked(PixelFormat pixelformat, int width, int height, final ByteBuffer pixels, final int hotX, final int hotY) { + if( getNativePointerIconPixelFormat() != pixelformat ) { + throw new IllegalArgumentException("Pixelformat no "+getNativePointerIconPixelFormat()+", but "+pixelformat); + } + if( getNativePointerIconForceDirectNIO() && !Buffers.isDirect(pixels) ) { + throw new IllegalArgumentException("pixel buffer is not direct "+pixels); + } + return createPointerIconImpl(pixelformat, width, height, pixels, hotX, hotY); + } + + /** + * Executed from EDT! + * + * @param pixelformat the pixels's format + * @param width the pixels's width + * @param height the pixels's height + * @param pixels the pixels + * @param hotX the PointerIcon's hot-spot x-coord + * @param hotY the PointerIcon's hot-spot x-coord + * @return if successful a valid handle (not null), otherwise null. + */ + protected long createPointerIconImpl(PixelFormat pixelformat, int width, int height, final ByteBuffer pixels, final int hotX, final int hotY) { + return 0; } + /** Executed from EDT! */ protected void destroyPointerIconImpl(final long displayHandle, long piHandle) { } diff --git a/src/newt/classes/jogamp/newt/PointerIconImpl.java b/src/newt/classes/jogamp/newt/PointerIconImpl.java index e2388be67..7c8535f20 100644 --- a/src/newt/classes/jogamp/newt/PointerIconImpl.java +++ b/src/newt/classes/jogamp/newt/PointerIconImpl.java @@ -27,27 +27,63 @@ */ package jogamp.newt; +import java.nio.ByteBuffer; + import javax.media.nativewindow.util.DimensionImmutable; +import javax.media.nativewindow.util.PixelFormat; +import javax.media.nativewindow.util.PixelRectangle; import javax.media.nativewindow.util.PointImmutable; -import com.jogamp.common.util.IOUtil; -import com.jogamp.common.util.IOUtil.ClassResources; import com.jogamp.newt.Display; import com.jogamp.newt.Display.PointerIcon; public class PointerIconImpl implements PointerIcon { private final DisplayImpl display; - private final IOUtil.ClassResources resource; + private final PixelFormat pixelformat; private final DimensionImmutable size; + private final ByteBuffer pixels; private final PointImmutable hotspot; private long handle; - public PointerIconImpl(DisplayImpl display, ClassResources resource, final DimensionImmutable size, final PointImmutable hotspot, final long handle) { + private int hashCode = 0; + private volatile boolean hashCodeComputed = false; + + public PointerIconImpl(final DisplayImpl display, final PixelFormat pixelformat, final DimensionImmutable size, final ByteBuffer pixels, final PointImmutable hotspot, final long handle) { this.display = display; - this.resource = resource; + this.pixelformat = pixelformat; this.size = size; + this.pixels = pixels; this.hotspot = hotspot; + this.handle=handle; } + public PointerIconImpl(final DisplayImpl display, final PixelRectangle pixelrect, final PointImmutable hotspot, final long handle) { + this.display = display; + this.pixelformat = pixelrect.getPixelformat(); + this.size = pixelrect.getSize(); + this.pixels = pixelrect.getPixels(); + this.hotspot = hotspot; + this.handle=handle; + } + + @Override + public int hashCode() { + if( !hashCodeComputed ) { // DBL CHECKED OK VOLATILE + synchronized (this) { + if( !hashCodeComputed ) { + // 31 * x == (x << 5) - x + int hash = 31 + display.getFQName().hashCode(); + hash = ((hash << 5) - hash) + pixelformat.hashCode(); + hash = ((hash << 5) - hash) + size.hashCode(); + hash = ((hash << 5) - hash) + getStride(); + hash = ((hash << 5) - hash) + ( isGLOriented() ? 1 : 0); + hash = ((hash << 5) - hash) + pixels.hashCode(); + hashCode = ((hash << 5) - hash) + hotspot.hashCode(); + } + } + } + return hashCode; + } + public synchronized final long getHandle() { return handle; } public synchronized final long validatedHandle() { synchronized(display.pointerIconList) { @@ -57,8 +93,7 @@ public class PointerIconImpl implements PointerIcon { } if( 0 == handle ) { try { - final PointerIconImpl temp = (PointerIconImpl) display.createPointerIcon(true /* isTemp */, resource, hotspot.getX(), hotspot.getY()); - handle = temp.handle; + handle = display.createPointerIconImpl(pixelformat, size.getWidth(), size.getHeight(), pixels, hotspot.getX(), hotspot.getY()); return handle; } catch (Exception e) { e.printStackTrace(); @@ -71,7 +106,9 @@ public class PointerIconImpl implements PointerIcon { @Override public final Display getDisplay() { return display; } @Override - public final IOUtil.ClassResources getResource() { return resource; } + public final PixelFormat getPixelformat() { return pixelformat; } + @Override + public final ByteBuffer getPixels() { return pixels; } @Override public synchronized final boolean isValid() { return 0 != handle; } @Override @@ -116,11 +153,19 @@ public class PointerIconImpl implements PointerIcon { return size; } @Override + public final int getStride() { + return size.getWidth() * pixelformat.bytesPerPixel(); + } + @Override + public final boolean isGLOriented() { + return false; + } + @Override public final PointImmutable getHotspot() { return hotspot; } @Override public final String toString() { - return "PointerIcon["+DisplayImpl.toHexString(super.hashCode())+", "+display.getFQName()+", "+resource.resourcePaths[0]+", 0x"+Long.toHexString(handle)+", "+size+", "+hotspot+"]"; + return "PointerIcon[obj 0x"+Integer.toHexString(super.hashCode())+", "+display.getFQName()+", 0x"+Long.toHexString(handle)+", "+pixelformat+", "+size+", "+hotspot+", pixels "+pixels+"]"; } } \ No newline at end of file diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 50f30f04d..dc9affd63 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -53,6 +53,7 @@ import javax.media.nativewindow.WindowClosingProtocol; import javax.media.nativewindow.util.DimensionImmutable; import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.InsetsImmutable; +import javax.media.nativewindow.util.PixelRectangle; import javax.media.nativewindow.util.Point; import javax.media.nativewindow.util.PointImmutable; import javax.media.nativewindow.util.Rectangle; @@ -61,7 +62,6 @@ import javax.media.nativewindow.util.RectangleImmutable; import jogamp.nativewindow.SurfaceUpdatedHelper; import com.jogamp.common.util.ArrayHashSet; -import com.jogamp.common.util.IOUtil; import com.jogamp.common.util.IntBitfield; import com.jogamp.common.util.ReflectionUtil; import com.jogamp.common.util.locks.LockFactory; @@ -1700,7 +1700,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } /** * Helper method to delegate {@link #setPointerVisibleImpl(boolean)} to - * {@link OffscreenLayerSurface#hideCursor()} or {@link OffscreenLayerSurface#setCursor(IOUtil.ClassResources, PointImmutable)}. + * {@link OffscreenLayerSurface#hideCursor()} or {@link OffscreenLayerSurface#setCursor(PixelRectangle, PointImmutable)}. *

    * Note: JAWTWindow is an OffscreenLayerSurface. *

    @@ -1755,7 +1755,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } /** * Helper method to delegate {@link #setPointerIconIntern(PointerIconImpl)} to - * {@link OffscreenLayerSurface#setCursor(IOUtil.ClassResources, PointImmutable)}. + * {@link OffscreenLayerSurface#setCursor(PixelRectangle, PointImmutable)} *

    * Note: JAWTWindow is an OffscreenLayerSurface. *

    @@ -1777,7 +1777,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer final OffscreenLayerSurface ols = (OffscreenLayerSurface) parent; try { if( null != pi ) { - return ols.setCursor(pi.getResource(), pi.getHotspot()); + return ols.setCursor(pi, pi.getHotspot()); } else { return ols.setCursor(null, null); // default } diff --git a/src/newt/classes/jogamp/newt/driver/PNGIcon.java b/src/newt/classes/jogamp/newt/driver/PNGIcon.java index ffa62978f..967acd413 100644 --- a/src/newt/classes/jogamp/newt/driver/PNGIcon.java +++ b/src/newt/classes/jogamp/newt/driver/PNGIcon.java @@ -32,6 +32,7 @@ import java.net.MalformedURLException; import java.nio.ByteBuffer; import jogamp.newt.Debug; +import jogamp.newt.DisplayImpl; import com.jogamp.common.util.IOUtil; import com.jogamp.common.util.ReflectionUtil; @@ -45,8 +46,7 @@ public class PNGIcon { Debug.initSingleton(); final ClassLoader cl = PNGIcon.class.getClassLoader(); - avail = ReflectionUtil.isClassAvailable("jogamp.newt.driver.opengl.JoglUtilPNGIcon", cl) && - ReflectionUtil.isClassAvailable("com.jogamp.opengl.util.texture.spi.PNGImage", cl); + avail = DisplayImpl.isPNGUtilAvailable() && ReflectionUtil.isClassAvailable("jogamp.newt.driver.opengl.JoglUtilPNGIcon", cl); } /** Returns true if PNG decoder is available. */ @@ -55,7 +55,11 @@ public class PNGIcon { } /** - * Implemented for X11. + * Special implementation for X11 Window Icons + *

    + * The returned byte buffer is a direct buffer! + *

    + * * @param resources * @param data_size * @param elem_bytesize @@ -73,29 +77,4 @@ public class PNGIcon { } throw new UnsupportedOperationException(err0); } - - /** - * Implemented for Windows. - * @param resources - * @param toBGRA if true, arranges stores in BGRA888 order, otherwise RGBA888 - * @param width - * @param height - * @param data_size - * @param resourcesIdx - * @return pixels with origin at upper-left corner. - * If storing RGBA8888, component R is located on the lowest 8-bit. - * If storing BGRA8888, component B is located on the lowest 8-bit. - * Component A is located on the highest 8-bit. - * - * @throws UnsupportedOperationException if not implemented - * @throws InterruptedException - * @throws IOException - * @throws MalformedURLException - */ - public static ByteBuffer singleToRGBAImage(IOUtil.ClassResources resources, int resourceIdx, boolean toBGRA, int[] width, int[] height, int[] data_size) throws UnsupportedOperationException, InterruptedException, IOException, MalformedURLException { - if( avail ) { - return jogamp.newt.driver.opengl.JoglUtilPNGIcon.singleToRGBAImage(resources, resourceIdx, toBGRA, width, height, data_size); - } - throw new UnsupportedOperationException(err0); - } } diff --git a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java index 30583c48c..d850a18af 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java @@ -34,28 +34,25 @@ package jogamp.newt.driver.macosx; -import java.io.IOException; -import java.net.MalformedURLException; +import java.net.URLConnection; import java.nio.Buffer; import java.nio.ByteBuffer; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeWindowException; -import javax.media.nativewindow.util.Dimension; -import javax.media.nativewindow.util.Point; +import javax.media.nativewindow.util.PixelFormat; +import com.jogamp.common.nio.Buffers; import com.jogamp.common.util.IOUtil; import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice; import com.jogamp.newt.NewtFactory; +import com.jogamp.opengl.util.PNGPixelRect; import jogamp.newt.DisplayImpl; import jogamp.newt.NEWTJNILibLoader; -import jogamp.newt.PointerIconImpl; -import jogamp.newt.driver.PNGIcon; public class DisplayDriver extends DisplayImpl { - private static final int defaultIconWidth, defaultIconHeight; - private static final Buffer defaultIconData; + private static final PNGPixelRect defaultIconData; static { NEWTJNILibLoader.loadNEWT(); @@ -67,21 +64,23 @@ public class DisplayDriver extends DisplayImpl { throw new NativeWindowException("Failed to initialize jmethodIDs"); } { - final int[] width = { 0 }, height = { 0 }, data_size = { 0 }; - Buffer data=null; - if( PNGIcon.isAvailable() ) { + PNGPixelRect image=null; + if( DisplayImpl.isPNGUtilAvailable() ) { try { + // NOTE: MUST BE DIRECT BUFFER, since NSBitmapImageRep uses buffer directly! final IOUtil.ClassResources iconRes = NewtFactory.getWindowIcons(); - data = PNGIcon.singleToRGBAImage(iconRes, iconRes.resourceCount()-1, false /* toBGRA */, width, height, data_size); + final URLConnection urlConn = iconRes.resolve(iconRes.resourceCount()-1); + image = PNGPixelRect.read(urlConn.getInputStream(), PixelFormat.BGRA8888, true /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */); } catch (Exception e) { e.printStackTrace(); } } - defaultIconWidth = width[0]; - defaultIconHeight = height[0]; - defaultIconData = data; + defaultIconData = image; if( null != defaultIconData ) { - DisplayDriver.setAppIcon0(defaultIconData, defaultIconWidth, defaultIconHeight); + final Buffer pixels = defaultIconData.getPixels(); + DisplayDriver.setAppIcon0( + pixels, Buffers.getDirectBufferByteOffset(pixels), true /* pixels_is_direct */, + defaultIconData.getSize().getWidth(), defaultIconData.getSize().getHeight()); } } @@ -112,17 +111,20 @@ public class DisplayDriver extends DisplayImpl { aDevice.close(); } + /** + * {@inheritDoc} + *

    + * NOTE: MUST BE DIRECT BUFFER, since NSBitmapImageRep uses buffer directly! + *

    + */ @Override - protected PointerIconImpl createPointerIconImpl(final IOUtil.ClassResources pngResource, final int hotX, final int hotY) throws MalformedURLException, InterruptedException, IOException { - if( PNGIcon.isAvailable() ) { - final int[] width = { 0 }, height = { 0 }, data_size = { 0 }; - if( null != pngResource && 0 < pngResource.resourceCount() ) { - final ByteBuffer data = PNGIcon.singleToRGBAImage(pngResource, 0, true /* toBGRA */, width, height, data_size); - return new PointerIconImpl( this, pngResource, new Dimension(width[0], height[0]), - new Point(hotX, hotY), createPointerIcon0(data, width[0], height[0], hotX, hotY)); - } - } - return null; + public final boolean getNativePointerIconForceDirectNIO() { return true; } + + @Override + protected final long createPointerIconImpl(PixelFormat pixelformat, int width, int height, final ByteBuffer pixels, final int hotX, final int hotY) { + return createPointerIcon0( + pixels, Buffers.getDirectBufferByteOffset(pixels), true /* pixels_is_direct */, + width, height, hotX, hotY); } @Override @@ -140,8 +142,8 @@ public class DisplayDriver extends DisplayImpl { private static native boolean initNSApplication0(); private static native void runNSApplication0(); private static native void stopNSApplication0(); - /* pp */ static native void setAppIcon0(Object iconData, int iconWidth, int iconHeight); - private static native long createPointerIcon0(Object iconData, int iconWidth, int iconHeight, int hotX, int hotY); + /* pp */ static native void setAppIcon0(Object pixels, int pixels_byte_offset, boolean pixels_is_direct, int width, int height); + private static native long createPointerIcon0(Object pixels, int pixels_byte_offset, boolean pixels_is_direct, int width, int height, int hotX, int hotY); private static native long destroyPointerIcon0(long handle); } diff --git a/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java b/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java index 216a0cb20..551929b8d 100644 --- a/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java +++ b/src/newt/classes/jogamp/newt/driver/opengl/JoglUtilPNGIcon.java @@ -32,20 +32,22 @@ import java.net.MalformedURLException; import java.net.URLConnection; import java.nio.ByteBuffer; +import javax.media.nativewindow.util.PixelFormat; + import com.jogamp.common.nio.Buffers; import com.jogamp.common.os.Platform; import com.jogamp.common.util.IOUtil; -import com.jogamp.opengl.util.texture.spi.PNGImage; +import com.jogamp.opengl.util.PNGPixelRect; public class JoglUtilPNGIcon { public static ByteBuffer arrayToX11BGRAImages(IOUtil.ClassResources resources, int[] data_size, int[] elem_bytesize) throws UnsupportedOperationException, InterruptedException, IOException, MalformedURLException { - final PNGImage[] images = new PNGImage[resources.resourceCount()]; + final PNGPixelRect[] images = new PNGPixelRect[resources.resourceCount()]; data_size[0] = 0; for(int i=0; iGetDirectBufferAddress(env, jiconData); +static NSImage * createNSImageFromData(JNIEnv *env, unsigned char * iconData, jint jiconWidth, jint jiconHeight) { + if( NULL != iconData ) { NSInteger iconWidth = (NSInteger) jiconWidth; NSInteger iconHeight = (NSInteger) jiconHeight; const NSInteger bpc = 8 /* bits per component */, spp=4 /* RGBA */, bpp = bpc * spp; @@ -319,28 +318,47 @@ static NSImage * createNSImageFromData(JNIEnv *env, jobject jiconData, jint jico * Method: setAppIcon0 */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_setAppIcon0 - (JNIEnv *env, jobject unused, jobject jiconData, jint jiconWidth, jint jiconHeight) + (JNIEnv *env, jobject unused, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct, jint width, jint height) { + if( 0 == pixels ) { + return; + } NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSImage * nsImage = createNSImageFromData(env, jiconData, jiconWidth, jiconHeight); + // NOTE: MUST BE DIRECT BUFFER, since NSBitmapImageRep uses buffer directly! + unsigned char * pixelPtr = (unsigned char *) ( JNI_TRUE == pixels_is_direct ? + (*env)->GetDirectBufferAddress(env, pixels) : + (*env)->GetPrimitiveArrayCritical(env, pixels, NULL) ); + NSImage * nsImage = createNSImageFromData(env, pixelPtr + pixels_byte_offset, width, height); if( NULL != nsImage ) { [nsImage autorelease]; [NSApp setApplicationIconImage: nsImage]; } + if ( JNI_FALSE == pixels_is_direct ) { + (*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT); + } [pool release]; } JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_createPointerIcon0 - (JNIEnv *env, jobject unused, jobject jiconData, jint jiconWidth, jint jiconHeight, jint hotX, jint hotY) + (JNIEnv *env, jobject unused, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct, jint width, jint height, jint hotX, jint hotY) { + if( 0 == pixels ) { + return 0; + } NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSImage * nsImage = createNSImageFromData(env, jiconData, jiconWidth, jiconHeight); + unsigned char * pixelPtr = (unsigned char *) ( JNI_TRUE == pixels_is_direct ? + (*env)->GetDirectBufferAddress(env, pixels) : + (*env)->GetPrimitiveArrayCritical(env, pixels, NULL) ); + NSImage * nsImage = createNSImageFromData(env, pixelPtr + pixels_byte_offset, width, height); NSCursor * res = NULL; if( NULL != nsImage ) { [nsImage autorelease]; NSPoint hotP = { hotX, hotY }; res = [[NSCursor alloc] initWithImage: nsImage hotSpot: hotP]; } + if ( JNI_FALSE == pixels_is_direct ) { + (*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT); + } [pool release]; DBG_PRINT( "createPointerIcon0 %p\n", res); return (jlong) (intptr_t) res; diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index 1fd8d0039..c20e156c1 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -2368,9 +2368,15 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_warpPointer0 JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_DisplayDriver_createBGRA8888Icon0(JNIEnv *env, jobject _unused, - jobject data, jint data_offset, jint width, jint height, jboolean isCursor, jint hotX, jint hotY) { + jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct, jint width, jint height, jboolean isCursor, jint hotX, jint hotY) { - const unsigned char * data_ptr = (const unsigned char *) (*env)->GetDirectBufferAddress(env, data) + data_offset; + if( 0 == pixels ) { + return 0; + } + + const unsigned char * pixelPtr = (const unsigned char *) ( JNI_TRUE == pixels_is_direct ? + (*env)->GetDirectBufferAddress(env, pixels) : + (*env)->GetPrimitiveArrayCritical(env, pixels, NULL) ); const int bytes = 4 * width * height; // BGRA8888 DWORD dwWidth, dwHeight; @@ -2403,10 +2409,14 @@ Java_jogamp_newt_driver_windows_DisplayDriver_createBGRA8888Icon0(JNIEnv *env, j hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&lpBits, NULL, (DWORD)0); - memcpy(lpBits, data_ptr, bytes); + memcpy(lpBits, pixelPtr + pixels_byte_offset, bytes); ReleaseDC(NULL,hdc); + if ( JNI_FALSE == pixels_is_direct ) { + (*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT); + } + // Create an empty mask bitmap. HBITMAP hMonoBitmap = CreateBitmap(dwWidth,dwHeight,1,1,NULL); diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c index 19e733111..b62a9b234 100644 --- a/src/newt/native/X11Display.c +++ b/src/newt/native/X11Display.c @@ -678,13 +678,15 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage * Signature: (JJILjava/lang/Object;I)V */ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_createPointerIcon0 - (JNIEnv *env, jclass clazz, jlong display, jobject data, jint data_offset, jint width, jint height, jint hotX, jint hotY) + (JNIEnv *env, jclass clazz, jlong display, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct, jint width, jint height, jint hotX, jint hotY) { Cursor c; - if( 0 != data ) { + if( 0 != pixels ) { Display * dpy = (Display *) (intptr_t) display; - char * data_ptr = (char *) (*env)->GetDirectBufferAddress(env, data) + data_offset; + const unsigned char * pixelPtr = (const unsigned char *) ( JNI_TRUE == pixels_is_direct ? + (*env)->GetDirectBufferAddress(env, pixels) : + (*env)->GetPrimitiveArrayCritical(env, pixels, NULL) ); XcursorImage ci; ci.version = 1; // XCURSOR_IMAGE_VERSION; ci.size = width; // nominal size (assume square ..) @@ -693,11 +695,14 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_createPointerI ci.xhot = hotX; ci.yhot = hotY; ci.delay = 0; - ci.pixels = (XcursorPixel *)(intptr_t)data_ptr; + ci.pixels = (XcursorPixel *)(intptr_t)(pixelPtr + pixels_byte_offset); c = XcursorImageLoadCursor (dpy, &ci); - DBG_PRINT( "X11: createPointerIcon0: %p %dx%d %d/%d -> %p\n", data_ptr, width, height, hotX, hotY, (void *)c); + if ( JNI_FALSE == pixels_is_direct ) { + (*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT); + } + DBG_PRINT( "X11: createPointerIcon0: %p %dx%d %d/%d -> %p\n", (pixelPtr+pixels_byte_offset), width, height, hotX, hotY, (void *)c); } else { c = 0; diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index da2778004..54b85c243 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -512,7 +512,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWindow0 jint visualID, jlong javaObjectAtom, jlong windowDeleteAtom, jint x, jint y, jint width, jint height, jboolean autoPosition, int flags, - jint iconDataSize, jobject iconData) + jint pixelDataSize, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct) { Display * dpy = (Display *)(intptr_t)display; Atom wm_delete_atom = (Atom)windowDeleteAtom; @@ -632,10 +632,16 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWindow0 { XEvent event; int left=0, right=0, top=0, bottom=0; - - if( 0 < iconDataSize && NULL != iconData ) { - const unsigned char * iconDataPtr = (const unsigned char *) (*env)->GetDirectBufferAddress(env, iconData); - NewtWindows_setIcon(dpy, window, (int)iconDataSize, iconDataPtr); + const unsigned char * pixelPtr = NULL; + + // NOTE: MUST BE DIRECT BUFFER, since _NET_WM_ICON Atom uses buffer directly! + DBG_PRINT("X11: CreateWindow icon: size %d, pixels %p, offset %d, direct %d\n", pixelDataSize, (void*)pixels, pixels_byte_offset, pixels_is_direct); + if( 0 < pixelDataSize && NULL != pixels ) { + pixelPtr = (const unsigned char *) ( JNI_TRUE == pixels_is_direct ? + (*env)->GetDirectBufferAddress(env, pixels) : + (*env)->GetPrimitiveArrayCritical(env, pixels, NULL) ); + DBG_PRINT("X11: CreateWindow icon: NIO %p\n", pixelPtr); + NewtWindows_setIcon(dpy, window, (int)pixelDataSize, pixelPtr+pixels_byte_offset); } XMapWindow(dpy, window); @@ -643,6 +649,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWindow0 XSync(dpy, False); + if( JNI_FALSE == pixels_is_direct && NULL != pixelPtr ) { + (*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT); + } + // send insets before visibility, allowing java code a proper sync point! NewtWindows_updateInsets(env, jwindow, dpy, window, &left, &right, &top, &bottom); (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java index 8cc676291..780338492 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java @@ -29,6 +29,7 @@ package com.jogamp.opengl.test.junit.jogl.demos.es2.newt; import java.io.IOException; +import java.net.URLConnection; import com.jogamp.common.util.IOUtil; import com.jogamp.newt.Display; @@ -47,6 +48,7 @@ import com.jogamp.opengl.test.junit.util.MiscUtils; import com.jogamp.opengl.test.junit.util.UITestCase; import com.jogamp.opengl.test.junit.util.QuitAdapter; import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.PNGPixelRect; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; import javax.media.nativewindow.NativeWindowFactory; @@ -171,25 +173,55 @@ public class TestGearsES2NEWT extends UITestCase { } }); - final PointerIcon pointerIconOne; + final PointerIcon[] pointerIcons = { null, null, null }; { - PointerIcon _pointerIconOne = null; - final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "jogamp-pointer-64x64.png" } ); final Display disp = glWindow.getScreen().getDisplay(); disp.createNative(); - try { - _pointerIconOne = disp.createPointerIcon(res, 32, 0); - } catch (Exception e) { - e.printStackTrace(); + { + PointerIcon _pointerIcon = null; + final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/crosshair-lumina-trans-32x32.png" } ); + try { + _pointerIcon = disp.createPointerIcon(res, 16, 16); + System.err.println("Create PointerIcon #01: "+_pointerIcon); + } catch (Exception e) { + e.printStackTrace(); + } + pointerIcons[0] = _pointerIcon; + } + { + PointerIcon _pointerIcon = null; + final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "jogamp-pointer-64x64.png" } ); + try { + _pointerIcon = disp.createPointerIcon(res, 32, 0); + System.err.println("Create PointerIcon #02: "+_pointerIcon); + } catch (Exception e) { + e.printStackTrace(); + } + pointerIcons[1] = _pointerIcon; + } + { + PointerIcon _pointerIcon = null; + final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "crosshair-lumina-trans-64x64.png" } ); + try { + final URLConnection urlConn = res.resolve(0); + final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), null, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */); + System.err.println("Create PointerIcon #03: "+image); + _pointerIcon = disp.createPointerIcon(image, 32, 32); + System.err.println("Create PointerIcon #03: "+_pointerIcon); + } catch (Exception e) { + e.printStackTrace(); + } + pointerIcons[2] = _pointerIcon; } - pointerIconOne = _pointerIconOne; } if( setPointerIcon ) { - glWindow.setPointerIcon(pointerIconOne); + glWindow.setPointerIcon(pointerIcons[0]); System.err.println("Set PointerIcon: "+glWindow.getPointerIcon()); } glWindow.addKeyListener(new KeyAdapter() { + int pointerIconIdx = 0; + @Override public void keyPressed(final KeyEvent e) { if( e.isAutoRepeat() ) { @@ -246,7 +278,14 @@ public class TestGearsES2NEWT extends UITestCase { final Thread t = glWindow.setExclusiveContextThread(null); System.err.println("[set pointer-icon pre]"); final PointerIcon currentPI = glWindow.getPointerIcon(); - glWindow.setPointerIcon( currentPI == pointerIconOne ? null : pointerIconOne); + final PointerIcon newPI; + if( pointerIconIdx >= pointerIcons.length ) { + newPI=null; + pointerIconIdx=0; + } else { + newPI=pointerIcons[pointerIconIdx++]; + } + glWindow.setPointerIcon( newPI ); System.err.println("[set pointer-icon post] "+currentPI+" -> "+glWindow.getPointerIcon()); glWindow.setExclusiveContextThread(t); } }.start(); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/PNGTstFiles.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/PNGTstFiles.java new file mode 100644 index 000000000..bb9bc42a8 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/PNGTstFiles.java @@ -0,0 +1,54 @@ +/** + * Copyright 2014 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.test.junit.jogl.util.texture; + +public class PNGTstFiles { + static public final String[] allBasenames = { + "test-ntscN_3-01-160x90", + "test-ntscN_4-01-160x90", + "test-ntscNG4-01-160x90", + "test-ntscI_3-01-160x90", + "test-ntscI_4-01-160x90", + "test-ntscIG3-01-160x90", + "test-ntscIG4-01-160x90", + "test-ntscP_3-01-160x90", + "test-ntscP_4-01-160x90", + "grayscale_texture", + "bug724-transparent-grey_orig", + "bug724-transparent-grey_gimpexp", + "crosshair-lumina-trans-32x32", + "crosshair-lumina-trans-64x64", + }; + static public final String[] greyBasenames = { + "grayscale_texture", + "bug724-transparent-grey_orig", + "bug724-transparent-grey_gimpexp", + "crosshair-lumina-trans-32x32", + "crosshair-lumina-trans-64x64", + }; +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage00NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage00NEWT.java deleted file mode 100644 index 3ace5ab6a..000000000 --- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage00NEWT.java +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Copyright 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ -package com.jogamp.opengl.test.junit.jogl.util.texture; - -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URLConnection; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.FixMethodOrder; -import org.junit.runners.MethodSorters; - -import com.jogamp.common.util.IOUtil; -import com.jogamp.opengl.test.junit.util.UITestCase; -import com.jogamp.opengl.util.texture.spi.PNGImage; - -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestPNGImage00NEWT extends UITestCase { - @Test - public void testPNGReadWriteAndCompare() throws InterruptedException, IOException, MalformedURLException { - final File out1_f=new File(getSimpleTestName(".")+"-PNGImageTest1.png"); - final File out2_f=new File(getSimpleTestName(".")+"-PNGImageTest2.png"); - final File out2F_f=new File(getSimpleTestName(".")+"-PNGImageTest2Flipped.png"); - final File out2R_f=new File(getSimpleTestName(".")+"-PNGImageTest2Reversed.png"); - final File out2RF_f=new File(getSimpleTestName(".")+"-PNGImageTest2ReversedFlipped.png"); - final String url_s="jogl/util/data/av/test-ntsc01-57x32.png"; - URLConnection urlConn = IOUtil.getResource(url_s, this.getClass().getClassLoader()); - PNGImage image1 = PNGImage.read(urlConn.getInputStream()); - System.err.println("PNGImage - Orig: "+image1); - image1.write(out1_f, true); - { - Assert.assertEquals(image1.getData(), PNGImage.read(out1_f.toURI().toURL().openStream()).getData()); - } - - final PNGImage image2 = PNGImage.createFromData(image1.getWidth(), image1.getHeight(), - image1.getDpi()[0], image1.getDpi()[1], - image1.getBytesPerPixel(), false /* reverseChannels */, image1.isGLOriented(), image1.getData()); - image2.write(out2_f, true); - { - Assert.assertEquals(image1.getData(), PNGImage.read(out2_f.toURI().toURL().openStream()).getData()); - } - - // flipped - final PNGImage image2F = PNGImage.createFromData(image1.getWidth(), image1.getHeight(), - image1.getDpi()[0], image1.getDpi()[1], - image1.getBytesPerPixel(), false /* reverseChannels */, !image1.isGLOriented(), image1.getData()); - image2F.write(out2F_f, true); - - // reversed channels - final PNGImage image2R = PNGImage.createFromData(image1.getWidth(), image1.getHeight(), - image1.getDpi()[0], image1.getDpi()[1], - image1.getBytesPerPixel(), true /* reverseChannels */, image1.isGLOriented(), image1.getData()); - image2R.write(out2R_f, true); - - // reversed channels and flipped - final PNGImage image2RF = PNGImage.createFromData(image1.getWidth(), image1.getHeight(), - image1.getDpi()[0], image1.getDpi()[1], - image1.getBytesPerPixel(), true /* reverseChannels */, !image1.isGLOriented(), image1.getData()); - image2RF.write(out2RF_f, true); - } - - public static void main(String args[]) { - org.junit.runner.JUnitCore.main(TestPNGImage00NEWT.class.getName()); - } -} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage01NEWT.java deleted file mode 100644 index 29e041908..000000000 --- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage01NEWT.java +++ /dev/null @@ -1,182 +0,0 @@ -/** - * Copyright 2010 JogAmp Community. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ -package com.jogamp.opengl.test.junit.jogl.util.texture; - -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URLConnection; - -import javax.media.opengl.GL; -import javax.media.opengl.GLAutoDrawable; -import javax.media.opengl.GLCapabilities; -import javax.media.opengl.GLEventListener; -import javax.media.opengl.GLProfile; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.FixMethodOrder; -import org.junit.runners.MethodSorters; - -import com.jogamp.common.util.IOUtil; -import com.jogamp.newt.opengl.GLWindow; -import com.jogamp.opengl.test.junit.jogl.demos.TextureDraw01Accessor; -import com.jogamp.opengl.test.junit.jogl.demos.es2.TextureDraw01ES2Listener; -import com.jogamp.opengl.test.junit.util.MiscUtils; -import com.jogamp.opengl.test.junit.util.QuitAdapter; -import com.jogamp.opengl.test.junit.util.UITestCase; -import com.jogamp.opengl.util.Animator; -import com.jogamp.opengl.util.GLReadBufferUtil; -import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; -import com.jogamp.opengl.util.texture.TextureData; -import com.jogamp.opengl.util.texture.TextureIO; -import com.jogamp.opengl.util.texture.spi.PNGImage; - -/** - * Test reading and displaying a PNG image. - *

    - * Main function accepts arbitrary PNG file name for manual tests. - *

    - */ -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestPNGImage01NEWT extends UITestCase { - - static boolean showFPS = false; - static long duration = 200; // ms - - public void testImpl(final InputStream istream) throws InterruptedException, IOException { - final PNGImage image = PNGImage.read(istream); - Assert.assertNotNull(image); - final boolean hasAlpha = 4 == image.getBytesPerPixel(); - System.err.println("PNGImage: "+image); - - final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false); - final GLProfile glp = GLProfile.getGL2ES2(); - final GLCapabilities caps = new GLCapabilities(glp); - if( hasAlpha ) { - caps.setAlphaBits(1); - } - - final int internalFormat; - if(glp.isGL2ES3()) { - internalFormat = hasAlpha ? GL.GL_RGBA8 : GL.GL_RGB8; - } else { - internalFormat = hasAlpha ? GL.GL_RGBA : GL.GL_RGB; - } - final TextureData texData = new TextureData(glp, internalFormat, - image.getWidth(), - image.getHeight(), - 0, - new GLPixelAttributes(image.getGLFormat(), image.getGLType()), - false /* mipmap */, - false /* compressed */, - false /* must flip-vert */, - image.getData(), - null); - - // final TextureData texData = TextureIO.newTextureData(glp, istream, false /* mipmap */, TextureIO.PNG); - System.err.println("TextureData: "+texData); - - final GLWindow glad = GLWindow.create(caps); - glad.setTitle("TestPNGImage01NEWT"); - // Size OpenGL to Video Surface - glad.setSize(texData.getWidth(), texData.getHeight()); - - // load texture from file inside current GL context to match the way - // the bug submitter was doing it - final TextureDraw01ES2Listener gle = new TextureDraw01ES2Listener( texData, 0 ) ; - // gle.setClearColor(new float[] { 1.0f, 0.0f, 0.0f, 1.0f } ); - - glad.addGLEventListener(gle); - glad.addGLEventListener(new GLEventListener() { - boolean shot = false; - - @Override public void init(GLAutoDrawable drawable) { - System.err.println("Chosen Caps: " + drawable.getChosenGLCapabilities()); - System.err.println("GL ctx: " + drawable.getGL().getContext()); - } - - @Override public void display(GLAutoDrawable drawable) { - // 1 snapshot - if(null!=((TextureDraw01Accessor)gle).getTexture() && !shot) { - shot = true; - snapshot(0, null, drawable.getGL(), screenshot, TextureIO.PNG, null); - } - } - - @Override public void dispose(GLAutoDrawable drawable) { } - @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { } - }); - - Animator animator = new Animator(glad); - animator.setUpdateFPSFrames(60, showFPS ? System.err : null); - QuitAdapter quitAdapter = new QuitAdapter(); - glad.addKeyListener(quitAdapter); - glad.addWindowListener(quitAdapter); - glad.setVisible(true); - animator.start(); - - while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration() + * Main function accepts arbitrary PNG file name for manual tests. + *

    + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestPNGPixelRect01NEWT extends UITestCase { + static boolean showFPS = false; + static long duration = 200; // ms + + public void testImpl(final int num, final String basename, final InputStream istream, final PixelFormat destFmt) throws InterruptedException, IOException { + final GLProfile glp = GLProfile.getGL2ES2(); + final PNGPixelRect image = PNGPixelRect.read(istream, destFmt, true /* directBuffer */, 0 /* destMinStrideInBytes */, true /* destIsGLOriented */); + Assert.assertNotNull(image); + final GLPixelAttributes glpa = GLPixelAttributes.convert(image.getPixelformat(), glp); + final boolean hasAlpha = 4 == glpa.bytesPerPixel; + System.err.println("PNGPixelRect: "+basename+", "+image+", glpa "+glpa); + + final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false); + final GLCapabilities caps = new GLCapabilities(glp); + if( hasAlpha ) { + caps.setAlphaBits(1); + } + + final int internalFormat; + if(glp.isGL2ES3()) { + internalFormat = hasAlpha ? GL.GL_RGBA8 : GL.GL_RGB8; + } else { + internalFormat = hasAlpha ? GL.GL_RGBA : GL.GL_RGB; + } + final TextureData texData = new TextureData(glp, internalFormat, + image.getSize().getWidth(), + image.getSize().getHeight(), + 0, + glpa, + false /* mipmap */, + false /* compressed */, + false /* must flip-vert */, + image.getPixels(), + null); + + // final TextureData texData = TextureIO.newTextureData(glp, istream, false /* mipmap */, TextureIO.PNG); + System.err.println("TextureData: "+texData); + + final GLWindow glad = GLWindow.create(caps); + glad.setTitle(this.getSimpleTestName(".")); + // Size OpenGL to Video Surface + glad.setSize(texData.getWidth(), texData.getHeight()); + + // load texture from file inside current GL context to match the way + // the bug submitter was doing it + final TextureDraw01ES2Listener gle = new TextureDraw01ES2Listener( texData, 0 ) ; + // gle.setClearColor(new float[] { 1.0f, 0.0f, 0.0f, 1.0f } ); + + glad.addGLEventListener(gle); + glad.addGLEventListener(new GLEventListener() { + boolean shot = false; + + @Override public void init(GLAutoDrawable drawable) { + System.err.println("Chosen Caps: " + drawable.getChosenGLCapabilities()); + System.err.println("GL ctx: " + drawable.getGL().getContext()); + } + + @Override public void display(GLAutoDrawable drawable) { + // 1 snapshot + if(null!=((TextureDraw01Accessor)gle).getTexture() && !shot) { + shot = true; + snapshot(num, basename, drawable.getGL(), screenshot, TextureIO.PNG, null); + } + } + + @Override public void dispose(GLAutoDrawable drawable) { } + @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { } + }); + + Animator animator = new Animator(glad); + animator.setUpdateFPSFrames(60, showFPS ? System.err : null); + QuitAdapter quitAdapter = new QuitAdapter(); + glad.addKeyListener(quitAdapter); + glad.addWindowListener(quitAdapter); + glad.setVisible(true); + animator.start(); + + while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration() "+destFmt); + final PixelRectangle imageConv1 = PixelFormatUtil.convert32(image1, destFmt, destMinStrideInBytes, destIsGLOriented, false /* nio */); + System.err.println("PNGPixelRect - Conv1: "+imageConv1); + final PixelRectangle imageConv2 = PixelFormatUtil.convert32(imageConv1, image1.getPixelformat(), image1.getStride(), image1.isGLOriented(), false /* nio */); + System.err.println("PNGPixelRect - Conv2: "+imageConv2); + Assert.assertEquals(image1.getPixels(), imageConv2.getPixels()); + } + } + + public static void main(String args[]) { + org.junit.runner.JUnitCore.main(TestPixelFormatUtil01NEWT.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/crosshair-lumina-trans-32x32.png b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/crosshair-lumina-trans-32x32.png new file mode 100644 index 000000000..92279640b Binary files /dev/null and b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/crosshair-lumina-trans-32x32.png differ diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/crosshair-lumina-trans-64x64.png b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/crosshair-lumina-trans-64x64.png new file mode 100644 index 000000000..9be285335 Binary files /dev/null and b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/crosshair-lumina-trans-64x64.png differ diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java index 69874df6b..70d01ae66 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java @@ -28,25 +28,27 @@ package com.jogamp.opengl.test.junit.newt.parenting; import java.awt.Frame; +import java.net.URLConnection; import javax.media.nativewindow.util.InsetsImmutable; import com.jogamp.common.util.IOUtil; import com.jogamp.newt.Display; -import com.jogamp.newt.Window; import com.jogamp.newt.Display.PointerIcon; import com.jogamp.newt.awt.NewtCanvasAWT; import com.jogamp.newt.event.KeyAdapter; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.test.junit.util.QuitAdapter; +import com.jogamp.opengl.util.PNGPixelRect; public class NewtAWTReparentingKeyAdapter extends KeyAdapter { final Frame frame; final NewtCanvasAWT newtCanvasAWT; final GLWindow glWindow; final QuitAdapter quitAdapter; - PointerIcon pointerIconTest = null; + PointerIcon[] pointerIcons = null; + int pointerIconIdx = 0; public NewtAWTReparentingKeyAdapter(Frame frame, NewtCanvasAWT newtCanvasAWT, GLWindow glWindow, QuitAdapter quitAdapter) { this.frame = frame; @@ -144,13 +146,46 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter { } } }.start(); } else if(e.getKeySymbol() == KeyEvent.VK_C ) { - if( null == pointerIconTest ) { - final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/jogamp-32x32.png" } ); - final Display disp = glWindow.getScreen().getDisplay(); - try { - pointerIconTest = disp.createPointerIcon(res, 16, 0); - } catch (Exception err) { - err.printStackTrace(); + if( null == pointerIcons ) { + { + pointerIcons = new PointerIcon[3]; + final Display disp = glWindow.getScreen().getDisplay(); + { + PointerIcon _pointerIcon = null; + final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "newt/data/crosshair-lumina-trans-32x32.png" } ); + try { + _pointerIcon = disp.createPointerIcon(res, 16, 16); + System.err.println("Create PointerIcon #01: "+_pointerIcon); + } catch (Exception ex) { + ex.printStackTrace(); + } + pointerIcons[0] = _pointerIcon; + } + { + PointerIcon _pointerIcon = null; + final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "jogamp-pointer-64x64.png" } ); + try { + _pointerIcon = disp.createPointerIcon(res, 32, 0); + System.err.println("Create PointerIcon #02: "+_pointerIcon); + } catch (Exception ex) { + ex.printStackTrace(); + } + pointerIcons[1] = _pointerIcon; + } + { + PointerIcon _pointerIcon = null; + final IOUtil.ClassResources res = new IOUtil.ClassResources(glWindow.getClass(), new String[] { "crosshair-lumina-trans-64x64.png" } ); + try { + final URLConnection urlConn = res.resolve(0); + final PNGPixelRect image = PNGPixelRect.read(urlConn.getInputStream(), null, false /* directBuffer */, 0 /* destMinStrideInBytes */, false /* destIsGLOriented */); + System.err.println("Create PointerIcon #03: "+image); + _pointerIcon = disp.createPointerIcon(image, 32, 32); + System.err.println("Create PointerIcon #03: "+_pointerIcon); + } catch (Exception ex) { + ex.printStackTrace(); + } + pointerIcons[2] = _pointerIcon; + } } } new Thread() { @@ -158,7 +193,14 @@ public class NewtAWTReparentingKeyAdapter extends KeyAdapter { final Thread t = glWindow.setExclusiveContextThread(null); System.err.println("[set pointer-icon pre]"); final PointerIcon currentPI = glWindow.getPointerIcon(); - glWindow.setPointerIcon( currentPI == pointerIconTest ? null : pointerIconTest); + final PointerIcon newPI; + if( pointerIconIdx >= pointerIcons.length ) { + newPI=null; + pointerIconIdx=0; + } else { + newPI=pointerIcons[pointerIconIdx++]; + } + glWindow.setPointerIcon( newPI ); System.err.println("[set pointer-icon post] "+currentPI+" -> "+glWindow.getPointerIcon()); glWindow.setExclusiveContextThread(t); } }.start(); -- cgit v1.2.3 From 5ef83c2b8576ccd764ffc4953eea506bd96277c3 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 11 Jan 2014 00:04:18 +0100 Subject: X11: Harden usage of 'XGetWindowProperty(..)' and 'XGetVisualInfo' - Add missing XFree(..) calls and argument checks. --- src/nativewindow/native/x11/Xmisc.c | 36 ++++++++++---------- src/newt/native/X11Window.c | 66 +++++++++++++++++++++---------------- 2 files changed, 55 insertions(+), 47 deletions(-) (limited to 'src/newt/native/X11Window.c') diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c index 7b9dc344b..5e6909f6e 100644 --- a/src/nativewindow/native/x11/Xmisc.c +++ b/src/nativewindow/native/x11/Xmisc.c @@ -219,7 +219,6 @@ static int x11ErrorHandler(Display *dpy, XErrorEvent *e) e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial, (int)e->request_code, (int)e->minor_code, reqCodeStr); } - if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); } @@ -347,25 +346,24 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_x11_X11Lib_XGetVisualInfo1__JJLjava_nio_ByteBuffer_2Ljava_lang_Object_2I(JNIEnv *env, jclass _unused, jlong arg0, jlong arg1, jobject arg2, jobject arg3, jint arg3_byte_offset) { XVisualInfo * _ptr2 = NULL; int * _ptr3 = NULL; - XVisualInfo * _res; - int count; - jobject jbyteSource; - jobject jbyteCopy; - if(0==arg0) { - NativewindowCommon_FatalError(env, "invalid display connection.."); - } - if (arg2 != NULL) { - _ptr2 = (XVisualInfo *) (((char*) (*env)->GetDirectBufferAddress(env, arg2)) + 0); - } - if (arg3 != NULL) { - _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, arg3, NULL)) + arg3_byte_offset); + XVisualInfo * _res = NULL; + int count = 0; + jobject jbyteSource = NULL; + jobject jbyteCopy = NULL; + if( 0 == arg0 || 0 == arg2 || 0 == arg3 ) { + NativewindowCommon_FatalError(env, "invalid display connection, vinfo_template or nitems_return"); + return NULL; } - NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 1, errorHandlerQuiet, 0); - _res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3); - // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 0, errorHandlerQuiet, 0); - count = _ptr3[0]; - if (arg3 != NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0); + _ptr2 = (XVisualInfo *) (((char*) (*env)->GetDirectBufferAddress(env, arg2)) + 0); + if( NULL != _ptr2 ) { + _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, arg3, NULL)) + arg3_byte_offset); + if( NULL != _ptr3 ) { + NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 1, errorHandlerQuiet, 0); + _res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3); + // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 0, errorHandlerQuiet, 0); + count = _ptr3[0]; + (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0); + } } if (_res == NULL) return NULL; diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 54b85c243..2cc66c78d 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -98,11 +98,11 @@ static void setJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlon } jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning) { - Atom actual_type; - int actual_format; + Atom actual_type = 0; + int actual_format = 0; int nitems_32 = ( sizeof(uintptr_t) == 8 ) ? 2 : 1 ; unsigned char * jogl_java_object_data_pp = NULL; - jobject jwindow; + jobject jwindow = 0; { unsigned long nitems= 0; @@ -122,7 +122,9 @@ jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong ja } if(actual_type!=(Atom)javaObjectAtom || nitems= PROP_MWM_HINTS_ELEMENTS) { // unsigned long mwmhints[PROP_MWM_HINTS_ELEMENTS] = { MWM_HINTS_DECORATIONS, 0, decorated, 0, 0 }; // flags, functions, decorations, input_mode, status unsigned long *hints = (unsigned long *) wm_data; decor = ( 0 != (hints[0] & MWM_HINTS_DECORATIONS) ) && ( 0 != hints[2] ); } + if( NULL != wm_data ) { + XFree(wm_data); + } } #endif @@ -319,27 +326,30 @@ static int NewtWindows_getSupportedStackingEWMHFlags(Display *dpy, Window w) { Atom _NET_WM_ALLOWED_ACTIONS = XInternAtom( dpy, "_NET_WM_ALLOWED_ACTIONS", False ); Atom _NET_WM_ACTION_FULLSCREEN = XInternAtom( dpy, "_NET_WM_ACTION_FULLSCREEN", False ); Atom _NET_WM_ACTION_ABOVE = XInternAtom( dpy, "_NET_WM_ACTION_ABOVE", False ); - Atom * actions; - Atom type; - unsigned long action_len, remain; - int res = 0, form, i; + Atom * actions = NULL; + Atom type = 0; + unsigned long action_len = 0, remain = 0; + int res = 0, form = 0, i = 0; Status s; if ( Success == (s = XGetWindowProperty(dpy, w, _NET_WM_ALLOWED_ACTIONS, 0, 1024, False, AnyPropertyType, &type, &form, &action_len, &remain, (unsigned char**)&actions)) ) { - for(i=0; i